Ask your Symfony questions! Pay money and get answers fast! (more info)

Allow forward slashes in variables Symfony

  • SOLVED

I have an application allowing to search by tag, the corresponding routing.yml part looks like this:


blog_search_tag:
url: /blog/tags/:tags
param: { module: blog, action: search }


This works until a tag contains a forward slash ("/").

How do I allow forward slashes in variables and pass them to the action?

[UPDATE]

My case doesn't seem to be clear. I don't want to separate several tags by "/". :tags will always contain one tag only, I however want this tag to be able to contain a "/".

Answers (5)

2010-12-15

Christian Schaefer answers:

You can also define each variable on its own.
You might want to read [[LINK href="http://test.ical.ly/2010/09/07/did-you-know-there-are-loads-of-configuration-options-to-symfony-routes-that-the-reference-book-is-not-telling-you/"]]this[[/LINK]] as well.

2010-12-16

Bernhard Schussek answers:

You have to change the pattern for the variable. By default, variables don't match slashes. Furthermore you have to define a custom route that decodes the slashes (which are urlencoded by default).

blog_search_tag:
url: /blog/tags/:tags
class: SlashRoute
param: { module: blog, action: search }
requirements: { tags: .+ }


SlashRoute.php
class SlashRoute extends sfRequestRoute
{
/**
* Utility function to unencode urlencoded slashes within a URL.
*
* @param string $url The original URL
* @param boolean $allowSlashes Whether to allow unencoded slashes
* @return string The cleaned URL
*/
static public function decodeSlashes($url, $allowSlashes = true)
{
if ($allowSlashes)
{
$url = str_replace('%2F','/', $url);
}

return $url;
}

/**
* @see sfRequestRoute
*/
public function generate($params, $context = array(), $absolute = false,
$allowSlashes = true)
{
return self::decodeSlashes(parent::generate($params, $context, $absolute), $allowSlashes);
}
}


You can use decodeSlashes() in other routes (f.i. SlashObjectRoute) as well.

2010-12-15

Alex Zgorzhelsky answers:

I guess you could use another segment separator instead of forward slash for you route
Underscore, for example


blog_search_tag:
url: /blog/tags/:tags
param: { module: blog, action: search }
options: { segment_separators: [_, ., -] }


sn comments:

In this case, _, ., - wouldn't be allowed as var content. Is there a way to allow "any" character as variable content?

2010-12-15

Gordon Franke answers:

@alex right the segment_seperator

@sn be warned search engines don't like to many levels and each forward slash stand for a deeper website level, the better option is to make a getTagForUrl method in that you replace some characters.

and than use:
options: { model: Tag, type: object, method: getForTagRouting, suffix: '' }

or something similar

2010-12-15

Jérôme Tamarelle answers:

You could simply create many routes redirecting to the same controller.


blog_search_tag1:
url: /blog/tags/:tag1
param: { module: blog, action: search }

blog_search_tag2:
url: /blog/tags/:tag1/:tag2
param: { module: blog, action: search }

blog_search_tag3:
url: /blog/tags/:tag1/:tag2/:tag3
param: { module: blog, action: search }


This way you don't have to split your "tags" parameter in the controller. You can access them using

$this->get RequestParameters()