Возврат фильтра Twig внутри тега html

Я пытаюсь отобразить всплывающую подсказку Bootstrap намного проще и чище внутри шаблона ветки. Я хочу добиться чего-то вроде этого: <i class="icon" {{'this is great tooltip'|tooltip}}></i> Я создал фильтр веток:

class TooltipExtension extends \Twig_Extension{

    public function getFilters()
    {
        return array(
            new \Twig_SimpleFilter('tooltip', array($this, 'tooltipFilter',['is_safe'=>['html']])),
            new \Twig_SimpleFilter('tooltip_top', array($this, 'tooltipTopFilter')),
            new \Twig_SimpleFilter('tooltip_bottom', array($this, 'tooltipBottomFilter')),
            new \Twig_SimpleFilter('tooltip_left', array($this, 'tooltipLeftFilter')),
            new \Twig_SimpleFilter('tooltip_right', array($this, 'tooltipRightFilter')),
        );
    }

    public function tooltipFilter($title, $direction = "top")
    {
        switch($direction){
            case "top":
                return $this->tooltipTopFilter($title);

            case "bottom":
                return $this->tooltipBottomFilter($title);

            case "left":
                return $this->tooltipLeftFilter($title);

            case "right":
                return $this->tooltipRightFilter($title);

        }
    }

    public function tooltipTopFilter($title)
    {
        return ' data-toggle=tooltip data-placement=top title="'.$title.'" ';
    }

    public function tooltipBottomFilter($title)
    {
        return ' data-toggle=tooltip data-placement=bottom title='.$title.' ';
    }

    public function tooltipLeftFilter($title)
    {
        return ' data-toggle=tooltip data-placement=left title='.$title.' ';
    }

    public function tooltipRightFilter($title)
    {
        return ' data-toggle=tooltip data-placement=right title='.$title.' ';
    }

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

Он возвращает строку так, как я хочу. Но в html-коде это выглядит так:

<i data-original-title="&quot;this" class="icon" data-toggle="tooltip" data-placement="top" title="" is="" great="" tooltip&quot;=""></i>

Как видите, я добавил ['is_safe'=>['html']], но это совсем ничего не изменило.
Я пытался изменить пробел на жесткий, но безрезультатно.
Что еще хуже, всплывающая подсказка выглядит так: < a href="https://i.stack.imgur.com/QuM3l.png" rel="nofollow noreferrer">«эта игнорируя все пробелы, кавычки или апострофы. Это должно выглядеть так: это очень хорошая подсказка!
Помогите, пожалуйста, как это исправить! :)


person ptyskju    schedule 06.01.2016    source источник
comment
Вы пробовали использовать фильтры конвейера, добавляя необработанный фильтр после фильтра всплывающей подсказки? Что-то вроде этого: "data" | tooltip | raw? И, пожалуйста, добавьте часть вашего шаблона ветки, где вы вызываете свой фильтр...   -  person Ilya Yarkovets    schedule 06.01.2016
comment
Как я решил, играя с вашим кодом: $title = html_entity_decode(str_replace(' ', '&nbsp;', $title)); return ' data-toggle=tooltip data-placement=top title='.($title)';   -  person Ilya Yarkovets    schedule 06.01.2016
comment
['is_safe'=>['html']] равно ` |raw` Ваше решение почти отличное, но более длинные тексты не переносятся из-за $nbsp;. Я изменил его на и он отлично работает. Благодарю вас!   -  person ptyskju    schedule 06.01.2016
comment
Нет проблем, но я чувствую, что это решение уродливо. Если вы найдете другое решение - пожалуйста, оставьте заметку здесь.   -  person Ilya Yarkovets    schedule 06.01.2016
comment
Нет проблем :) Еще раз спасибо за это решение!   -  person ptyskju    schedule 06.01.2016


Ответы (2)


Благодаря @Ilya Yarkovets я нашел способ решить эту проблему. Все, что мне нужно было сделать, это изменить $title, сделав это:

$title = html_entity_decode(str_replace(' ', '&thinsp;', $title));
return ' data-toggle=tooltip data-placement=top title='.($title).' ';

&thinsp был лучше, чем   из-за переноса текста.

person ptyskju    schedule 06.01.2016

Благодаря динамическим фильтрам Twig вы можете упростить код своего расширения, следует:

class TooltipExtension extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
            new \Twig_SimpleFilter('tooltip', array($this, 'tooltip',['is_safe'=>['html']])),
            new \Twig_SimpleFilter('tooltip_*', array($this, 'positionedTooltip', ['is_safe'=>['html']])),
        );
    }

    public function tooltip($title)
    {    
        return $this->positionedTooltip('top', $title);
    }

    public function positionedTooltip($position, $title)
    {
        $validPositions = ['top', 'bottom', 'left', 'right'];
        if (!in_array($position, $validPositions)) {
            throw new \InvalidArgumentException(sprintf('The position of the tooltip can only be one of the following: %s', implode(', ', $validPositions)));
        }

        return sprintf(' data-toggle=tooltip data-placement=%s title="%s" ', $position, $title);
    }

    public function getName()
    {
        return 'tooltip_extension';
    }
}
person Javier Eguiluz    schedule 07.01.2016
comment
Но где я могу указать $direction? Я думаю, что возвращаемая строка должна выглядеть так: data-toggle=tooltip data-placement='.$direction.' title="'.$title.'" ' - person ptyskju; 07.01.2016
comment
Ты прав! Я обновил код PHP, чтобы исправить некоторые проблемы. - person Javier Eguiluz; 07.01.2016
comment
За все время, что я расширил Twig, я даже не знал о динамических фильтрах - спасибо Хавьеру за внимание. - person Jason Roman; 07.01.2016