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% будет белый экран. |
- Написать текст введения.