Пакет меню KNP со специальными символами HTML

Я использую пакет меню KNP в своем проекте Symfony2 и создаю свои меню как услугу.

У меня проблема с тем, что кавычки Route Labels и другие специальные символы отображаются неправильно.

В качестве примера:

Test Text & Stuff будет отображаться как Test Text & Stuff, и я не могу понять, как с этим справиться.

Я создаю маршрут следующим образом:

$menu->addChild('seller', array(
    'route' => 'routename',
    'routeParameters' => $array,
    'label' => $sellername
))->setLinkAttribute('class', 'dark-color active-hover');

Я попытался с помощью этой команды избавиться от него:

  1. html_entity_decode()
  2. htmlspecialchars_decode()
  3. htmlспециальныесимволы()
  4. htmlсущности()

Но ни один из них не работал. Не было бы большой проблемы, если бы браузер переводил их правильно, но браузер не делает этого из-за этого:

                 Test Text & Stuff                     

До и после моего текста много пробелов, и я не могу понять, откуда он взялся. Я обрезал $sellername, а также добавил команды обрезки из ветки в knp_menu.html.twig.

Любые предложения, как я могу справиться с этой ситуацией?

Редактировать:

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

Редактировать:

Вот шаблон knp_menu.html.twig

{% extends 'knp_menu.html.twig' %}

