Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

parametrized-locale-aware routing #5885

Closed
wants to merge 4 commits into from

Conversation

djungbluth
Copy link

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 Jungbluth added 4 commits February 28, 2014 17:16
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‘).
@weierophinney weierophinney added this to the 2.3.0 milestone Mar 3, 2014
weierophinney added a commit that referenced this pull request Mar 5, 2014
parametrized-locale-aware routing
weierophinney added a commit that referenced this pull request Mar 5, 2014
weierophinney added a commit that referenced this pull request Mar 5, 2014
@weierophinney weierophinney self-assigned this Mar 5, 2014
@weierophinney
Copy link
Member

Merged to develop for release with 2.3.0.

@CreativeNative
Copy link

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
Copy link
Author

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
Copy link

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
Copy link
Contributor

@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
Copy link
Contributor

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
Copy link

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
Copy link
Contributor

@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
Copy link

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

@djungbluth
Copy link
Author

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 subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants