Последние записи в блоге

Внутренности Twig

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

Как работает Twig?

Рендеринг шаблона Twig может быть представлен в виде четырех основных этапов:

  • Загрузка шаблона: Если шаблон уже скомпилирован, загрузите его и переходите к этапу оценки, в противном случае:

    • Во-первых, lexer разбивает на мелкие кусочки (лексемы) код-исходник шаблона для облегчения обработки;
    • Затем parser преобразует поток лексем в осмысленное дерево узлов (the Abstract Syntax Tree);
    • И затем, компилятор преобразует AST в PHP код.
  • Оценка шаблона: Это в основном означает вызов метода display() из скомпилированного шаблона и передачи ему контекста.

Лексер

Лексер разбивает на лексемы код-исходник шаблона в поток символов (каждый символ является экземпляром Twig_Token, и поток является экземпляром Twig_TokenStream). Лексер по умолчанию распознает 13 различных типов символов:

  • Twig_Token::BLOCK_START_TYPE, Twig_Token::BLOCK_END_TYPE: Разделители для блоков ({% %})
  • Twig_Token::VAR_START_TYPE, Twig_Token::VAR_END_TYPE: Разделители для переменных ({{ }})
  • Twig_Token::TEXT_TYPE: Текст за пределами выражения;
  • Twig_Token::NAME_TYPE: Имя в выражении;
  • Twig_Token::NUMBER_TYPE: Число в выражении;
  • Twig_Token::STRING_TYPE: Строка в выражении;
  • Twig_Token::OPERATOR_TYPE: Оператор;
  • Twig_Token::PUNCTUATION_TYPE: Знак пунктуации;
  • Twig_Token::INTERPOLATION_START_TYPE, Twig_Token::INTERPOLATION_END_TYPE (начиная с Twig 1.5): Разделители для строчной интерполяции;
  • Twig_Token::EOF_TYPE: Конец шаблона.

Вы можете вручную преобразовать код-исходник в поток символов вызовом метода среды tokenize():

$stream = $twig->tokenize($source, $identifier);

Поскольку поток имеет метод __toString(), вы можете иметь текстовое представление объекта с помощью команды echo:

echo $stream;

Далее представлен результат для шаблона Hello {{ name }}:

TEXT_TYPE(Hello )
VAR_START_TYPE()
NAME_TYPE(name)
VAR_END_TYPE()
EOF_TYPE()

По умолчанию лексер (Twig_Lexer) может быть изменен с помощью вызова метода setLexer():

$twig->setLexer($lexer);

Парсер

Парсер преобразует поток символов в AST (Abstract Syntax Tree), или узел дерева (экземпляр Twig_Node_Module). Расширение ядра определяет основные узлы, как: for, if, ... и узлы выражения.

Вы можете вручную преобразовать поток символов в древо узлов, вызвав метод parse():

$nodes = $twig->parse($stream);

Команда echo для объекта узел представит дерево в удобной форме:

echo $nodes;

Ниже показан результат для шаблона Hello {{ name }} :

Twig_Node_Module(
  Twig_Node_Text(Hello )
  Twig_Node_Print(
    Twig_Node_Expression_Name(name)
  )
)

По умолчанию парсер (Twig_TokenParser) может быть изменен с помощью вызова метода setParser():

$twig->setParser($parser);

Компилятор

Последний шаг осуществляется компилятором. Он принимает древо узлов на вход и генерирует PHP код, чтобы он был пригодным для выполнения шаблона.

Вы можете вручную скомпилировать древо узлов в PHP код методом среды compile():

$php = $twig->compile($nodes);

Сгенерированный шаблон для Hello шаблона выглядит следующим образом (фактический результат может отличаться в зависимости от версии Twig, которую вы используете):

/* Hello {{ name }} */
class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Twig_Template
{
    protected function doDisplay(array $context, array $blocks = array())
    {
        // line 1
        echo "Hello ";
        echo twig_escape_filter($this->env, $this->getContext($context, "name"), "ndex", null, true);
    }

    // some more code
}

Компилятор по умолчанию (Twig_Compiler) может быть изменен с помощью вызова метода setCompiler():

$twig->setCompiler($compiler);
Агрегатор фриланс бирж FreelanceGrab, искать заказы на фрилансе стало еще проще.
8 крупных бирж, удобный поиск и фильтрация по проектам,
моментальное обновление ленты без перезагрузки страницы