Background
Given 1) the Symfony framework and 2) the need for localization, one shouldn't be surprised that there's a package that takes care of that already (somewhat): JMSI18nRoutingBundle. It works so that in your config.yml, you can specify the default locale, the locales that your site works with, and what the domain names are for each locale. I guess I'm not using this bundle correctly, though, because although my config.yml file looks like this:
jms_i18n_routing: default_locale: %locale% locales: [en, fr] strategy: custom hosts: en: www.englishVersion.com fr: www.frenchVersion.com redirect_to_host: true
typing in the French locale into the address bar redirects to the English site. (And if you happen to have an inkling of what I'm doing wrong, do let me know!)
This necessitates the extra steps of 1) creating a separate /fr path that serves up French content and 2) configuring .htaccess to redirect www.frenchVersion.com to that path.
The Problem
Given that 1) www.frenchVersion.com originally serves up English content and 2) needs coaxing in .htaccess to redirect, I hit the problem of English 404 pages appearing under the French domain. Ie., www.frenchVersion.com/path-does-not-exist will serve up the English 404 message.
The Solutions
The halfway solution - detect the language in the template
In my custom 404 page (in project_root\app\Resources\TwigBundle\views\Exception\error404.html.twig), I included an if-statement that checked the domain name and then set the variable lang appropriately.
{% set lang = ('frenchVersion' in app.request.getHost()) ? 'fr' : 'en' %}{{ 'projname.error404.copy' | trans({}, "messages", lang) }}
This solution only worked halfway, though. While the 404 message was in French, the surrounding layout.html.twig was still in English.
Full solution - create a listener for any exceptions thrown
With the guidance of this Stackoverflow answer, I was able to check for the domain name before anything was rendered when an exception is thrown. This is a two-file (or two-part) solution. First, you create a LanguageListener in projectroot\src\GenericName\SpecificNameBundle\EventListener. Code it like:
namespace GenericName\SpecificNameBundle\EventListener; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; class LanguageListener { public function setLocale(GetResponseEvent $event) { if (strstr($_SERVER['HTTP_HOST'], 'frenchVersion')) { $request = $event->getRequest(); $request->setLocale('fr'); } } }
And then in projectroot\src\GenericName\SpecificNameBundle\Resources\config\services.yml:
services: # ... genericname.language.kernel_request_listener: class: GenericName\SpecificNameBundle\EventListener\LanguageListener tags: - { name: kernel.event_listener, event: kernel.exception, method: setLocale }
And there you go! Even your layout should be rendered using the correct locale. Go try it out! Happy coding!
No comments:
Post a Comment