{% block item %}
    {% import "knp_menu.html.twig" as macros %}
    {% if item.displayed %}
        {%- set attributes = item.attributes %}
        {%- set is_dropdown = attributes.dropdown|default(false) %}
        {%- set icon = attributes.icon|default(false) %}
        {%- set span = attributes.span|default(false) %}
        {%- set spanContent = attributes.spanContent|default(false) %}
        {%- set notification = attributes.notification|default(false) %}
        {%- set divider_prepend = attributes.divider_prepend|default(false) %}
        {%- set divider_append = attributes.divider_append|default(false) %}

        {# unset bootstrap specific attributes #}
        {%- set attributes = attributes|merge({'dropdown': null, 'icon': null, 'span': null, 'spanContent': null, 'notification': null, 'divider_prepend': null, 'divider_append': null }) %}

        {%- if divider_prepend %}
            {{ block('dividerElement') }}
        {%- endif %}

        {# building the class of the item #}
        {%- set classes = item.attribute('class') is not empty ? [item.attribute('class')] : [] %}
        {%- if matcher.isCurrent(item) %}
            {%- set classes = classes|merge([options.currentClass]) %}
        {%- elseif matcher.isAncestor(item, options.depth) %}
            {%- set classes = classes|merge([options.ancestorClass]) %}
        {%- endif %}
        {%- if item.actsLikeFirst %}
            {%- set classes = classes|merge([options.firstClass]) %}
        {%- endif %}
        {%- if item.actsLikeLast %}
            {%- set classes = classes|merge([options.lastClass]) %}
        {%- endif %}

        {# building the class of the children #}
        {%- set childrenClasses = item.childrenAttribute('class') is not empty ? [item.childrenAttribute('class')] : [] %}
        {%- set childrenClasses = childrenClasses|merge(['menu_level_' ~ item.level]) %}

        {# adding classes for dropdown #}
        {%- if is_dropdown %}
            {%- if item.level > 1 %}
                {%- set classes = classes|merge(['dropdown-submenu']) %}
            {%- else %}
                {%- set classes = classes|merge(['dropdown']) %}
            {%- endif %}
            {%- set childrenClasses = childrenClasses|merge(['dropdown-menu']) %}
        {%- endif %}

        {# putting classes together #}
        {%- if classes is not empty %}
            {%- set attributes = attributes|merge({'class': classes|join(' ')}) %}
        {%- endif %}
        {%- set listAttributes = item.childrenAttributes|merge({'class': childrenClasses|join(' ') }) %}

        {# displaying the item #}
        <li{{ macros.attributes(attributes) }}>
            {%- if is_dropdown %}
                {{- block('dropdownElement') -}}
            {%- elseif item.uri is not empty and (not matcher.isCurrent(item) or options.currentAsLink) %}
                {{- block('linkElement') -}}
            {%- else %}
                {{- block('spanElement') -}}
            {%- endif %}
            {# render the list of children#}
            {{- block('list') -}}
        </li>

        {%- if divider_append %}
            {{ block('dividerElement') }}
        {%- endif %}
    {% endif %}
{% endblock %}

{% block linkElement %}
    <a href="{{ item.uri }}"{{ knp_menu.attributes(item.linkAttributes) }}>
        {% if item.attribute('icon') is not empty %}
            <i class="{{ item.attribute('icon') }}"></i>
        {% endif %}
        {{ block('label')|trim }}
        {% if item.attribute('notification') is not empty %}
            <span class="bagde"><icon class=" {{ item.attribute('notification') }}"></icon></span>
        {% endif %}
        {% if item.attribute('span') is not empty %}
            <span class="{{ item.attribute('span') }}">{% if item.attribute('spanContent') is not empty %}{{ item.attribute('spanContent')}}{% endif %}</span>
        {% endif %}
    </a>
{% endblock %}

{% block dividerElement %}
    {% if item.level == 1 %}
        <li class="sidebar-divider"></li>
    {% else %}
        <li class="divider"></li>
    {% endif %}
{% endblock %}

{% block dropdownElement %}
    {%- set classes = item.linkAttribute('class') is not empty ? [item.linkAttribute('class')] : [] %}
    {%- set classes = classes|merge(['dropdown-toggle']) %}
    {%- set attributes = item.linkAttributes %}
    {%- set attributes = attributes|merge({'class': classes|join(' ')}) %}
    {%- set attributes = attributes|merge({'data-toggle': 'dropdown'}) %}
    <a href="#"{{ macros.attributes(attributes) }}>
        {% if item.attribute('icon') is not empty %}
            <i class="{{ item.attribute('icon') }}"></i>
        {% endif %}
        {{ block('label')|trim }}
        {% if item.level <= 1 %} <b class="caret"></b>{% endif %}</a>
{% endblock %}

{% block label %}{{ item.label|trim|trans }}{% endblock %}

person KhorneHoly    schedule 30.06.2015    source источник
comment
Не могли бы вы добавить свой шаблон knp_menu.html.twig? Вероятно, вам нужно использовать {{ labelVariable|raw }}. Ваша проблема может быть связана с автоматическим экранированием twig.   -  person tftd    schedule 02.07.2015
comment
@tftd я обновил свой вопрос   -  person KhorneHoly    schedule 02.07.2015
comment
Попробуйте заменить содержимое {%block label%} на {{ item.label|raw|trim|trans }}   -  person tftd    schedule 02.07.2015
comment
Похоже, проблема связана с trim. Попробуйте заменить {{ block('label')|trim }} на {{ block('label') }}, и это должно сработать (по крайней мере, у меня работает).   -  person VolenD    schedule 02.07.2015
comment
завтра попробую, сегодня не на работе   -  person KhorneHoly    schedule 02.07.2015
comment
Он также работает с {{ block('label')|trim|raw }}. Кажется, что Twig автоматически экранирует символы в trim.   -  person VolenD    schedule 02.07.2015


Ответы (1)


Что делает сырье?

По умолчанию при отображении чего-либо в Twig (используя {{ }}) Twig будет экранировать это, чтобы убедиться, что это безопасно. Мы не хотим, чтобы какой-либо вредоносный HTML оказался на наших страницах.

Иногда то, что мы хотим отобразить, уже является HTML, поэтому мы не хотим снова его экранировать. Вот тут-то и пригодится фильтр raw! Он сообщает twig, что то, что он только что «отфильтровал», уже экранировано, мы хотим использовать его в необработанном виде (например, не экранировать его снова).

Как работать с сырьем

block('label') отобразит блок с именем «метка». Этот рендеринг будет выполнен html-безопасным, что означает, что он экранирован.

Отобразив его в другом шаблоне (выполнив {{ block('label') }}), он снова будет экранирован. Если вам это не нужно, используйте фильтр raw: {{ block('label')|raw }}

Фильтр raw должен использоваться последним, иначе он не будет работать. Поэтому, если вы хотите обрезать рендеринг, сделайте это в первую очередь: {{ block('label')|trim|raw }}

PS: Даже когда вы делаете что-то более сложное, вам все равно придется использовать raw в конце и в целом. Например: {{ ('<span>' ~ block('label')|trim ~ '</span>')|raw }}

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

Подробнее об фильтре необработанных данных и расширение escaper

person Jasper N. Brouwer    schedule 02.07.2015
comment
Это работает, что делает меня очень счастливым. Но почему это работает с |raw? С |raw не сбежать? - person KhorneHoly; 03.07.2015
comment
Я обновил свой ответ, надеюсь, он отвечает на вопрос, что на самом деле делает raw. - person Jasper N. Brouwer; 03.07.2015
comment
Спасибо за обновление, теперь я это понял, мне очень помогло! PS: у вас опечатка в raw for (e.g. not escape it again)., думаю должно быть forM - person KhorneHoly; 03.07.2015
comment
Спасибо, опечатка исправлена ​​:) - person Jasper N. Brouwer; 03.07.2015
comment
Извините за запоздалое присуждение этой награды, я был болен, но вы ее полностью заслужили :) - person KhorneHoly; 08.07.2015