In-Portal Developers Guide

This is a wiki-based Developers Guide for In-Portal Open Source CMS. The purpose of this guide is to provide advanced users, web developers and programmers with documentation on how to expand, customize and improve the functionality and the code the In-Portal software. Please consider contributing to our documentation writing effort.

K4:Базовые сведения о тэгах и шаблонах

From In-Portal Developers Guide

Jump to: navigation, search
m (1 версия)
Current revision (22:11, 13 March 2009) (view source)
 
(10 intermediate revisions not shown.)
Line 1: Line 1:
{{toc | category = Работа с шаблонами | sortkey = 001.001}}
{{toc | category = Работа с шаблонами | sortkey = 001.001}}
<!-- Пишите ПОСЛЕ этой строки, пожалуйста. Ничего не стирать! -->
<!-- Пишите ПОСЛЕ этой строки, пожалуйста. Ничего не стирать! -->
-
Данная статья открывает собой цикл статей, посвящённых синтаксическому анализатору шаблонов (<code>template parser</code>), использующемуся в платформе.
 
-
Синтаксический анализатор применяется для разбора шаблонов (файлов, имеющих расширение "'''<code>.tpl</code>'''") и их последующего преобразования в HTML-формат. При этом используется один главный файл PHP-файл ("<code>index.php</code>" на пользовательской части сайта или "<code>admin/index.php</code>" в административной консоли), через который ведётся обработка всех тэгов в шаблонах и пользователю в браузер выдаётся итоговый HTML-документ.  
+
This is an introductory article in a series of articles describing the In-Portal CMS template parser.
 +
 
 +
The template parser parses templates (files with the "'''<code>.tpl</code>'''" file extension) and renders them in HTML. For this the system uses one main PHP file ("<code>index.php</code>" on the front end website and "<code>admin/index.php</code>" in the administrative console), through which all tags are processed, to output HTML to the browser.
 +
 
