K4:Вывод данных в шаблоне
From In-Portal Developers Guide
Revision as of 09:51, 4 February 2009
| This article is not finished yet! You see this message because current Article is finished yet or contains unverified information. How to write an Article. |
| ||
|---|---|---|
| Статьи в этой категории | ||
Contents |
Введение
Данная статья продолжает собой цикл статей, посвящённых синтаксическому анализатору шаблонов (template parser), использующемуся в платформе. Основной упор делается на описание работы с очень важными тэгами класса kDBTagProcessor:
- ProcessParsedTag
- ParseBlock
Описан метод prepareTagParams.
Есть раздел в котором представлена информация, посвященная ограничениям при работе с тэгами.
Важное замечание: все примеры предоставлены для самой новой версии парсера, под кодовым названием NParser. Данная версия парсера официально доступна начиная с Core v 4.3.9
Использование метода Application::ProcessParsedTag
Данный метод нужен для того, чтобы вызвать метод другого TagProcessora.
Параметры вызова метода
| параметр | описание |
|---|---|
prefix (string) | Префикс тэга, например "test".
|
tag (string) | тэг, т.е. название метода другого TagProcessora.
|
params (string) | массив параметров, которые можно передать. |
Пример применения метода ProcessParsedTag. Вызывается метод t префикса m c типичными для такого метода параметрами.
function LoginLink($params) { $params['t'] = 'login'; $params['pass'] = 'm'; $params['m_cat_id'] = 0; return $this->Application->ProcessParsedTag('m', 't', $params); }
Применение ProcessParsedTag позволяет вызывать методы, других не связанных с друг другом TagProcessor классов, что в повседневной работе дает еще
больше возможности для повторного применения уже написанного кода.
Использование Application::ParseBlock
Метод ParseBlock - это стандартный способ вывести в шаблон результат работы php функции.
Пример вызова метода Application::ParseBlock в классе CustonTagProcessor, который зарегистрирован с префиксом custom-section:
function PrintNumbers($params) { $o = ''; $block_params = $this->prepareTagParams($params); $block_params['name'] = $this->SelectParam($params, 'render_as,block'); for ($i = 1; $i <= 5 ; $i++ ) { $block_params['number'] = $i; $o.= $this->Application->ParseBlock($block_params); } return $o; }
Пример описание и вызова блока в шаблоне:
// Описание блока <inp2:m_DefineElement name="menu_block"> <inp2:m_Param name="number"/><br /> </inp2:m_DefineElement> // Вызов метода PrintNumbers <inp2:custom-section_PrintNumbers render_as="menu_block" /> // Результат работы метода PrintNumbers 1 2 3 4 5
Параметры метода Application::ParseBlock
| параметр | описание |
|---|---|
params (array) | Массив содержит параметры, которые передаются в блок. Обязательный параметер - это name, т.е. имя блок или шаблона. Можно
задавать сколько угодно много дополнительных параметров в этом массиве. |
pass_params (int) | По умолчанию равен 0, если установлено отличное от нуля значение, то метод передает параметры в блок. |
as_template (int) | По умолчанию равен false, если установлено значение true, то метод парсит не блок, а шаблон с таким именем. Если нет такого в папке с темой проекта, то будет выдано сообщение об ошибке в отладчике.
|
Метод prepareTagParams
Данный метод предназначен для упрощения задания параметров префикса и special в других тегах, главным образом для тех, которые для вывода данных используют метод Application::ParseBlock.
Метод prepareTagParams принимает в качестве параметра ассоциативный массив $params и добавляет в него значения префикса и special.
Результатом работы метода является ассоциативный массив вида:
Array( // другие параметры 'Prefix' => 'mytestprefix' 'Special' => '' 'PrefixSpecial' => 'mytestprefix' );
Пример функции PrintList, которая выводит список товаров заказа для префикса mytestprefix.
Хорошо видно как массив $params передаеться в метод prepareTagParams и результат работы записываются в другой массив $block_params, который в свою очередь уже передается в метод Application::ParseBlock
function PrintList($params) { $list =& $this->GetList($params); $list->Query(); $o = ''; $list->GoFirst(); $block_params = $this->prepareTagParams($params); $block_params['name'] = $this->SelectParam($params, 'render_as,block'); while (!$list->EOL()) { $o.= $this->Application->ParseBlock($block_params, 1); $list->GoNext(); } return $o; }
Пример задания блока my_test_row в шаблоне.
<inp2:m_DefineElement name="my_test_row"> <tr> <td><inp2:Field field="ProductName"/></td> <td><inp2:Field field="Quantity"/></td> <td><inp2:Field field="Price"/></td> </tr> </inp2:m_DefineElement>
Пример вызова блока my_test_row в шаблоне.
<inp2:mytestprefix_PrintList block="my_test_row"/>Можно иногда для тэга Field встретить такой вызов <inp2:{$PrefixSpecial}_Field field="ProductName"/>.
Это означает, что PrefixSpecial жестко передаеться для тэга Field. Сейчас такую конструкцию применять не нужно, т.к. есть метод prepareTagParams которые устанавливает эти параметры.
Ограничения на объявление блоков (чего точно не будет работать)
При объявление блока нужно следовать правилам.
- Нельзя объявить 2 блока с одинаковым именем и ждать, что будет использован первый объявленный. В таком случае будет использоваться второй блок.
// первое объявление блока <inp2:DefineElement name="my_test_block"> Hello World ! </inp2:DefineElement> // второе объявление блока <inp2:DefineElement name="my_test_block"> Hello Everyone ! </inp2:DefineElement>
При вызове на шаблоне блока my_test_block будет выведено
Hello Everyone !
- Если объявить блок внутри тэгa
m_ifили другого парного тэга, то результат будет непредсказуемым.
Пример тэга m_if для показа ошибки при логине.
<inp2:m_if check="u_HasError" field="ValidateLogin"> <inp2:m_DefineElement name="error_message"> Special error message </inp2:m_DefineElement> <inp2:u_Error field="ValidateLogin" /> </inp2:m_if> // Вызов блока <inp2:m_RenderElement name="error_message" />
При попадании на такую страницу, будет выведена ошибка отладчика
Fatal Error: Rendering of undefined element error_message
- При определение блока нужно применять только конструкцию
DefineElement. Раньше можно было также применятьblock .. blockend.
// правильный вариант <inp2:m_DefineElement name="valid_block"> Block body </inp2:m_DefineElement> // устаревший способ <inp2:m_block name="invalid_block"> Block body <inp2:m_blockend/>
При попадании на такую страницу, будет выведена ошибка отладчика
Fatal Error: Tag without a handler: m_block - probably missing <empty /> tag closing- Нужно быть внимательнее с знаком
/в написание блокаDefineElement. Если забыть закрывающий/как в примере
<inp2:m_DefineElement name="error_message"> Special error message <inp2:m_DefineElement>
При попадании на такую страницу, будет выведена ошибка отладчика
Fatal Error: Tag m_DefineElement called without required name attribute in w:\newsletter\themes\theme_newsletter\index.tpl on line 6
Заметки редактора
| текст | коррекция |
|---|---|
|
// правильный вариант <inp2:m_DefineElement name="valid_block" /> Block body </inp2:m_DefineElement> | В данном случае это как-раз неправильный вариант, т.к. стоит "/" в открывающем тэге и это приведёт к "Fatal Error" вместо желаемого результата. Рекомендуется все примеры проверить в жизни, т.е. создать "test.tpl" и в нём всё запустить и проверить, что работает. |
| Notice: Undefined property: TemplateName | Используя приведённый в статье пример у меня не получается повторить приведённую в статье ошибку. Мне кажется, что был использован TemplateParser вместо NParser (что было отдельно подчёркнуто для всех статей связанных с парсером). Все примеры и сообщения об ошибках нужно выводить используя проект где включён NParser или любой проект начиная с Core v 4.3.9 версии. |
| TagProcessora | Данное слово нужно заменить на "обработчика тэгов". |
|
$o = $this->Application->ParseBlock( Array('name' => $params['render_as'], 'number' => $i) ); | В данном примере массив определяется прямо при вызове метода. Это расходиться с правилами вызова методов. Нужно чтобы массив и его неизменяемые параметры были определены до начала цикла, а изменяемые параметры подставлялись уже в цикле. |
| выдано сообщение об ошибке в дебаггере. | Вместо слово "дебаггере" нужно использовать слово "отладчике" и сделать его ссылкой на статью об отладчике. |
| 'Prefix' => 'orditems' | Вместо префикса "orditems" рекомендуется использовать более абстрактный префикс. |
| <inp2:m_DefineElement name="order_detail_row"> | Названия блоков, да и вообще названия рекомендуется делать более абстрактными, а не использовать названия из других проектов. |
| <td align="left" width="100%"><inp2:{$PrefixSpecial}_Field field="ProductName"/></td> | Этот фрагмент примера из главы про метод prepareTagParams. В данном примере можно не писать "{$PrefixSpecial}_" вообще. Также необходимо написать почему. |
| <inp2:orditems_PrintList block="order_detail_row" per_page="-1" requery="1"/> | Параметры per_page и requery никак к теме статьи не относятся и поэтому их использовать не следует. |
| Нельзя объявить блок внутри тэгa m_if или другого парного тэга. | Объявить-то можно, но результат будет непредсказуемым. |
| <inp2:m_ParseBlock name="error_message" /> | Тэг ParseBlock является устаревшим и просто не будет рабоатать с NParser. В примерах его следует заменить на RenderElement. |
| и дальше будет виден только "белый" экран. | Думаю нужно где-то в начале статьи оговорить, что при возникновении "Fatal Error" и выключенном отладчике получается белый экран, но не писать так, что после какой-то из операций 100% будет белый экран. |
- Написать текст введения.
