2012-01-05 3 views
1

хорошо, я сумел поставить код для моей тестовой страницы для переключения языков в сочетании с JMSTranslationBundle, как это в веточкеSymfony2-Rookie: Установка Путь динамически

<li> 
<a href="{{ path("main", {"_locale": "en","name": name}) }}"> 
<img src="{{ asset('img/flags/gb.png') }}"></a></li> 
<li> 
<a href="{{ path("main", {"_locale": "de","name": name}) }}"> 
<img src="{{ asset('img/flags/de.png') }}"></a></li> 

, но это будет работать на path ("main") как я могу сделайте его динамически работать для страницы/маршрута, над которым я сейчас работаю, включая необходимый параметр (в данном случае "name": name? так что если я нахожусь в настоящее время на странице «о нас», я могу автоматически переключиться на немецкую страницу о нас, в том числе его параметры? возможно ли это? или мне нужно жестко кодировать каждую страницу/шаблон страницы с путями?

ответ

3

Это описывает расширение так же, как вы ищете: http://blog.viison.com/post/15619033835/symfony2-twig-extension-switch-locale-current-route

ScopeWideningInjectionException может быть исправлена ​​путем введения @service_container получить маршрутизатор и запрос вместо инъекционных их непосредственно.

+0

работает как шарм, спасибо миллиону человек! – Confidence

3

Hardcoding - плохая идея, и это возможно, но не из коробки, насколько я знаю. То, что я сделал, чтобы предоставить URL-адрес с одним и тем же путем и параметрами, но для другого языкового стандарта, заключался в создании пользовательского расширения ветви, чтобы это сделать.

Это расширение обеспечивает новую функцию твига, которая будет считывать текущий маршрут, текущие параметры, исключать частные параметры и генерировать один и тот же маршрут, но для другого языкового стандарта. Здесь расширение прут в вопросе:

<?php 

namespace Acme\WebsiteBundle\Twig\Extension; 

use Symfony\Component\DependencyInjection\ContainerInterface; 

class LocalizeRouteExtension extends \Twig_Extension 
{ 
    protected $request; 
    protected $router; 

    public function __construct(ContainerInterface $container) 
    { 
     $this->request = $container->get('request'); 
     $this->router = $container->get('router'); 
    } 

    public function getFunctions() 
    { 
     return array(
      'localize_route' => new \Twig_Function_Method($this, 'executeLocalizeRoute', array()), 
     ); 
    } 

    public function getName() 
    { 
     return 'localize_route_extension'; 
    } 

    /** 
    * Execute the localize_route twig function. The function will return 
    * a localized route of the current uri retrieved from the request object. 
    * 
    * The function will replace the current locale in the route with the 
    * locale provided by the user via the twig function. 
    * 
    * Current uri: http://www.example.com/ru/current/path?with=query 
    * 
    * In Twig: {{ localize_route('en') }} => http://www.example.com/en/current/path?with=query 
    *   {{ localize_route('fr') }} => http://www.example.com/fr/current/path?with=query 
    * 
    * @param mixed $parameters The parameters of the function 
    * @param string $name The name of the templating to render if needed 
    * 
    * @return Output a string representation of the current localized route 
    */ 
    public function executeLocalizeRoute($parameters = array(), $name = null) 
    { 
     $attributes = $this->request->attributes->all(); 
     $query = $this->request->query->all(); 
     $route = $attributes['_route']; 

     # This will add query parameters to attributes and filter out attributes starting with _ 
     $attributes = array_merge($query, $this->filterPrivateKeys($attributes)); 

     $attributes['_locale'] = $parameters !== null ? $parameters : \Locale::getDefault(); 

     return $this->router->generate($route, $attributes); 
    } 

    /** 
    * This function will filter private keys from the attributes array. A 
    * private key is a key starting with an underscore (_). The filtered array is 
    * then returned. 
    * 
    * @param array $attributes The original attributes to filter out 
    * @return array The filtered array, the array withtout private keys 
    */ 
    private function filterPrivateKeys($attributes) 
    { 
     $filteredAttributes = array(); 
     foreach ($attributes as $key => $value) { 
      if (!empty($key) && $key[0] != '_') { 
       $filteredAttributes[$key] = $value; 
      } 
     } 

     return $filteredAttributes; 
    } 
} 

Теперь вы можете включить это расширение прут, загрузив это определение службы либо с помощью вашего комплекта, либо непосредственно в файл config.yml, расположенный под app/config.

services: 
     acme.twig.extension: 
     class: Acme\WebsiteBundle\Twig\Extension\LocalizeRouteExtension 
     scope: request 
     arguments: 
      request: "@request" 
      router: "@router" 
     tags: 
      - { name: twig.extension } 

И теперь вы можете сделать это в веточке, чтобы предложить другую версию текущей загруженной страницы:

<a id='englishLinkId' href="{{ localize_route('en') }}"> 
    English 
</a> 
<a id='frenchLinkId' href="{{ localize_route('fr') }}"> 
    Français 
</a> 

Надеется, что это помогает, и что это то, что вы ищете.

Edit:

Кажется, что это не представляется возможным, чтобы сузить область расширения прута непосредственно. Чтобы этого избежать, сначала добавьте контейнер зависимостей, а затем извлеките необходимые службы. Это должно быть отражено путем изменения определения конструктора расширения ветки и определения службы для расширения. Я отредактировал свой предыдущий ответ, проверил новое обновленное определение конструктора и новое определение службы.

Другим возможным решением было бы ввести вспомогательную службу, которая отвечает за локализацию маршрута. Эта вспомогательная служба должна находиться в области запроса. Фактически, это то, что у меня есть в моем коде. У меня есть служба RoutingHelper, которая вводится в расширение моей ветки. Затем, в методе executeLocalizeRoute, я использую свой помощник, чтобы выполнить тяжелую работу.

Сообщите мне, если все работает сейчас.

С уважением,
Matt

+0

сладкий ... выглядит очень аккуратно, спасибо, человек ... попробуем, важно для меня, если он распознает параметры .... возможно, более простой вариант заключается в том, что каждый пользователь определяет их локаль под настройками, и он автоматически набор оттуда .... но мне это нужно хотя бы для страниц без входа. – Confidence

+0

Я пробовал ваше решение. но я получаю: «Обнаружение области видимости: обнаружено: определение« веточка »ссылается на сервис« tracker.twig.extension », который относится к более узкому пространству. Как правило, безопаснее перемещать «ветку» в запрос «область действия» или альтернативно полагаться на шаблон поставщика, вставляя сам контейнер и запрашивая услугу «tracker.twig.extension» каждый раз, когда это необходимо. Однако в редких особых случаях, которые могут не понадобиться, вы можете установить ссылку на strict = false, чтобы получить , чтобы избавиться от этой ошибки. ' – Confidence

+0

Я отредактирую свой ответ, чтобы исправить вашу проблему. – Matt

 Смежные вопросы

  • Нет связанных вопросов^_^