Symfony2-Rookie: установка пути динамически - PullRequest
1 голос
/ 05 января 2012

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

<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? поэтому, если я сейчас нахожусь на английской странице "о нас", я могу автоматически переключиться на немецкую страницу о нас, включая ее параметры«Это возможно?» или мне нужно жестко закодировать каждую страницу / шаблон ветки с путями?

Ответы [ 2 ]

3 голосов
/ 10 января 2012

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

ScopeWideningInjectionException можно исправить, введя @service_container для получения маршрутизатора и запроса вместо непосредственного введения их.

3 голосов
/ 05 января 2012

Жесткое кодирование - плохая идея, и это достижимо, но не из коробки, насколько я знаю. То, что я сделал, чтобы обеспечить 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

...