В последнее время в работе над проектами мне требуется база данных на MySQL, я конечно же мог развер...
Простая загрузка на сервер и слежение за изменениями файловой системы через небольшой bash скрипт ...
Небольшая подборка разных инструментов javascript для разработчиков ...
Wget - это небольшая консольная программа, выполняющая роль загрузчика файлов из Интернета, либо чер...
Нативные аналоги функций jQuery, которыми я зачастую пользуюсь ...
По умолчанию настройки виртуальных хостов Apache на Mac OS X находятся в файле /etc/apache2/extra/ht...
Недавно перешел на Mac OS Yosemite, в его базовой комплектации уже имеется web server Apac...
В твиге есть много полезного, но порой этого не хватает для решения поставленных задач. Например,&nb...
Автор: Дмитрий Цирульников
Дата: 9 Октября 2014
Наследование в Twig очень мощная штука, но не хватает тут одного - переопределения макросов.
Суть задачи в следующем: есть файл с макросами macro.twig
{% macro test() %} Hello {{ _self.test_1() }} {% endmacro %} {% macro test_1() %} World {% endmacro %}
Из одного макроса вызываем второй, в результате работы {{ test() }} мы получим уже изрядно намозоливший «Hello World».
У нас же задача переопределить макрос test_1.
Сразу код, комментарии ниже:
{% macro macro_extend( macroName, macroOptions, mergeList ) %} {% set source_ %} {% for path in mergeList %} {{ source(path) }} {% endfor %} {% endset %} {% set args %} {% for index in macroOptions|keys %} macroOptions[{{ index }}] {% endfor %} {% endset %} {% set controll = '{{ _self.' ~ macroName ~ '(' ~ args ~ ') }}' %} {{ include(template_from_string( source_ ~controll )) }} {% endmacro %}
Для удобства создаем макрос extend, который как аргументы принимает:
Основной смысл затеи - собрать все макросы в одно место и вызвать нужный. Это все можно сделать при помощи spurce, include и template_from_string и магического _self.
Есть одна особенность в парсере твига для макросов: если парсер натыкается на два макроса названные одинаково, то он запомнит последний из них, то есть:
{% macro test() %} test 1 {% endmacro %} {% macro test() %} test 2 {% endmacro %}
Результатом вызова {{ test() }} будет test 2. Это-то нам и поможет переопределять макросы так, как нам нужно.
Чтобы сделать вызов определенного макроса из цепочки на лету нам понадобится _self, он ссылается на текущую область видимости, и через нее можно вызвать нужный нам макрос.
Вот, собственно, и вся хитрость, которая облегчит жизнь при построении сложных шаблонов с многочисленными контроллами.
PS: Пример вызова моего макроса
{% from 'macro_extend.twig' import macro_extend %} {{ macro_extend('test', [], [ 'test.twig', 'test2.twig' ]) }}