XF 2.2 Добавление своего тега в шаблоны

Версия XenForo
2.2

rozhur

Проверенные
Сообщения
144
Решения
3
Реакции
201
Баллы
1,755
Здравствуйте.

Понадобилось добавить свой тег, аналогичный <xf:sidenav...

Создал класс Template\Compiler\Tag\SidePanel, добавил нужные переменные в PAGE_CONTAINER, и т.д. Проблема лишь в том, что при добавлении неизвестного тега происходит ошибка, что его не существует.

Изучая движок, не нашел метода, как его добавить. Вижу, что за генерацию этих тегов отвечает класс Template\Compiler, но система расширений классов его не расширяет, и сама переменная, где хранятся эти теги, является protected.

Решил пойти костыльным путем: В Compiler нашел метод setTag, через который все таки можно добавить свой тег, к которому даже можно указать свой класс тега. Т.к. Compiler расширить не получится, решил ловить ивент app_setup:
PHP:
public function setTag($name, $tag)
{
    if (is_string($tag))
    {
        $class = $tag[0] == '\\' ? $tag : __NAMESPACE__ . '\\Compiler\\Tag\\' . $tag;
        $tag = new $class($name);
    }
    if (!($tag instanceof AbstractTag))
    {
        throw new \InvalidArgumentException("Tag must be a class name or object that is an instance of AbstractTag");
    }

    $this->tags[$name] = $tag;

    return $this;
}
PHP:
<?php

namespace Extender;

class Listener
{
    public static function init(\XF\App $app)
    {
        $compiler = $app->templateCompiler();
        $compiler->setTag('sidepanel', '\Extender\Template\Compiler\Tag\SidePanel');
    }
}

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

Есть ли другие решения?
 
Решение
Обработчик не спит. Его вообще ещё на тот момент нет в движке.
Вынесите тег в отдельное дополнение.

И есть более правильный путь:
PHP:
<?php
   
namespace HLmod;

class Listener
{
    /**
     * @see app_setup
     */
    public static function onAppSetup(\XF\App $app)
    {
        $app->container()->extend('templateCompiler', function(\XF\Template\Compiler $compiler, \XF\Container $container)
        {
            $compiler->setTag('tag_name', 'Tag\Handler');
            return $compiler;
        });
    }
}

Но, как выше сказали, не рекомендуется свои теги делать.
Разработчики писали где-то, что не рекомендуется добавлять свои теги, ибо это приводит к описанным вами проблемам.
Вместо этого лучше добавляйте своё добро в виде функций шаблонизатора.
 
Обработчик не спит. Его вообще ещё на тот момент нет в движке.
Вынесите тег в отдельное дополнение.

И есть более правильный путь:
PHP:
<?php
   
namespace HLmod;

class Listener
{
    /**
     * @see app_setup
     */
    public static function onAppSetup(\XF\App $app)
    {
        $app->container()->extend('templateCompiler', function(\XF\Template\Compiler $compiler, \XF\Container $container)
        {
            $compiler->setTag('tag_name', 'Tag\Handler');
            return $compiler;
        });
    }
}

Но, как выше сказали, не рекомендуется свои теги делать.
 
Современный облачный хостинг провайдер | Aéza
Назад
Сверху Снизу