{{InfoBox|
{{InfoBox|
-
* Шаблоны, в свою очередь, используются для разделения бизнес-логики от визуального оформления сайта.
+
* Templates are used for separating business logic from the visual design of the site. You will not find any files in In-Portal CMS containing PHP and HTML together!
-
* Тэги, которые используются в синтаксическом анализаторе ни в коем случае не являются дополнительным языком программирования, т.к. для этого существует <code>PHP</code>.}}
+
* Although the tags used by the template parser contain a lot of functionality, they are by no means to be considered an additional programming language, because for that we have <code>PHP</code>!}}
-
Синтаксический анализатор обрабатывает только  [http://www.w3schools.com/xml/xml_dtd.asp '''правильно сформированные'''] (<code>well formed</code>) <code>XML</code> тэги из пространства имён '''<code>inp2</code>'''. Далее в этой статье будут рассмотрены базовые вопросы, связанные с тэгами и шаблонами, а именно:
+
-
* процесс создание нового тэга с нуля;
+
-
* параметры тегов и шаблонов;
+
-
* область действия параметров;
+
-
* примеры и ограничения при работе с тэгами и шаблонами.
+
-
== Добавление нового тэга ==
+
The template parser processes only [http://www.w3schools.com/xml/xml_dtd.asp '''<code>well formed</code>'''] <code>XML</code> tags with the namespace '''<code>inp2</code>'''. This article will discuss the basics of templates and tags, specifically:
-
Добавление тэга можно разбить на следующие основные этапы:
+
* Creating a tag from the start;
-
* принятие решения о расположении тела тэга в классовой структуре обработчиков тэгов проекта;
+
* Tag and template parameters;
-
* создание нового класса, который будет содержать тело тэга (только, если требуется);
+
* Parameter scope;
-
* регистрация нового класса в фабрике классов (только, если на предыдущем этапе создавался класс);
+
* Examples and restrictions/limitations of working with tags and templates.
-
* написание тела тэга в выбранном или созданном на предыдущем этапе обработчике тэгов.
+
-
Далее в статье будут описан каждый из выше упомянутых этапов создания тэга.
 
-
=== Расположение тэга ===
+
== Adding a New Tag ==
-
В общем случае создаваемый тэг должен быть расположен в том [[TagProcessor:About|обработчике тэгов]], с данными [[K4:Unit Configs#Prefix|префикс]]а которого он работает. Например если есть таблица "<code>int_Tests</code>" связанная с префиксом "<code>test</code>", то тэг, работающей с данной таблицей должен находиться в обработчике тэгов (напр. "<code>TestTagProcessor</code>"), который связан с данным префиксом "<code>test</code>".
+
Adding a tag can be broken down into the following steps:
 +
* Deciding on the location of the body of the tag in the class structure of the project's tag processors;
 +
* Creating a new class, that's going to contain the body of the tag (if necessary);
 +
* Registering the new tag in factory.php class (only if a class was created in the previous step);
 +
* Writing the body of the tag in the chosen or created tag processor.
-
=== Создание обработчика тэгов ===
+
Following we'll discuss the details of each of the above stages of creating a tag.
-
Создание обработчика тэгов начинается с создания [[K4:Назначение имён#Файлы|файла]], который в последствии будет содержать класс [[TagProcessor:About|обработчика тэгов]]. Согласно [[K4:Назначение имён#Файлы|правилам]] наименования файлов, содержащих классы, его название формируется путём замены всех дефисов в названии [[K4:Unit Configs#Prefix|префикс]]а на подчёркивания и добавления текста "<code>_tp.php</code>" в конец получившейся после этого строки. Для [[K4:Unit Configs#Prefix|префикс]]а "<code>sample-prefix</code>" название файла обработчика тэгов будет равно "<code>sample_prefix_tp.php</code>". Файл обработчика тэгов должен располагаться в директории, содержащей [[K4:Unit Configs|конфигурационный файл]], в котором происходит его регистрация в фабрике классов. Для префикса "<code>sample-prefix</code>" это будет директория "<code>custom/units/sample_prefix</code>".
+
 +
=== Tag Placement ===
 +
In most cases, a new tag should be placed in the [[TagProcessor:About|tag processor]], with the [[K4:Unit Configs#Prefix|prefix]] that it's using. For example, if there's an "<code>int_Tests</code>" table for the "<code>test</code>" prefix, then the tag that's using this table would be located in the tag processor (e.g. "<code>TestTagProcessor</code>"), that's tied to the "<code>test</code>" prefix.
-
Далее в созданном ранее файле требуется определить класс обработчика тэгов. [[K4:Назначение имён#Классы|Название класса]] обработчика тэгов формируется из [[K4:Unit Configs#Prefix|префикс]]а по следующей схеме:  
+
=== Creating a Tag Processor ===
-
* первая буква каждого слова в [[K4:Unit Configs#Prefix|префикс]]е делается заглавной;
+
Creating a tag processor starts with creating the [[K4:Назначение имён#Файлы|file]], which will contain the tag processor class. The [[K4:Назначение имён#Файлы|naming convention]] for files that contain classes is as follows, the filename is formed by replacing all dashes in the [[K4:Unit Configs#Prefix|prefix]] with an underscore followed by <code>tp.php</code>, e.g. "<code>sample_prefix_tp.php</code>". The tag processor file must be in the same directory that contains the [[K4:Unit Configs|unit config]], which indicates where it's registered in the class factory. For example, for the prefix "<code>sample-prefix</code>", the directory would be "<code>custom/units/sample_prefix</code>".
-
* убираются дефисы;
+
 
-
* к результирующей строке добавляется текст "<code>TagProcessor</code>".
+
Furthermore, in the above created file, it's required to define the tag processor class. The [[K4:Назначение имён#Классы|Class name]] for the tag processor is formed based on the [[K4:Unit Configs#Prefix|prefix]] as follows:
-
Например, если префикс называется "<code>sample-prefix</code>", то класс его [[TagProcessor:About|обработчика тэгов]] будет называться "<code>SamplePrefixTagProcessor</code>". Данный класс в свою очередь должен быть наследником класса "<code>kDBTagProcessor</code>":
+
* the first letter of each word in the [[K4:Unit Configs#Prefix|prefix]] is capitalized;
 +
* all dashes are removed;
 +
* "<code>TagProcessor</code>" is added to the resulting line.
 +
For example, if the prefix is "<code>sample-prefix</code>", then the class of its [[TagProcessor:About|tag processor]] is going to be called  "<code>SamplePrefixTagProcessor</code>". This class must be the child of the class "<code>kDBTagProcessor</code>":
<source lang="php">
<source lang="php">
Line 41: Line 44:
</source>
</source>
-
 
+
The final step in creating new tag processors is registering in the class factory. The tag processor class is [[K4:Регистрация классов|registered]] using the key [[K4:Unit Configs#TagProcessorClass|TagProcessorClass]] in the [[K4:Unit Configs|config file]] for the prefix to which it will be connected. In the present example, that prefix is "<code>sample-prefix</code>". To register the tag processor, we must specify the name of the tag processor class and the file where its declared. This is illustrated in the below example.
-
Завершающим этапом в создании нового обработчика тэгов является его регистрация в фабрике классов. Класс обработчика тэгов [[K4:Регистрация классов|регистрируется]] при помощи ключа [[K4:Unit Configs#TagProcessorClass|TagProcessorClass]] в [[K4:Unit Configs|конфигурационном файле]] того префикса, с которым он будет связан. В данном примере это префикс "<code>sample-prefix</code>". Для регистрации требуется указать название класса обработчика тэгов и файл, в котором этот класс объявлен. Это будет наглядно показано на ниже приведённом примере.
+
<source lang="php">
<source lang="php">
Line 50: Line 52:
);
);
</source>
</source>
-
Не описанный ранее ключ "<code>build_event</code>" используется для задания [[EventHandler:About|события]], которое будет инициализировать объект. Для классов обработчиков тэгов это всегда событие [[EventHandler:OnBuild|OnBuild]].
 
-
{{InfoBox|Названия всех классов, зарегистрированных в фабрике классов находятся в [[K4:Cache|кеше]] и поэтому требуется его перестроить прежде, чем сделанные изменения вступят в силу.}}
+
The key that wasn't described above is called "<code>build_event</code>", that is used for the [[EventHandler:About|event]] task, which will initialize the object. For tag processor classes, this will always be the event [[EventHandler:OnBuild|OnBuild]].
-
=== Добавление тэга в обработчик тэгов ===
+
{{InfoBox|All class names, registered in the class factory are [[K4:Cache|cached]] so we must reset cache before changes will take effect.}}
-
После того, как успешно создан или найден класс [[TagProcessor:About|обработчика тэгов]], можно приступать к созданию метода, результат работы которого и будет выведен на странице, как результат работы нового тэга. Сам метод будет располагаться в классе обработчика тэгов. Согласно [[K4:Назначение имён#Функции и методы|правилу именования тэгов]] каждое слово в названии метода должно начинаться с большой буквы. Также название данного метода может содержать только латинские буквы и цифры. Цифры желательно не использовать.  
+
-
Синтаксический анализатор (<code>template parser</code>) при вызове метода, связанного с найденным им в шаблоне тэгом также будет передать ассоциативный массив параметров, переданных в сам тэг в качестве первого аргумента метода. Это будет наглядно показано на приведённом ниже примере:
+
=== Adding a Tag to the Tag Processor ===
 +
 
 +
After successfully creating or finding the class of the [[TagProcessor:About|tag processor]], we can start writing the method whose output will be displayed on the page as a result of the new tag. The method itself will be located in the class of the tag processor. Following [[K4:Назначение имён#Функции и методы|tag naming conventions]], each word in the method name must start with a capital letter. Also, each method's name may contain only Latin letters and numbers, although it's preferred that numbers aren't used.
 +
 
 +
The (<code>template parser</code>) upon calling the method indicated in the tag in the template will also pass an associative array of parameters, passed to the tag itself as the first argument of the method. This is illustrated in the following example:
<source lang="php">
<source lang="php">
Line 75: Line 79:
</source>
</source>
-
На шаблоне вызов тэга выглядит следующим образом:
+
In the template, the tag call looks like this:
<source lang="xml">  
<source lang="xml">  
<inp2:sample-prefix_PrintHelloWorld />
<inp2:sample-prefix_PrintHelloWorld />
Line 81: Line 85:
{| class="prettytable"
{| class="prettytable"
-
! текст || описание
+
! Text|| Description
|-
|-
-
| '''<code>inp2</code>''' || Пространство имён тэгов, которое синтаксический анализатор (<code>template parser</code>) обрабатывает.
+
| '''<code>inp2</code>''' || Namespace tag that the <code>template parser</code> processes.
|-
|-
-
| '''<code>sample-prefix</code>''' || Название префикса тега.  
+
| '''<code>sample-prefix</code>''' || Name of tag's prefix.
|}
|}
-
== Парные и непарные тэги ==
+
== Paired and Unpaired Tags ==
-
Все, обрабатываемые синтаксическим анализатором (<code>template parser</code>) тэги делятся на парные и непарные. Парные тэги от непарных отличаются тем, что они могут использовать заключённое в них содержание по своему усмотрению. Все, объявленные в классах обработчиков тэгов тэги непарные. В свою очередь все парные тэги системные и не подлежат переопределению. В общем виде парные и непарные тэги выглядят так:
+
 
 +
All tags processed by the template parser are either tag pairs (opening and closing tag) or solo tags (self-closing). Paired tags differ from self-closing tags in that paired tags can use the code/text within them at their discretion. All tags declared in tag processor classes are self-closing tags. All paired tags are system tags and cannot be changed/overwritten. In general, paired and non-paired tags look like this:
<source lang="xml">
<source lang="xml">
-
непарный тэг:
+
non-paired/self-closing tag:
<inp2:prefix.special_TagName param1="value1" param2="value2"/>
<inp2:prefix.special_TagName param1="value1" param2="value2"/>
-
парный тэг:
+
paired tag:
<inp2:prefix_TagName param1="value1" param2="value2">
<inp2:prefix_TagName param1="value1" param2="value2">
-
содержание тэга
+
text contained in tag
</inp2:prefix_TagName>
</inp2:prefix_TagName>
</source>
</source>
-
{{TipBox|Для разделения параметров тэга и его самого допускается использование любого количества разделительных символов (<code>whitespace</code>).}}
+
{{TipBox|To separate tag parameters from the tag any number of <code>whitespace</code> characters can be used.}}
-
Ниже приведены примеры использования нескольких популярных тэгов.
+
Below are examples and explanations of a couple common tags.
-
* Непарные тэги:
+
* Unpaired tags::
<source lang="xml">
<source lang="xml">
-
а) <inp2:m_TemplatesBase module="Custom"/> - путь к папке с файлами темы модуля Custom.
+
а) <inp2:m_TemplatesBase module="Custom"/> - path to the directory containing the theme files for the module Custom.
-
б) <inp2:m_GetConfig var="Site_Name"/> - переменная конфигурации Site_Name.
+
б) <inp2:m_GetConfig var="Site_Name"/> - config variable Site_Name.
-
с) <inp2:st_PageInfo type="meta_title"/> - название текущей страницы.
+
с) <inp2:st_PageInfo type="meta_title"/> - page title.
</source>
</source>
-
* Парные тэги:
+
* Paired tags:
<source lang="xml">
<source lang="xml">
-
а) Тэг условия.
+
а) Tag conditions.
<inp2:m_if check="m_Param" name="is_last">
<inp2:m_if check="m_Param" name="is_last">
...
...
</inp2:m_if>
</inp2:m_if>
-
б) Тэг определения блочного элемента в шаблоне.
+
б) Tag defining a block element in a template.
<inp2:m_DefineElement name="menu_block">
<inp2:m_DefineElement name="menu_block">
<td><inp2:m_Phrase name="lu_about_us"/></td>
<td><inp2:m_Phrase name="lu_about_us"/></td>
Line 127: Line 132:
</source>
</source>
-
== Общая форма вызова тэга из шаблона ==
+
== General Form for Calling a Tag in a Template ==
-
В общем виде форма вызова тэга на шаблоне имеет вид:
+
The general form for calling a tag in a template looks as follows:
<source lang="xml">
<source lang="xml">
Line 135: Line 140:
{| class="prettytable"
{| class="prettytable"
-
! параметр || описание
+
! parameter|| description
|-
|-
-
| {{ConfigProperty|prefix|string}} || [[K4:Unit Configs#Prefix|Префикс]] тэга, например "<code>test</code>".
+
| {{ConfigProperty|prefix|string}} || Tag [[K4:Unit Configs#Prefix|Prefix]], for example, "<code>test</code>".
|-
|-
-
| {{ConfigProperty|special|string}} || <code>Special</code> тэга, например "<code>front</code>". Если указан, то отделяется от префикса при помощи символа точки ("<code>.</code>").
+
| {{ConfigProperty|special|string}} || Tag <code>Special</code>, for example, "<code>front</code>". If used, then separated from the prefix using a period ("<code>.</code>").
|-
|-
-
| {{ConfigProperty|TagName|string}} || Название тэга, например "<code>PrintHelloWorld</code>". Если тэг нигде не определён, то синтаксический анализатор (<code>template parser</code>) расценит это как критичную ошибку (<code>fatal error</code>) и прекратит выполнение всех последующих тэгов на текущем шаблоне.
+
| {{ConfigProperty|TagName|string}} || The name of the tag, for example, "<code>PrintHelloWorld</code>". If the tag is not defined anywhere, then the <code>template parser</code> will output a (<code>fatal error</code>) and will stop processing the rest of the tags in the current template.
|-
|-
-
| '''<code>param1="value1"</code>''' || Пара параметр и его значение, которые можно передать в тэг. В тэг может передаваться неограниченное количество параметров. Названия параметров должны быть уникальными в пределах одного тэга, а также должны состоять только из латинских букв и цифр.
+
| '''<code>param1="value1"</code>''' || Parameter pair and its value, that can be passed to a tag. An unlimited amount of parameters can be passed to a tag. A parameter name must be unique within a single tag and be made up of only Latin letters and numbers.
|-
|-
| '''<code>other_param='value2'</code>'''
| '''<code>other_param='value2'</code>'''
-
| Также является допустимой формой задания значения параметра в тэге. Рекомендуется использовать тогда, когда сам тэг применяется в качестве значения атрибута HTML-тэга. В таком случае не будет нарушена подсветка синтаксиса в шаблоне (если используется редактор шаблонов с подсветкой синтаксиса). Это будет показано на ниже приведённом примере.
+
| It's also valid to assign the parameter value inside another tag. This is useful when the tag itself is being used as the attribute in an HTML tag because it won't mess up syntax highlighting in a template (if an editor with syntax highlighting is being used). This is demonstrated in the below example.
<source lang="html4strict">
<source lang="html4strict">
<img src="<inp2:m_TemplatesBase module='custom'/>img/spacer.gif" alt=""/>
<img src="<inp2:m_TemplatesBase module='custom'/>img/spacer.gif" alt=""/>
Line 152: Line 157:
|}
|}
-
Пример вызова тэга на шаблоне:
+
Example of calling a tag in a template:
<source lang="xml">
<source lang="xml">
Line 158: Line 163:
</source>
</source>
-
Пример функции в классе <code>TestTagProcessor</code>
+
Example of a function the class <code>TestTagProcessor</code>
<source lang="php">
<source lang="php">
Line 169: Line 174:
function PrintHelloWorld($params)
function PrintHelloWorld($params)
{
{
-
// проверка на special
+
// check for special
$ret = $this->Special == 'front' ? 'Hello World Front !' : 'Hello World !';
$ret = $this->Special == 'front' ? 'Hello World Front !' : 'Hello World !';
-
// проверка установлен ли параметр 'current_datetime'
+
// check whether parameter 'current_datetime' is set
if (array_key_exists('current_datetime', $params) && ($params['current_datetime'] == 'yes')) {
if (array_key_exists('current_datetime', $params) && ($params['current_datetime'] == 'yes')) {
$ret .= ' ' . adodb_date('m/d/Y H:s');
$ret .= ' ' . adodb_date('m/d/Y H:s');
Line 181: Line 186:
</source>
</source>
-
== Задание параметров по умолчанию ==
+
== Setting Default Parameters ==
-
Параметры по умолчанию позволяют задать значения параметров для парных (блочных) тэгов и для шаблонов на тот случай, если эти тэги или шаблоны будут использоваться без передачи в них всех, используемых в них параметров.
+
Default parameters allow assigning parameter values for paired (block) tags and for templates for the case where the given tags or templates will be used without passing to them all the parameters that they use.
-
=== Параметры шаблона по умолчанию ===
+
=== Default Template Parameters ===
-
Параметры шаблона по умолчанию задаются вверху шаблона при помощи тэг [[TagProcessor:m_DefaultParam|m_DefaultParam]]. Если в теле такого шаблона будет использоваться такой параметр, но его значение не будет передано при вызове шаблона, то будет использовано значение по умолчанию. Это будет показано на ниже приведённом примере.
+
Default template parameters are set at the top of the template using the tag [[TagProcessor:m_DefaultParam|m_DefaultParam]]. If a parameter is going to be used in the body of a tag, but it's value isn't passed when the template is called, then it's default parameter will be used. This is demonstrated on the below example.
<source lang="xml">
<source lang="xml">
=== include_test.tpl ===
=== include_test.tpl ===
Line 193: Line 198:
=== index.tpl ===
=== index.tpl ===
-
// выведет PARAM: [default_value2]
+
// will output PARAM: [default_value2]
<inp2:m_include template="include_test"/>
<inp2:m_include template="include_test"/>
-
// выведет PARAM: [given_value]
+
// will output PARAM: [given_value]
<inp2:m_include template="include_test" param2="given_value"/>
<inp2:m_include template="include_test" param2="given_value"/>
</source>
</source>
-
=== Параметры парного тэга по умолчанию ===
+
=== Default Paired Tag Paramaters ===
-
Параметры по умолчанию для парных тэгов задаются при их определении. Это будет показано на ниже приведённом примере.
+
Default parameters for paired tags tags are specified in their definition. This is demonstrate on the below example.
<source lang="xml">
<source lang="xml">
-
<!-- определение блока -->
+
<!-- block definition -->
<inp2:m_DefineElement name="sample_element" as_label="" currency="USD">
<inp2:m_DefineElement name="sample_element" as_label="" currency="USD">
[<inp2:m_Param name="as_label"/> - <inp2:m_Param name="currency"/>]
[<inp2:m_Param name="as_label"/> - <inp2:m_Param name="currency"/>]
</inp2:m_DefineElement>
</inp2:m_DefineElement>
-
<!-- использование блока передавая ему параметры -->
+
<!-- using the block and passing it parameters -->
<inp2:m_RenderElement name="sample_element" as_label="1"/> // даст [1 - USD]
<inp2:m_RenderElement name="sample_element" as_label="1"/> // даст [1 - USD]
-
<!-- использование блока не передавая ему параметры -->
+
<!-- using the block without passing it parameters -->
<inp2:m_RenderElement name="sample_element"/> // даст [ - USD]
<inp2:m_RenderElement name="sample_element"/> // даст [ - USD]
</source>
</source>
-
== Расположение шаблонов ==
+
== Location of Templates ==
-
Все шаблоны делятся на 2 группы по месту их применения:
+
All templates are divided into 2 groups based on where they are used:
-
* административная консоль;
+
* administrative console;
-
* пользовательская часть сайта.
+
* front end site.
-
Далее будут описаны особенности расположения и использования шаблонов из обеих выше упомянутых групп.
+
Below will be described the specifics concerning location and purpose of templates from both of the above groups.
-
=== Шаблоны в административной консоли ===
+
=== Administrative Console Templates ===
-
В административной консоли все шаблоны разделены по [[K4:Modules|модулям]]. В каждом модуле в свою очередь есть директория "'''<code>admin_templates</code>'''", в которой содержатся все его шаблоны. Например если модуль называется "<code>proj-base</code>", то его шаблоны буду лежать в директории "<code>proj-base/admin_templates</code>". Под директорией "<code>admin_templates</code>" допускается создание других директорий для логической группировки шаблонов в пределах одного модуля. При использовании шаблона всегда следует писать название модуля перед названием шаблона, напр. "<code>proj-base/users/users_list</code>", а не просто "<code>users/users_list</code>". Если требуется подключить (<code>include</code>) оригинальную версию шаблона (если шаблон был подменён через [[K4:Unit Configs#ReplacementTemplates|ReplacementTemplates]]) то нужно написать "<code>orginal:</code>" перед названием шаблона, напр. "<code>original:path/to/replaced/template</code>".
+
All administrative console templates are divided by [[K4:Modules|modules]]. Following, each module has its own "'''<code>admin_templates</code>'''" directory, which contains all of its admin templates. For example, if the module is called "<code>proj-base</code>", then its admin templates will be in the "<code>proj-base/admin_templates</code>" directory. Under the "<code>admin_templates</code>" directory, it's allowed to create other directories to logically group templates within a single module. When using a template, one must always write the module name preceding the template name, for example "<code>proj-base/users/users_list</code>", instead of simply "<code>users/users_list</code>". If one has to <code>include</code> the original version of a template (if the template was changed through [[K4:Unit Configs#ReplacementTemplates|ReplacementTemplates]]) then one must write "<code>orginal:</code>" before the template name, for example "<code>original:path/to/replaced/template</code>".
-
{{TipBox|Название модуля писать не обязательно только для шаблонов из директории "<code>core/admin_templates</code>".}}
+
{{TipBox|Writing the module name is not required for templates in the "<code>core/admin_templates</code>" directory.}}
-
{{InfoBox|В проектах разрешается создавать и изменять только шаблоны административной консоли, находящиеся в папке "<code>custom/admin_templates</code>", т.е. принадлежащие модулю "<code>custom</code>".}}
+
{{InfoBox|For projects, creating and changing administrative console templates is only allowed for templates in the "<code>custom/admin_templates</code>" folder, i.e. belonging to the module "<code>custom</code>".}}
-
=== Шаблоны на пользовательской части сайта ===
+
=== Front-end Templates ===
-
На пользовательской части сайта все шаблоны разделены по [[K4:Theme|темам]] (<code>styles</code>). Для каждой [[K4:Theme|темы]] существует директория вида "<code>themes/<theme_name></code>", где "<code><theme_name></code>" это значение поля [[K4:Theme#Name|Name]] конкретной темы. Все темы задаются в [[K4:Добавление секций в дереве|секции]] "<code>Configuration -> Themes</code>". Обычно достаточно создать папку с темой и шаблоны в ней и нажать кнопку "<code>Rebuild Theme Files</code>" на панели инструментов в списке тем для того, чтобы запись в таблице [[K4:Theme|Theme]] создалась автоматически. Например, если путь к шаблону относительно корневой директории проекта "<code>themes/theme_test/testing/sample_template.tpl</code>", то для использования этого шаблона нужно указывать "<code>testing/sample_template</code>". При этом шаблон будет искаться в той [[K4:Theme|теме]] сайта, которая указана в ссылке на сайт.
+
Front-end templates are divided by [[K4:Theme|theme]](<code>styles</code>). There's a directory for each [[K4:Theme|theme]] such as "<code>themes/<theme_name></code>", where "<code><theme_name></code>" is the [[K4:Theme#Name|Name]] field of the actual template. All templates are defined in the "<code>Configuration -> Themes</code>" [[K4:Добавление секций в дереве|section]]. Usually, creating a theme folder with templates inside of it and pressing the "<code>Rebuild Theme Files</code>" button in the themes toolbar is enough for an entry to be automatically created in the [[K4:Theme|Theme]] table. For example, if the path to the template relative to the project's root directory is "<code>themes/theme_test/testing/sample_template.tpl</code>", then to use the template one can write "<code>testing/sample_template</code>". The template will then look in the [[K4:Theme|theme]] that's indicated in the site URL.
-
{{TipBox|В проектах на платформе обычно используется только одна тема, с названием "<code>theme_<project_name></code>", напр. "<code>theme_fuse</code>".}}
+
{{TipBox|In projects, there's usually only one theme, named "<code>theme_<project_name></code>", for example "<code>theme_estore</code>".}}
-
== Область действия параметров ==
+
== Parameter Scope ==
-
По умолчанию параметры переданные в блок или шаблон будут видны только в нём самом. Если требуется, передать '''значение индивидуального параметра''' в следующий блок или шаблон, то это можно сделать при помощи следующей конструкции <code>'''param_name="$param_name"'''</code>. Если требуется передать '''все параметры''' из шаблона или блока в следующий шаблон, то это можно сделать указав параметр "'''<code>pass_params</code>'''". Все выше описанные варианты будут показаны на ниже приведённом примере.
+
By default, parameters passed to a block or template will only be visible in the block or template itself. If the situation calls for passing the '''value of an individual parameter''' to another block or template, then that can be done with the following code: <code>'''param_name="$param_name"'''</code>. If passing '''all parameter values''' from one template or block to another is what's needed, then one needs to set the parameter "'''<code>pass_params</code>'''". All above described variations will be demonstrated in the below example.
<source lang="xml">
<source lang="xml">
== main.tpl ==
== main.tpl ==
-
<inp2:m_DefaultParam main_param="sample_value" main_param2="test"/> <!-- Установка значения по умолчанию для параметров "main_param" и "main_param2". -->
+
<inp2:m_DefaultParam main_param="sample_value" main_param2="test"/> <!-- Setting default values for the "main_param" and "main_param2" parameters. -->
<inp2:m_DefineElement name="sample_element">
<inp2:m_DefineElement name="sample_element">
Line 244: Line 249:
</inp2:m_DefineElement>
</inp2:m_DefineElement>
-
<!-- Значение всех параметров из этого шаблона не будут доступны в подключаемом шаблоне и используемом блоке. -->
+
<!-- The values of all parameters from this block will not be accessible in the included template and rendered block. -->
<inp2:m_include template="include_test"/>
<inp2:m_include template="include_test"/>
<inp2:m_RenderElement name="sample_element"/>
<inp2:m_RenderElement name="sample_element"/>
-
<!-- Только значение параметра "main_param" будет доступно в подключаемом шаблоне и используемом блоке. -->
+
<!-- Only the value of "main_param" will be accessible in the included template and rendered block. -->
<inp2:m_include template="include_test" main_param="$main_param"/>
<inp2:m_include template="include_test" main_param="$main_param"/>
<inp2:m_RenderElement name="sample_element" main_param="$main_param"/>
<inp2:m_RenderElement name="sample_element" main_param="$main_param"/>
-
<!-- Только значение параметра "main_param2", но под именем "main_param" будет доступно в подключаемом шаблоне и используемом блоке. -->
+
<!-- Only the value of "main_param2", by the name of "main_param" will be accessible by the included template and rendered block. -->
<inp2:m_include template="include_test" main_param="$main_param2"/>
<inp2:m_include template="include_test" main_param="$main_param2"/>
<inp2:m_RenderElement name="sample_element" main_param="$main_param2"/>
<inp2:m_RenderElement name="sample_element" main_param="$main_param2"/>
-
<!-- Значения всех параметров этого шаблона будут доступны в подключаемом шаблоне и используемом блоке. -->
+
<!-- All parameter values from this template will be accessible in the included template and rendered block. -->
<inp2:m_include template="include_test" pass_params="true"/>
<inp2:m_include template="include_test" pass_params="true"/>
<inp2:m_RenderElement name="sample_element" pass_params="true"/>
<inp2:m_RenderElement name="sample_element" pass_params="true"/>
Line 265: Line 270:
</source>
</source>
-
== Назначения имён параметрам ==
+
== Parameter Naming Conventions ==
-
Название параметра тэга, в котором передаётся название блока должно называться "'''<code>render_as</code>'''". В случае, когда в тэг передаётся несколько названий блоков, то названия параметров, в которых передаются названия блоков должны заканчиваться на "'''<code>_render_as</code>'''", напр. "<code>user_render_as</code>". Это будет показано на ниже приведённом примере.
+
The name of the tag parameter, which passes the name of the block must be called "'''<code>render_as</code>'''". In the case where several block names are passed to the tag, the parameter names, which pass the block names must start with  "'''<code>_render_as</code>'''", for example "<code>user_render_as</code>". This is shown in the below example.
<source lang="xml">
<source lang="xml">
Line 272: Line 277:
</source>
</source>
-
Параметры, используемые на шаблоне при его компиляции превращаются в <code>PHP</code>-переменные и поэтому их название должно соответствовать тем же правилам, что и остальные наименования в PHP. Правильное название параметра должно начинаться с буквы или символа подчёркивания с последующими в любом количестве буквами, цифрами или символами подчёркивания.
+
Parameters used in the template are changed into <code>PHP</code>-variables when the template is compiled, because of this their names must follow the same rules that apply to PHP variables. A correct parameter name must start with a letter or underscore, followed by any number of letters, numbers, and/or underscores.
-
== Значение параметров по умолчанию ==
+
== Parameter Default Values ==
-
Если не задавать значения по умолчанию для необязательных параметров шаблона или блока, то при их (шаблона или блока) использовании будут выдаваться <code>php warnings</code>, что есть не очень хорошо. Для нахождения мест в шаблоне, где не заданы значения параметров по умолчанию лучше всего подходит [[K4:Debugger|отладчик]].
+
If parameter default values are not set for optional parameters in the template or block, then <code>PHP warnings</code> will be generated when the template or block is used, which is not desirable. To find places in a template where default values for parameters aren't set, the best thing to use is the [[K4:Debugger|debugger]].

Current revision

Работа с шаблонами Работа с шаблонами
Статьи в этой категории

This is an introductory article in a series of articles describing the In-Portal CMS template parser.

The template parser parses templates (files with the ".tpl" file extension) and renders them in HTML. For this the system uses one main PHP file ("index.php" on the front end website and "admin/index.php" in the administrative console), through which all tags are processed, to output HTML to the browser.

Image:Infobox Icon.gif
  • Templates are used for separating business logic from the visual design of the site. You will not find any files in In-Portal CMS containing PHP and HTML together!
  • Although the tags used by the template parser contain a lot of functionality, they are by no means to be considered an additional programming language, because for that we have PHP!

The template parser processes only well formed XML tags with the namespace inp2. This article will discuss the basics of templates and tags, specifically:

  • Creating a tag from the start;
  • Tag and template parameters;
  • Parameter scope;
  • Examples and restrictions/limitations of working with tags and templates.


Contents

Adding a New Tag

Adding a tag can be broken down into the following steps:

  • Deciding on the location of the body of the tag in the class structure of the project's tag processors;
  • Creating a new class, that's going to contain the body of the tag (if necessary);
  • Registering the new tag in factory.php class (only if a class was created in the previous step);
  • Writing the body of the tag in the chosen or created tag processor.

Following we'll discuss the details of each of the above stages of creating a tag.

Tag Placement

In most cases, a new tag should be placed in the tag processor, with the prefix that it's using. For example, if there's an "int_Tests" table for the "test" prefix, then the tag that's using this table would be located in the tag processor (e.g. "TestTagProcessor"), that's tied to the "test" prefix.

Creating a Tag Processor

Creating a tag processor starts with creating the file, which will contain the tag processor class. The naming convention for files that contain classes is as follows, the filename is formed by replacing all dashes in the prefix with an underscore followed by tp.php, e.g. "sample_prefix_tp.php". The tag processor file must be in the same directory that contains the unit config, which indicates where it's registered in the class factory. For example, for the prefix "sample-prefix", the directory would be "custom/units/sample_prefix".

Furthermore, in the above created file, it's required to define the tag processor class. The Class name for the tag processor is formed based on the prefix as follows:

  • the first letter of each word in the prefix is capitalized;
  • all dashes are removed;
  • "TagProcessor" is added to the resulting line.

For example, if the prefix is "sample-prefix", then the class of its tag processor is going to be called "SamplePrefixTagProcessor". This class must be the child of the class "kDBTagProcessor":

class SamplePrefixTagProcessor extends kDBTagProcessor {
 
}

The final step in creating new tag processors is registering in the class factory. The tag processor class is registered using the key TagProcessorClass in the config file for the prefix to which it will be connected. In the present example, that prefix is "sample-prefix". To register the tag processor, we must specify the name of the tag processor class and the file where its declared. This is illustrated in the below example.

$config = Array (
	'Prefix' => 'sample-prefix',
	'TagProcessorClass' =>	Array ('class' => 'SamplePrefixTagProcessor', 'file' => 'sample_prefix_tp.php', 'build_event' => 'OnBuild'),
);

The key that wasn't described above is called "build_event", that is used for the event task, which will initialize the object. For tag processor classes, this will always be the event OnBuild.

Image:Infobox Icon.gif All class names, registered in the class factory are cached so we must reset cache before changes will take effect.

Adding a Tag to the Tag Processor

After successfully creating or finding the class of the tag processor, we can start writing the method whose output will be displayed on the page as a result of the new tag. The method itself will be located in the class of the tag processor. Following tag naming conventions, each word in the method name must start with a capital letter. Also, each method's name may contain only Latin letters and numbers, although it's preferred that numbers aren't used.

The (template parser) upon calling the method indicated in the tag in the template will also pass an associative array of parameters, passed to the tag itself as the first argument of the method. This is illustrated in the following example:

class SamplePrefixTagProcessor extends kDBTagProcessor {
 
	/**
	 * Tag description
	 *
	 * @param Array $params
	 * @return string
	 */ 
	function PrintHelloWorld($params)
	{
		return 'Hello World! Param Value: [' . $params['sample_param'] . ']';
	}
}

In the template, the tag call looks like this:

<inp2:sample-prefix_PrintHelloWorld />
Text Description
inp2 Namespace tag that the template parser processes.
sample-prefix Name of tag's prefix.

Paired and Unpaired Tags

All tags processed by the template parser are either tag pairs (opening and closing tag) or solo tags (self-closing). Paired tags differ from self-closing tags in that paired tags can use the code/text within them at their discretion. All tags declared in tag processor classes are self-closing tags. All paired tags are system tags and cannot be changed/overwritten. In general, paired and non-paired tags look like this:

non-paired/self-closing tag:
<inp2:prefix.special_TagName param1="value1" param2="value2"/>
 
paired tag:
<inp2:prefix_TagName param1="value1" param2="value2">
text contained in tag
</inp2:prefix_TagName>
Image:Tipbox Icon.gif To separate tag parameters from the tag any number of whitespace characters can be used.

Below are examples and explanations of a couple common tags.

  • Unpaired tags::
а) <inp2:m_TemplatesBase module="Custom"/> - path to the directory containing the theme files for the module Custom.
б) <inp2:m_GetConfig var="Site_Name"/> - config variable Site_Name.
с) <inp2:st_PageInfo type="meta_title"/> - page title.
  • Paired tags:
а) Tag conditions.
<inp2:m_if check="m_Param" name="is_last">
...
</inp2:m_if>
 
б) Tag defining a block element in a template.
<inp2:m_DefineElement name="menu_block">
	<td><inp2:m_Phrase name="lu_about_us"/></td>
</inp2:m_DefineElement>

General Form for Calling a Tag in a Template

The general form for calling a tag in a template looks as follows:

<inp2:prefix[.special]_TagName param1="value1" other_param='value2'/>
parameter description
prefix (string) Tag Prefix, for example, "test".
special (string) Tag Special, for example, "front". If used, then separated from the prefix using a period (".").
TagName (string) The name of the tag, for example, "PrintHelloWorld". If the tag is not defined anywhere, then the template parser will output a (fatal error) and will stop processing the rest of the tags in the current template.
param1="value1" Parameter pair and its value, that can be passed to a tag. An unlimited amount of parameters can be passed to a tag. A parameter name must be unique within a single tag and be made up of only Latin letters and numbers.
other_param='value2' It's also valid to assign the parameter value inside another tag. This is useful when the tag itself is being used as the attribute in an HTML tag because it won't mess up syntax highlighting in a template (if an editor with syntax highlighting is being used). This is demonstrated in the below example.
<img src="<inp2:m_TemplatesBase module='custom'/>img/spacer.gif" alt=""/>

Example of calling a tag in a template:

<inp2:test.front_PrintHelloWorld current_datetime="yes" />

Example of a function the class TestTagProcessor

/**
 * Printing sample text and current date, when additional parameter is given
 *
 * @param Array $params
 * @return string
 */ 
function PrintHelloWorld($params)
{
	// check for special
	$ret = $this->Special == 'front' ? 'Hello World Front !' : 'Hello World !';
 
	// check whether parameter 'current_datetime' is set	
	if (array_key_exists('current_datetime', $params) && ($params['current_datetime'] == 'yes')) {
		$ret .= ' ' . adodb_date('m/d/Y H:s');
	}
 
	return $ret;
}

Setting Default Parameters

Default parameters allow assigning parameter values for paired (block) tags and for templates for the case where the given tags or templates will be used without passing to them all the parameters that they use.

Default Template Parameters

Default template parameters are set at the top of the template using the tag m_DefaultParam. If a parameter is going to be used in the body of a tag, but it's value isn't passed when the template is called, then it's default parameter will be used. This is demonstrated on the below example.

=== include_test.tpl ===
<inp2:m_DefaultParam param1="default_value1" param2="default_value2"/>
 
PARAM: [<inp2:m_Param name="param2"/>]
 
=== index.tpl ===
// will output PARAM: [default_value2]
<inp2:m_include template="include_test"/>
 
// will output PARAM: [given_value]
<inp2:m_include template="include_test" param2="given_value"/>

Default Paired Tag Paramaters

Default parameters for paired tags tags are specified in their definition. This is demonstrate on the below example.

<!-- block definition -->
<inp2:m_DefineElement name="sample_element" as_label="" currency="USD">
	[<inp2:m_Param name="as_label"/> - <inp2:m_Param name="currency"/>]
</inp2:m_DefineElement>
 
<!-- using the block and passing it parameters -->
<inp2:m_RenderElement name="sample_element" as_label="1"/> // даст [1 - USD]
 
<!-- using the block without passing it parameters -->
<inp2:m_RenderElement name="sample_element"/> // даст [ - USD]

Location of Templates

All templates are divided into 2 groups based on where they are used:

  • administrative console;
  • front end site.

Below will be described the specifics concerning location and purpose of templates from both of the above groups.

Administrative Console Templates

All administrative console templates are divided by modules. Following, each module has its own "admin_templates" directory, which contains all of its admin templates. For example, if the module is called "proj-base", then its admin templates will be in the "proj-base/admin_templates" directory. Under the "admin_templates" directory, it's allowed to create other directories to logically group templates within a single module. When using a template, one must always write the module name preceding the template name, for example "proj-base/users/users_list", instead of simply "users/users_list". If one has to include the original version of a template (if the template was changed through ReplacementTemplates) then one must write "orginal:" before the template name, for example "original:path/to/replaced/template".

Image:Tipbox Icon.gif Writing the module name is not required for templates in the "core/admin_templates" directory.
Image:Infobox Icon.gif For projects, creating and changing administrative console templates is only allowed for templates in the "custom/admin_templates" folder, i.e. belonging to the module "custom".

Front-end Templates

Front-end templates are divided by theme(styles). There's a directory for each theme such as "themes/<theme_name>", where "<theme_name>" is the Name field of the actual template. All templates are defined in the "Configuration -> Themes" section. Usually, creating a theme folder with templates inside of it and pressing the "Rebuild Theme Files" button in the themes toolbar is enough for an entry to be automatically created in the Theme table. For example, if the path to the template relative to the project's root directory is "themes/theme_test/testing/sample_template.tpl", then to use the template one can write "testing/sample_template". The template will then look in the theme that's indicated in the site URL.

Image:Tipbox Icon.gif In projects, there's usually only one theme, named "theme_<project_name>", for example "theme_estore".

Parameter Scope

By default, parameters passed to a block or template will only be visible in the block or template itself. If the situation calls for passing the value of an individual parameter to another block or template, then that can be done with the following code: param_name="$param_name". If passing all parameter values from one template or block to another is what's needed, then one needs to set the parameter "pass_params". All above described variations will be demonstrated in the below example.

== main.tpl ==
<inp2:m_DefaultParam main_param="sample_value" main_param2="test"/> <!-- Setting default values for the "main_param" and "main_param2" parameters. -->
 
<inp2:m_DefineElement name="sample_element">
	main param: [<inp2:m_Param name="main_param"/>]
	main param2: [<inp2:m_Param name="main_param2"/>]
</inp2:m_DefineElement>
 
<!-- The values of all parameters from this block will not be accessible in the included template and rendered block. -->
<inp2:m_include template="include_test"/>
<inp2:m_RenderElement name="sample_element"/>
 
<!-- Only the value of "main_param" will be accessible in the included template and rendered block. -->
<inp2:m_include template="include_test" main_param="$main_param"/>
<inp2:m_RenderElement name="sample_element" main_param="$main_param"/>
 
<!-- Only the value of "main_param2", by the name of "main_param" will be accessible by the included template and rendered block. -->
<inp2:m_include template="include_test" main_param="$main_param2"/>
<inp2:m_RenderElement name="sample_element" main_param="$main_param2"/>
 
<!-- All parameter values from this template will be accessible in the included template and rendered block. -->
<inp2:m_include template="include_test" pass_params="true"/>
<inp2:m_RenderElement name="sample_element" pass_params="true"/>
 
== include_test.tpl ==
main param: [<inp2:m_Param name="main_param"/>]
main param2: [<inp2:m_Param name="main_param2"/>]

Parameter Naming Conventions

The name of the tag parameter, which passes the name of the block must be called "render_as". In the case where several block names are passed to the tag, the parameter names, which pass the block names must start with "_render_as", for example "user_render_as". This is shown in the below example.

<inp2:sample-prefix_PrintList render_as="sample_element" more_render_as="more_element"/>

Parameters used in the template are changed into PHP-variables when the template is compiled, because of this their names must follow the same rules that apply to PHP variables. A correct parameter name must start with a letter or underscore, followed by any number of letters, numbers, and/or underscores.

Parameter Default Values

If parameter default values are not set for optional parameters in the template or block, then PHP warnings will be generated when the template or block is used, which is not desirable. To find places in a template where default values for parameters aren't set, the best thing to use is the debugger.