Symfony 1.4 skip sf_culture in URL for main language with overridden sfPatternRouting class

If you have i18n website and want to have language in the URL _BUT_ want to skip main language to be in the URL you need some custom solution.


You can solve this by using following custom routing class:

class cxCulturePatternRouting extends sfPatternRouting
{
    /**
     * @param string $name
     * @param array $params
     * @param bool $absolute
     * @return mixed|string
     * @throws sfConfigurationException
     */
    public function generate($name, $params = array(), $absolute = false)
    {
        $culture = $this->getDefaultParameter('sf_culture');

        // I don't like sfContext solutions
        $options = sfContext::getInstance()->getUser()->getOptions();

        if ($options['default_culture'] != $culture) {
            $culture_route_name = $name . '_i18n';
        }

        if (isset($culture_route_name) && array_key_exists($culture_route_name, $this->routes)) {
            $name = $culture_route_name;
        }

        return parent::generate($name, $params, $absolute);
    }
}

and following records in settings.yml :

    default_culture:        uk
    i18n: true

and following routes in routing.yml :

cities:
  url:   /cities
  param: { module: cities, action: index }
  requrements: { sf_culture: (?:uk) }

cities_i18n:
  url:   /:sf_culture/cities
  param: { module: cities, action: index}
  requrements: { sf_culture: (?:ru|en) }

and finally add this routing class to your app factories.yml :

all:
  routing:
    class: cxCulturePatternRouting
    param:
      generate_shortest_url:            true
      extra_parameters_as_query_string: true

 

After that in the template you can simply have:

echo link_to('Cities', '@cities')

and routing generator will add sf_culture automatically and will generate i18n valid URL.

Enjoy!