Symfony 2 ссылка на текущую страницу

Как я могу создать ссылку на текущий в моем шаблоне?

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


person Johni    schedule 04.04.2012    source источник


Ответы (3)


Я заканчиваю тем, что запускаю свою собственную функцию для этого. Я хоть и был сначала включен где-то в FrameworkBundle но ничего по этому поводу не нашел. Вот шаги, которые я предпринял.

Сначала я создал функцию расширения Twig, которая выводит тот же маршрут, что и тот, который пользователь посещает в данный момент (включая параметры и строку запроса). Я оставил этот шаг вам. Вы можете посмотреть эту ссылку из хорошего учебника по Symfony2 для описания того, как создать расширение Twig, если вы еще не знаете, как это сделать. Я мог бы помочь вам с этим, если вам это нужно.

Следующим шагом является создание самой функции, которая будет переключать локаль текущего маршрута. Этой функции потребуются объекты Request и Router в качестве зависимостей. В моем личном случае я поместил эту функцию в специальный сервис с именем RoutingHelper service. Затем этот сервис используется моей функцией расширения Twig. Вот определение службы, которое я добавил в контейнер зависимостей:

acme.helper.routing:
    class: Application\AcmeBundle\Helper\RoutingHelper
    scope: "request"
    arguments:
        request: "@request"
        router: "@router"

И конструктор моего сервиса:

protected $request;
protected $router;

public function __construct($request, $router)
{
    $this->request = $request;
    $this->router = $router;
}

Параметр $locale — это новая локаль, на которую нужно переключиться. Здесь функция:

public function localizeCurrentRoute($locale)
{
    $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'] = $locale;

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

По сути, он делает то, что до сих пор делали другие, но также обрабатывает параметры и строку запроса. Метод filterPrivateKeys удалит частный атрибут из атрибутов маршрута. Эти атрибуты начинаются со знака подчеркивания и не должны передаваться обратно в генератор маршрутов. Вот его определение:

private function filterPrivateKeys($attributes)
{
    $filteredAttributes = array();
    foreach ($attributes as $key => $value) {
        if (!empty($key) && $key[0] != '_') {
            $filteredAttributes[$key] = $value;
        }
    }

    return $filteredAttributes;
}

В конце концов, я могу сделать это в своем представлении Twig, чтобы создать ссылки для переключения языков:

{% block language_bar %}
        <a href="{{ localize_route('en') }}"> English </a>
        <a href="{{ localize_route('fr') }}"> Français </a>
{% endblock %}

Изменить:

Вот мое определение службы расширения ветки:

acme.twig.extension:
    class: Application\AcmeBundle\Twig\Extension\AcmeExtension
    arguments:
      container: "@service_container"
    tags:
      -  { name: twig.extension }

И в функции расширения ветки у меня есть этот вызов: $routingHelper = $this->container->get('acme.helper.routing');

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

Обновление:

Теперь с Symfony 2.1 возможно иметь переключатель локали более простым способом, чем раньше. Действительно, версия Symfony 2.1 представила новый параметр для маршрутов, который упрощает более переключение локали. Вот код, все в ветке

{% set route_params = app.request.attributes.get('_route_params') %}

{# merge the query string params if you want to keep them when switching the locale #}
{% set route_params = route_params|merge(app.request.query.all) %}

{# merge the additional params you want to change #}
{% set route_params = route_params|merge({'_locale': 'fr'}) %}

{{ path(app.request.attributes.get('_route'), route_params) }} 

Это по-прежнему несколько строк кода ветки, но его можно включить в блок Twig для упрощения повторного использования. Спасибо stof от сообщества Symfony за приведенный выше код.

Надеюсь, это то, что вы ищете.

С уважением,
Мэтт

person Matt    schedule 04.04.2012
comment
Хорошо, так что я должен написать это сам. Я подумал, что в фреймворке должно быть что-то подобное, поскольку это важная функция. Мне удалось написать плагин и вспомогательный класс, но теперь у меня проблема с областью действия. Поскольку расширение помощника и ветки находится в: области: запрос, а сама ветка - нет (обнаружена инъекция, расширяющая область: ветка определения ссылается на службу s2_tools.twig.routing_helper, которая принадлежит к более узкой области. ). Как вам это удалось? - person Johni; 05.04.2012
comment
Да, я тоже думал об этом, но пока ничего не нашел. Хотелось бы увидеть что-то встроенное. Я решил эту проблему, внедрив контейнер с полным сервисом, а не извлекая из него своего помощника. Я отредактировал свой ответ, чтобы отразить это. - person Matt; 06.04.2012
comment
Хорошо, теперь я ввел полный сервисный контейнер. Теперь это работает. Спасибо. - person Johni; 10.04.2012
comment
@Parhs, если у вас есть более простое решение, я хотел бы услышать об этом. Когда я это сделал, я подумал, что для этого нужно много работы. Возможно, это решение можно было бы интегрировать в RouterBundle чего-то подобного для более удобного повторного использования... - person Matt; 06.05.2012
comment
@Parhs В мой ответ добавлено обновление с методом работы less для достижения того же результата в Symfony 2.1. - person Matt; 25.09.2012

<a href="{{ path(app.request.attributes.get('_route')) }}">Current page</a>

Аналогичный вопрос: переключение языка без изменения текущей страницы

person Anton Babenko    schedule 04.04.2012
comment
Да, но я также хочу использовать текущие параметры и изменить только локаль. - person Johni; 04.04.2012

person    schedule
comment
Да, это то, что я уже нашел, мне также нужен текущий параметр для построения маршрута для страниц с параметрами. - person Johni; 04.04.2012