Roy van Kaathoven
Full Stack Developer

06 Nov

Translating urls in Zend Framework 2

Recently i needed to build a multi language website using Zend Framework 2. The framework has a lot options to translate the website, but one thing that was lacking in the documentation was a method to translate URL's.

After some research i found a Pull Request which adds the ability to translate routes. The current version only supports the Segment route for now, which is fine for basic routing.

In order to start translating routes the router needs to be aware of the translator, do this by injecting the translator into the router during the module bootstrap.

namespace Application;

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        $app = $e->getApplication();
        $sm = $app->getServiceManager();
        $translator = $sm->get('translator');

        // Attach the translator to the router
        $e->getRouter()->setTranslator($translator);
    }
}

Now the routes can be translated, it requires some modifications to the URL's which are configured in the 'router.routes' key in the module.config.ph

By default the router object does not support translating so it has to be replaced by a router which is translator aware. Replace the router with TranslatorAwareTreeRouteStack by setting the router_class configuration.

The segments can be translated by wrapping the parts which needs to translated within curly braces. If the route is called 'home' then it must be replaced with '{home}'

return [
    'router' => [
        // Replace the default router with the Translator aware TreeRouteStack
        'router_class' => 'Zend\Mvc\Router\Http\TranslatorAwareTreeRouteStack',
        'routes' => [
            'home' => [
                'type' => 'Segment',
                'options' => [
                    'route' => '/{home}', // The parts within curly braces will be translated
                    'defaults' => [
                        'controller' => '...',
                        'action' => 'index',
                    ],
                ],
                'may_terminate' => true,
                'child_routes' => [
                    'profile' => [
                        'type' => 'Segment',
                        'options' => [
                            'route' => '/{profile}',
                            'defaults' => [
                                'controller' => '...',
                                'action' => 'profile',
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
];