====== Создание собственных MACRO-тегов ====== Мы предполагаем, что вам уже знакомы материалы следующих разделов: * [[limb3:ru:packages:macro:important_details|"Компиляция и выполнение шаблона. Пример рендеринга MACRO-шаблона"]], * [[limb3:ru:packages:macro:compiler|"Как работает компилятор MACRO-шаблонов"]], Теги хранятся в файлах с именем some_tag_name.tag.php, который должен быть расположен в одной из директорий вида src/macro пакетов или приложения, а также в папке /limb/macro/src/tags. Обратите внимание на окончание .tag.php - только их таких файлов информацию попадает в словарь тегов. ===== Аннотации тегов ===== Перед самой декларацией класса тега существует зона комментариев в стиле phpDoc - это зона аннотаций тега, например: Полный список аннотация для тегов: * **tag** - название тега, которое может использовать внутри шаблона. Регистр не имеет значения. * **aliases** - другие имена тегов. Можно указывать несколько альтернативных названий тегов через запятую, например: @aliases params,param. * **req_attributes** - список атрибутов тега, которые должны обязательно присутствовать в шаблоне. * **parent_tag_class** - указывает название класса родительского тега, внутри которого обязан находиться. Если эта аннотация указана, а родительский тег не найден - будет сгенерирована ошибка компиляции. * **restrict_self_nesting** - запрещает тегу иметь в качестве непосредственного родителя аналогичный тег. * **forbid_end_tag** - запрещает тег иметь открывающий и закрывающий тег. То есть для данных тегов доступна только короткая форма, например, %%{{include}}%% или %%{{include/}}%%, но не %%{{include}}%%[...]%%{{/include}}%% ===== Базовые классы для тегов ===== * **lmbMacroTag** - используется в качестве родительского в самых общих случаях. Примеры подобных тего - %%{{include}}%%, %%{{list}}%%, %%{{list:item}}%% и т.д. * **lmbMacroPassiveTag** - используется в качестве родительского в случаях, когда тег сам в комплируемый шаблон ничего не пишет, однако может писать, если его об этом попросить явно при помощи метода **generateNow($code_writer)** * **lmbMacroRuntimeWidgetTag** - этот класс используется, если предполагается, что для работы тега потребуется какой-то объект-helper или widget. Пример такого тега: %%{{pager}}%%. При использовании данного тега необходимо определить 2 атрибута: * **$widget_class_name** - название класса widget-а * **$widget_include_file** - путь до файла, который содержит определение класса $widget_class_name Это определение можно сделать также в методе preParse(lmbMacroCompiler $compiler) (см. пример limb/macro/src/tags/form/input.tag.php) lmbMacroRuntimeWidgetTag использует метод lmbMacroCodeWriter :: **writeToInit($php_code)**, который используется для записи инициализирующего кода в генерируемый шаблон. lmbMacroRuntimeWidgetTag создает объект, как атрибут генерируемого класса с именем, которое можно получить при помощи метода **getRuntimeVar()**. **getRuntimeVar()** - возвращает кусок php-кода, который ссылается на объект widget-а, обычно это что-то вроде $this->tag_tag_id. * **lmbMacroRuntimeWidgetHtmlTag** - этот класс используется в качестве родителя в случае, если MACRO-тег на этапе выполнения генерит html-тег, и для этого используется специальный widget, который наследуют от класса **lmbMacroHtmlTagWidget**. lmbMacroRuntimeWidgetHtmlTag требует также указания атрибута **$html_tag**. Примеры - это большинство тегов в папке limb/macro/src/tags/form/ * **lmbMacroFormElementTag** - этот класс используется в качестве родителя в случае, если MACRO-тег на этапе выполнения генерит какой-то аналоги html-тега элемента формы. Этот класс можно найти в файле limb/macro/src/tags/form/lmbMacroFormElementTag.class.php ===== Методы, которые можно перекрывать ===== То, какие методы перекрывать, зависит от типа создаваемого тега: Если это будет обычный тег (не имеющий html-аналога), тогда вы скорее всего будете наследоваться от lmbMacroTag или lmbMacroRuntimeWidgetTag и вам лучше всего перекрывать следующие методы: * _generateBeforeContent($code_writer) * _generateContent($code_writer) * _generateTagContent($code_writer) Главное, не забудьте вызвать родительский _generateContent($code_writer), так как именно в нем передается управление дочерним элементам. Если вы создаете тег, у которого есть html-аналог, тогда скорее всего вам будет удобнее отнаследоваться от lmbMacroRuntimeWidgetHtmlTag или даже lmbMacroFormElementTag и перекрывать методы: * _generateBeforeOpeningTag($code_writer) * _generateAfterOpeningTag($code_writer) * _generateContent($code_writer) * _generateBeforeClosingTag($code_writer) * _generateAfterClosingTag($code_writer) В принципе, можно в последнем случае также перекрывать метод _generateContent($code_writer). ===== Метод preParse() ===== Этот метод используется для предварительного анализа атрибутов тега, родительских элементов и т.д. Этот метод вызывается в тот самый момент, когда компилятор находит соответствующий тег в MACRO-шаблоне. Обычно этот метод используется для установки каких-то обязательных атрибутов до момента их автоматических проверок на более поздних этапах. см. примеры: %%{{input}}%%, %%{{insert}}%% и нек. другие.