parametrized-locale-aware routing #5885

Closed
wants to merge 4 commits into from

5 participants

@djungbluth

For translation-aware routers, i.e. TranslatorAwareTreeRouteStack:

If parameter „locale“ is detected during routing (either matching or
assembling), the translator will use this locale instead of a default
one. By doing so, the following route is possible:

/:locale/{NEWS}/{TODAY}

Which would match/assemble with/to:

/en/news/today
/de/neues/heute

with translations (excerpt for locale 'de': 'NEWS' => 'neues', 'TODAY' => 'heute').

Daniel Jungb... added some commits Feb 28, 2014
Daniel Jungbluth parametrized-locale-aware routing
For translation-aware routers, i.e. TranslationAwareTreeRouteStack:

If parameter „locale“ is detected during routing (either matching or
assembling), the translator will use this locale instead of a default
one. By doing so, the following route is possible:

   /:locale/{NEWS}/{TODAY}

Which would match/assemble with/to:

   /en/news/today
   /de/neues/heute

with translations (excerpt for locale ‚de‘: ‚NEWS‘ => ‚neues‘).
4da5778
Daniel Jungbluth fix previous commit & adding tests
okay, okay…
5e166ae
Daniel Jungbluth coding standard 18bd319
Daniel Jungbluth coding standard, pt II 32beb08
@weierophinney weierophinney added this to the 2.3.0 milestone Mar 3, 2014
@weierophinney weierophinney added a commit that referenced this pull request Mar 5, 2014
@weierophinney weierophinney [#5885] Added note to README 44c23e9
@weierophinney weierophinney added a commit that referenced this pull request Mar 5, 2014
@weierophinney weierophinney Merge branch 'feature/5885' into develop
Close #5885
893782e
@weierophinney weierophinney self-assigned this Mar 5, 2014
@weierophinney
Zend Framework member

Merged to develop for release with 2.3.0.

@CreativeNative

Hey djungbluth, thanks for that.

I get missing parameter "locale" in file Zend/Mvc/Router/Http/Segment.php:298.

Could you please explain this a litte bit more for me. I'm not quite sure, how the translator get this locale. A working example would be nice.

@djungbluth

Hi CreativeNative,

A short example can be found in the tests:

ZendTest/Mvc/Router/Http/TranslatorAwareTreeRouteStackTest.php

  • testAssembleRouteWithParameterLocale
  • testMatchRouteWithParameterLocale

When assembling a route, you need to specify the locale either as a routing param or as a default.

Please, provide an excerpt of your code that leads to the exception you mentioned.

  • Daniel
@CreativeNative

Yep, you 're right. I missed the default. Now my route looks like this:

'type' => 'segment',
    'options' => array(
        'route' => '/:locale',
        'constraints' => array(
            'locale' => '[a-zA-Z][a-zA-Z]',
        ),
        'defaults'    => array(
            'locale'     => 'de',
            'controller' => 'Application\Controller\Index',
            'action'     => 'index',
        ),
    ),

But now it's not switching the translator locale if I type the url /de or /en. I think it has something to do with my bootstrapping which actualy looks like this.

Also when I commented out the setLocale and onPreRoute stuff it's not working.
$translator->getLocale() shows me than always 'en_US_POSIX'.

public function onBootstrap($e)
{
    ...

    /** @var $translator \Zend\I18n\Translator\Translator */
    $translator = $serviceManager->get('translator');
    $locale     = new \Locale();

    $httplanguages = getenv('HTTP_ACCEPT_LANGUAGE');
    if (empty($httplanguages) && isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
        $httplanguages = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
    }

    $translator->setLocale($locale->acceptFromHttp($httplanguages))->setFallbackLocale('de_DE');
    $locale->setDefault($translator->getLocale());

  ...

    // Route translator
    $eventManager->attach('route', array($this, 'onPreRoute'), 100);
}

/**
 * @param $e \Zend\Mvc\MvcEvent
 */
public
function onPreRoute($e)
{
    /** @var $application \Zend\Mvc\Application */
    $application    = $e->getApplication();
    $serviceManager = $application->getServiceManager();
    $serviceManager->get('router')->setTranslator($serviceManager->get('translator'));
}
@moderndeveloperllc

@CreativeNative Using just the HTTP_ACCEPT_LANGUAGE is a bit limiting. If you want auto-detection of the locale, I would look into modules like SlmLocale to see how they've done it. I think that module and what just got merged are complimentary, but I haven't tried it out. Hopefully @juriansluiman will make it so.

@juriansluiman

Thanks for the ping @moderndeveloperllc.

SlmLocale does locale detection before routing starts, so you can translate routes without having the need to define the locale as a route parameter. It might be tedious to pass on the current locale every time you use route assembling. However, I do agree these two things look complimentary.

@CreativeNative

Thanks for that hint. This is where I stuck with 'HTTP_ACCEPT_LANGUAGE'. When somebody with locale de_DE click on an en_EN translated link, it failes because of missing translation file. For that I will do my url's like this /de/ferienhaus or /en/vacation-home.

I like this way how @djungbluth has done it. Only have to know how the translator get the locale from route. This is not quite clear for me.

@juriansluiman

@CreativeNative as far as I see, this PR implements the locale directly from the route match parameters. As such, "en" is seen as a locale, not "en-US". The first is actually a language part, the second the complete locale. It can get quite messy with i18n (including date / number / currency formatting) if you only supply the language part and not the full locale. SlmLocale can make a mapping so "en" is assumed as "en-US". I am not sure if this segment part in the route can do the same.

@CreativeNative

I give your module a try. Looks like this will solve my problems. We'll see. 👍

@djungbluth

Just to put it straight: This patch is not about detecting the user's locale. It is about translating routes. And yes, "as such" it is required that the translator contains translations for a locale that can be found as a route match param.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment