Скачать Symfony

Скачать последнюю версию Symfony можно тут

Документация Symfony

Русская документация по Symfony тут (оригинальная документация на английском тут)

Сообщество Symfony

Symfony коммьюнити тусуется тут

Переключение локали без смены остальных параметров маршрута

0

 

Условия: необходимо создать механизм переключения языков на сайте, который позволяет пользователю изменить локаль без смены параметров маршрута. Например:

Пользователь открывает страницу блога для локали по-умолчанию: /blog/en/some-post с маршрутом 'blog_post' и параметрами {'_locale': 'en', 'slug': 'some-post '}. Когда пользователь переключается на локаль DE, он ожидает такой URI: /blog/de/some-post (т.е. изменится только локаль) с тем же самым маршрутом ('blog_post' )  и теми же параметрами (кроме локали) {'_locale': 'de', 'slug': 'some-post '}.

Ниже вы найдёте одно из возможных решений данной задачи.

Первая идея: а не могли бы мы решить данную задачу используя только Twig? Внутри шаблона мы можем получить доступ к маршруту и его параметрам:

{% requestAttributes =  app.request.attributes.all()  %}
Переменная requestAttributes теперь содержит массив array('_locale' => 'en', 'slug' => 'some-post ', '_route' => 'blog_post', '_controller' => 'SomeBlogController'}. Отлично. Но мы не можем изменить значение полей массива в Twig (в данном случае нам надо сменить _locale и очистить _route...)! Упс... 

Итак, мы не можем решить нашу задачу при помощи лишь Twig, но мы можем... расширить возможности Twig!

Вторая идея:

Создадим расширение Twig для работы с нашим массивом requestAttributes:
<?php
// src/Your/SiteBundle/Extension/TwigLocaleExtension.php

namespace Your\SiteBundle\Extension;

/**
* TwigLocaleExtension
*
*/
class TwigLocaleExtension extends \Twig_Extension
{
/**
* Returns the name of the extension.
*
* @return string The extension name
*/
public function getName()
{
return 'twig_locale_extension';
}

/**
* Returns a list of functions to add to the existing list.
*
* @return array An array of functions
*/
public function getFunctions()
{
return array(
'localeSwitch' => new \Twig_Function_Method($this, 'localeSwitch'),
);
}

/**
* Prepare route parameters for language switch.
*
* @param $newLocale
* @param $requestAttributes
*
* @return array
*/
public function localeSwitch($newLocale, $requestAttributes)
{
unset(
$requestAttributes['_controller'],
$requestAttributes['_route']
);
$requestAttributes['_locale'] = $newLocale;
return $requestAttributes;
}
}
Итак, мы создали новую функцию для Twig - localeSwitch(). Теперь осталось лишь зарегистрировать расширение:
<?php
// src/Your/SiteBundle/DependencyInjection/YourSiteExtension.php
namespace Your\SiteBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\Definition;

/**
* This is the class that loads and manages your bundle configuration
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class YourSiteExtension extends Extension
{
/**
* {@inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);

$definition = new Definition('Your\SiteBundle\Extension\TwigLocaleExtension');
$definition->addTag('twig.extension');
$container->setDefinition('twig_locale_extension', $definition);

$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');
}
}
Теперь в шаблоне вы можете использовать такую конструкцию:
<div>
{% set requestAttributes = app.request.attributes.all() %}
{% set route = requestAttributes._route %}
{% if app.session.getLocale() == 'en' %}
{% set newRouteParams = localeSwitch('de', requestAttributes) %}
<a href="{{ path(route, newRouteParams) }}">DE</a>
{% elseif app.session.getLocale() == 'de' %}
{% set newRouteParams = localeSwitch('en', requestAttributes) %}
<a href="{{ path(route, newRouteParams) }}">EN</a>
{% endif %}
</div>
Этот код проверен на этом сайте и работает для всех маршрутов сразу (он включен в layout в составе menu_block).

Hope this helps!

Поделиться: Плюсануть:

0 comments for "Переключение локали без смены остальных параметров маршрута"

Комментировать