Несколько тегов, разделённых запятой, означают логическое И между ними. Вы также можете использовать точку с запятой в качестве логического ИЛИ. И имеет высший приоритет над ИЛИ. Вы не можете использовать скобки для группировки условий. Звёздочка (*) внутри тега используется в качестве маски для "подстроки".
Разделы: Документация / Расширяем Cotonti / Темы
Этот документ описывает возможности, структуру и синтаксис применяемый в шаблонизаторе CoTemplate версии 2.7 и выше.
Блоки являются основой структуры шаблонов. Шаблон содержит блоки, блоки могут содержать другие блоки, выражения, условия, теги и обычный текст. Рассмотрим пример блока:
<!-- BEGIN: BLOCK_NAME --> Содержимое блока в виде HTML кода <!-- END: BLOCK_NAME -->
Где `BLOCK_NAME` — это имя блока (допустимы латинские буквы и символ подчеркивания). Большинство блоков состоят из единственного корневого блока `MAIN`. Шаблон допускает применение нескольких корневых блоков одновременно. Текст (как и HTML код) находящийся вне корневых блоков игнорируется.
Названия блоков задаются в верхнем регистре, это основное правило.
Блок идентифицируется и выводится контроллером. Блоки могут быть идентифицированы по их полному имени: 'PARENT_BLOCK.BLOCK_NAME'. Блоки самые быстрые структуры в шаблонах. Эти три основные момента делают их основой всех остальных конструкций шаблонизатора.
Переменные в CoTemplate именуются Тегами шаблона (TPL Tags) или просто Тегами. Используются 2 вида тегов: глобальные и локальные.
Локальные теги назначаются (определяются) через вызов метода XTemplate::assign() в управляющем PHP коде. Их синтаксис таков:
{TAG_NAME}
Такая запись будет заменена на значение локальной переменной шаблона (определенной внутри объекта XTemplate ) с именем 'TAG_NAME'. Указание имен в верхнем регистре используется, как основное правило, позволяющее выделить Теги шаблона среди прочего кода.
Глобальные теги это по сути ссылка на переменную PHP в глобальной области видимости. Такие теги используют для этого ключевое слово «PHP» в своем имени:
{PHP.my_var}
В большинстве случаев рекомендуется использование локальных тегов. Глобальные применяются для вывода переменных, которые должны использоваться в разных блоках или шаблонах или как выход из ситуации когда специальный локальный тег не определен..
Теги могут быть использованы для доступа к элементам массива или (публичным) свойствам объекта. Для указания ключей массива или имен свойств используется запись через точку:
{ARRAY_TAG_NAME.array_key_name} {OBJECT_TAG_NAME.object_property_name} {PHP.global_var_name.key_name}
Массивы/объекты могут быть вложенными. Доступ к вложенным элементам осуществляется аналогично:
{TAG_NAME.level1_key.level2_key}
Ограничения на вложенность нет, но надо иметь в виду, что чем больше вложенность, тем медленней работает такой тег.
Вызов функций позволяет перед выводом значения тега обработать его с помощью заданной функции. Для этого используется вертикальная черта (знак «пайп») для отделения имени тега и имени функции:
{TAG_NAME|function_name}
Результатом будет возвращенный функцией результат по обработке значения тега с именем «TAG_NAME». В качестве имени функции может быть использовано имя любой PHP функции, которая принимает один строковый параметр и возвращает строковое значение (можно использовать как встроенные функции, так и определенные пользователем).
Если функция подразумевает более одного аргумента, они могут быть заданы в круглых скобках. Синтаксис аналогичен обычному вызову PHP функции, с учетом того, что все аргументы постоянны, за исключением случая, когда указано ключевое слово `$this`, которое будет заменено на значение тега или предыдущего вызова функции:
{MY_TAG|substr($this, 3, 5)}
Возможен вызов цепочкой, при этом результат вызова первой функции будет передан далее в следующую. Пример:
{MY_STRING|str_replace('foo', 'bar', $this)|htmlspecialchars}
Вызов функций и использование массивов/объектов можно совмещать:
{MY_TAG.item1|do_something|mb_strtoupper}
Глобальные теги также могут быть обработаны через вызов функции. Причем таким образом может быть вызвана функция без передачи содержимого какого-либо тега вообще:
{PHP|my_function_call('some_data', 10)}
Используйте механизм вызова функций с умом, чтобы не превратить код вашего шаблона в кашу.
Оператор FILE используется для включения дополнительных файлов шаблоны в текущий. Синтаксис таков:
{FILE "path/to/file.tpl"}
Путь указывается относительно корня вашего сайта. Вы можете использовать теги шаблона при задании пути к файлу:
{FILE "{PHP.cfg.plugins_dir}/{PHP.theme}/something.tpl"}
Таким образом происходит фиксированная вставка: содержимое указанного файла целиком и без изменений вставляется на место оператора перед тем, как произойдет дальнейшая обработка шаблона.
Оператор IF используется для вывода отдельных частей шаблона исходя из логического условия проверяемого на момент запуска. Оператор IF так же называется условным блоком или логическим блоком. Простейший синтаксис условного блока:
<!-- IF expression --> часть HTML кода <!-- ENDIF -->
Содержимое блока будет отображено, если выражение (expression) истинно (равняется TRUE). Синтаксис условного выражения аналогичен таковому в PHP может содержать Теги шаблона, константы, операторы и скобки. Полный перечень приведен здесь.
Также поддерживается конструкция IF/ELSE :
<!-- IF {FOO} > 10 AND ({PHP.bar} OR {BAZ} ~= 'boo') --> This is rendered if the condition is TRUE. <!-- ELSE --> This is rendered if the condition is FALSE. <!-- ENDIF -->
Условные блоки могут содержать внутри себя другие блоки, условные блоки и циклы, теги, операторы FILE и обычный HTML код.
Оператор FOR используется для обработки данных, которые сами по себе такого механизма не имеют. Простейший пример:
<!-- FOR {VALUE} IN {MY_ARRAY} --> Используем {VALUE} <!-- ENDFOR -->
или
<!-- FOR {KEY}, {VALUE} IN {MY_ARRAY} --> Используем {KEY} и {VALUE} <!-- ENDFOR -->
Здесь 'MY_ARRAY' — это имя тега, данные которого мы хотим обработать. 'KEY' и 'VALUE' имена тегов, используемых для доступа к имени элемента и значению; {VALUE} представляет собой значение элемента, а {KEY} содержит строковое или числовое значение ключа массива.
Использование совместно с вызовом функций предоставляет большие возможности. Пример одного из вариантов использования:
<ul> <!-- FOR {KEY}, {VALUE} IN {MY_ARRAY} --> <li><strong>{VALUE.title}: </strong> <input name="{KEY}" type="text" value="{VALUE.text|htmlspecialchars}" /></li> <!-- ENDFOR --> </ul>
Обычный цикл по диапазну:
<!-- FOR {INDEX} IN {PHP|range(1,10)} --> {INDEX}<!-- IF {INDEX} < 10 -->,<!-- ENDIF --> <!-- ENDFOR -->
Цикл от 10 до 2 с шагом -2:
<!-- FOR {NUM} IN {PHP|range(10, 2, -2)} --> {NUM}<br /> <!-- ENDFOR -->
Как и логические блоки циклы могут включать в себя любые доступные для шаблона типы блоков и текста.
Имя ключа и значение находятся, как и другие теги, в едином с ними пространстве. В шаблонизаторе нет понятия области видимости или стеков.
Разделы: Документация / Расширяем Cotonti / Темы
Универсальность движка Котонти состоит в том числе и в использовании гибкого механизма шаблонов CoTemplate (ранее известного как XTemplate). CoTemplate добавляет новые возможности к обработке шаблонов: обработка вложенных блоков (поддерживаются циклы и условные блоки) и вызов дополнительных функций.
Условные блоки использующие оператор `IF` вероятно многим разработчикам уже знакомы. Однако здесь можно использовать не только обычные сравнения на равенство. Ниже приводится таблица операторов допустимых в условных блоках:
Наименование | Оператор | Описание |
---|---|---|
равенство | == | значения равны |
неравенство | != | значения не равны |
меньше чем | < | левое значение меньше правого |
больше чем | > | левое значение больше правого |
меньше или равно | <= | левое значение меньше или равно правому |
больше или равно | >= | левое значение больше или равно правому |
содержит | HAS | левое выражение (массив) содержит правое значение (строку) |
включает | ~= | левое значение (строка) включает в себя правое значение (строку) |
сложение | + | складывает 2 значения |
вычитание | - | вычитает значения |
умножение | * | умножает значения |
деление | / | делит значение |
остаток целочисленного деления | % | возвращает остаток от деления |
логическое `И` | AND | объединяет два значения, оба должны истинны (true) |
логическое `ИЛИ` | OR | объединяет два значения, хотя бы одно из них должно быть истинно (true) |
логическое `исключающее ИЛИ` | XOR | объединяет два значения, только одно может быть истинно (true) |
отрицание | ! | делает булевское значение (boolean) обратным |
Эти операторы могут использоваться в условных блоках файлов шаблонов. Ниже простой пример объединения нескольких условий:
<!-- IF {PHP.i} % 2 == 0 AND {PHP.usr.isadmin} --> Строка четная и пользователь имеет права администратора. <!-- ENDIF -->
Начиная с Siena 0.9.0, которая использует CoTemplate версии 2.5, условные блоки могут быть вложенными. Это значит, что вы можете использовать условные блоки или циклы внутри других блоков (условных илил циклов). Кроме того, это позволяет использовать конструкции типа «ELSE IF» (которые в таком виде не работают), просто добавив дополнительный условный блок (`IF`) внутри блока `ELSE`.
Еще одно мощное нововведение шаблонизатора CoTemplate версии 2.5 — это вызов функций (callback или «функция обратного вызова»). Здесь обратный вызов — это вызов функции PHP из вашего шаблона, с возможностью передать значение любого шаблонного тега как параметр функции. Тег с вызовом функци будет заменен на значение возвращаемое функцией.
В качестве параметра функции может быть использован любой вид шаблонных тегов, включая ссылки на переменную PHP — {PHP.myvar} (которая ссылается на значение переменной $myvar вашего скрипта). Вызов функции инициируется добавлением знака вертикальной черты `|` (знак конвейера / pipe sign) к тегу с последующим указанием имени функции PHP (включая пользовательские функции и стандартные движка). Вызов функции практически аналогичен её же вызову в PHP — все параметры перечисляются в скобках, с той лишь разницей, что передача значения тега шаблона осуществляется через специальную переменную `$this`. Переменная `$this` при вызове будет заменена на значение тега шаблона, используемого перед знаком конвейера.
Таким образом, к значению тегов шаблона можно применять обычные функции PHP, используя результат в шаблоне. Ниже приведено несколько примеров обратного вызова функций:
{PAGE_BEGIN_STAMP|cot_date('date_full', $this)} |
2011-01-01 (зависит от локаьных настроек) |
{LIST_ROW_BEGIN_STAMP|cot_date('date_text', $this)} |
January 1, 2011 (зависит от локаьных настроек) |
Copyright {PHP|date('Y')} |
Copyright 2011 |
{PHP|cot_url('page', 'c=news')} |
page.php?c=news (зависит от правил создания URL) |
{PHP.sys.xk|cot_url('users', 'm=logout&x=$this')} |
users.php?m=logout&x=1234567890abcdef (зависит от правил создания URL) |
В примерах выше используется тег `PHP`. Этот тег сам по себе не имеет значения и используется для вызова функций в которые нет необходимости передавать значения каких-либо тегов.
Имейте в виду, что реализация механизма обратного вызова такова, что все параметры вызова интерпретируются программой как значения строкового (string) типа. Это значит, что передать «на прямую» в функцию значение `false` не удастся. Для выхода из этой ситуации используйте вместо `false` значение `0` (ноль). Однако помните, что метод не сработает, если в функции этот параметр проверяется с использованием строгой проверки (проверка с типом оператором `===`).
Учитывая возможность вызывать собственные функции (например добалвяя их в файл system/functions.custom.php), возможности шаблонов расширяются практически неограничено. Тем не менее, надо учитывать, что просто не значит правильно. Применение логики в ваших шаблоных имеет и обратные стороны. Во-первых, это снижает производительность, особенно если часто использовать такой подход. Во-вторых, это нарушает принципы MVC (методология программирования Модель-Вид-Контейнер), согласно которой логика приложения должна быть отделена от представления (отображения шаблонов). По мимо прочего, это может усложнить работу дизайнера. Особенно если он не разбирается в Котонти и тем более в PHP.
Разделы: Documentation / Quick help & how-to's
By default, dates and times in Cotonti are formatted in a preconfigured way. While this works out fine in most cases, sometimes you will want to use a different format in your theme. Cotonti provides a simple way to achieve this using CoTemplate callbacks.
{PAGE_ROW_DATE_STAMP|cot_date('d-m-Y', $this)}
The cot_date()
function is very similar to the regular date function in PHP, with the addition of localized date formats. These formats are defined in $Ldt in main.en.lang.php. It's recommended to use these formats since they are more flexible. Here's an example:
{PAGE_ROW_DATE_STAMP|cot_date('date_full', $this)}
Here's a list of all the available localized date/time formats (default en_US locale):
Name | Format | Example |
---|---|---|
date_full | Y-m-d | 1988-06-18 |
date_medium | Y-m | 1988-06 |
date_short | m-d | 06-18 |
date_text | F d, Y | June 18, 1988 |
date_fulltext | l, F d, Y | Saturday, June 18, 1988 |
time_full | H:i:s | 08:45:00 |
time_medium | G:i | 8:45 |
time_short | i:s | 45:00 |
time_text | g:i A | 8:45 AM |
time_fulltext | g:i:s A | 8:45:00 AM |
datetime_full | Y-m-d H:i:s | 1988-06-18 08:45:00 |
datetime_medium | Y-m-d H:i | 1988-06-18 08:45 |
datetime_short | m-d H:i | 06-18 08:45 |
datetime_text | F d, Y H:i | June 18, 1988 08:45 |
datetime_fulltext | l, F d, Y H:i | Saturday, June 18, 1988 8:45 |
week_full | o-\WW | 1988-W24 * |
week_medium | \WW | W24 |
week_short | \WW-N | W24-6 |
week_text | \WW, l | W24, Saturday |
week_fulltext | o-\WW, l | 1988-W24, Saturday |
* If the ISO week number belongs to the previous or next year, that year is used.
For more information on date/time formatting, see the PHP documentation.
Разделы: Documentation / Extending Cotonti / Themes
This document covers features, statements and their syntax supported by CoTemplate v.2.7 and later.
Blocks are the largest elements in the template's structure. Templates consist of blocks, blocks consist of other blocks, statements, tags and raw text. Here is the block syntax:
<!-- BEGIN: BLOCK_NAME --> Block HTML contents here <!-- END: BLOCK_NAME -->
Most templates have one root-level block named MAIN, but multiple root-level blocks in one template file are allowed. HTML outside the root-level blocks is ignored.
Block names are given in upper case. This is a common rule.
Blocks are triggered and pushed to output by controller PHP code. Blocks can be referenced by their full name, e.g. 'PARENT_BLOCK.BLOCK_NAME'. And blocks are slightly faster than other statements. These 3 facts make them fundamental building blocks in CoTemplate.
Variables in CoTemplate are called TPL Tags or just Tags. There are 2 kinds of tags depending on their scope: local tags and global tags.
Local tags are assigned with XTemplate::assign() method in controller PHP code. Their syntax is:
{TAG_NAME}
Such a statement will be substituted with current value of a locally assigned variable in the XTemplate object with name 'TAG_NAME'. Local tag names are given in upper case, this common rule allows us to distinct TPL tags quite easily from the other code.
Global tags are just global PHP variables, they have PHP keyword in their name:
{PHP.my_var}
Although it is recommended to use local tags for most of the output, global tags are used to output global variables which are available in many blocks and templates or to compensate the lack of a specific local tag.
Tags can be used to access arrays and objects with public properties. Dot notation is used to specify array keys or property names:
{ARRAY_TAG_NAME.array_key_name} {OBJECT_TAG_NAME.object_property_name} {PHP.global_var_name.key_name}
Arrays/objects can be nested. The same notation is used to access nested elements:
{TAG_NAME.level1_key.level2_key}
There is no limit on nesting level, but the deeper the level, the slower such a tag works.
Callbacks provide the way to process data with some functions before output. Pipe character is used to separate callback from the tag being processed:
{TAG_NAME|function_name}
This will be substituted with the result of function 'function_name' called on the value of tag 'TAG_NAME', where 'function_name' is the name of any valid PHP function that takes 1 string argument and returns a string value, including built-in PHP functions and user functions.
If there are more than 1 argument, braces can be used to specify them. The syntax is similar to PHP function call, but arguments are literals, except for the special keyword $this, which is replaced with the current value of the tag or a previous callback result:
{MY_TAG|substr($this, 3, 5)}
Multiple callbacks are supported, the result of the previous callback is "piped" to the next callback. Example:
{MY_STRING|str_replace('foo', 'bar', $this)|htmlspecialchars}
Callbacks and array/object access can be mixed together:
{MY_TAG.item1|do_something|mb_strtoupper}
Global tags are processed with callbacks too. There is a special use of global tags + callbacks which allows you to invoke PHP functions without processing any actual tags:
{PHP|my_function_call('some_data', 10)}
It is not recommended to turn your TPL files into PHP spaghetti, so use them carefully.
FILE statements are used to include TPL files within other TPL files. The syntax is:
{FILE "path/to/file.tpl"}
The path is relative to the root of your website. You can use TPL tags within the path, e.g.:
{FILE "{PHP.cfg.plugins_dir}/{PHP.theme}/something.tpl"}
Inclusion is performed quite literally: the contents of the given file are inserted exactly in the place of the FILE statement before any further parsing/processing of the current template.
IF statements are used to render parts of the template depending on logical conditions at run-time. IF statements are also known as conditional or logical blocks. A simple IF statement syntax:
<!-- IF expression --> some HTML/TPL code here <!-- ENDIF -->
The contents of the logical block is rendered if the expression evaluates to TRUE. The syntax of expressions is similar to PHP comparison and boolean expressions and may consist of TPL tags, literals, operators and parenthesis. The list of all supported operators is avialable here.
IF/ELSE syntax is also supported:
<!-- IF {FOO} > 10 AND ({PHP.bar} OR {BAZ} ~= 'boo') --> This is rendered if the condition is TRUE. <!-- ELSE --> This is rendered if the condition is FALSE. <!-- ENDIF -->
Conditional blocks may contain other blocks, other IF and FOR statements, tags, FILE statements and raw HTML.
FOR statements are used to iterate over the data which doesn't have any special iteration blocks provided. The most generic syntax is:
<!-- FOR {VALUE} IN {MY_ARRAY} --> Some use of {VALUE} <!-- ENDFOR -->
or
<!-- FOR {KEY}, {VALUE} IN {MY_ARRAY} --> Some use of {KEY} and {VALUE} <!-- ENDFOR -->
Where 'MY_ARRAY' is the name of the tag which contains the actual data which is being looped over. 'KEY' and 'VALUE' are the names of the tags which are used to access array elements inside the loop; {VALUE} represents the value of the current item, {KEY} represents a string or an integer key of the item within the array.
Callbacks can be used to provide almost limitless looping and processing possibilities. Below some common examples are represented.
<ul> <!-- FOR {KEY}, {VALUE} IN {MY_ARRAY} --> <li><strong>{VALUE.title}: </strong> <input name="{KEY}" type="text" value="{VALUE.text|htmlspecialchars}" /></li> <!-- ENDFOR --> </ul>
Traditional loop within an integer range:
<!-- FOR {INDEX} IN {PHP|range(1,10)} --> {INDEX}<!-- IF {INDEX} < 10 -->,<!-- ENDIF --> <!-- ENDFOR -->
Loop from 10 downto 2 with a negative step of -2:
<!-- FOR {NUM} IN {PHP|range(10, 2, -2)} --> {NUM}<br /> <!-- ENDFOR -->
FOR loops may conatin other nested FOR loops, IF statements, FILE includes, blocks, tags and raw HTML data.
Key and value tags are assigned in the common tag scope. There is no stack/scoping in CoTemplate.
Разделы: Documentation / Extending Cotonti / Themes
Much of Cotonti's flexibility is derived from it's templating engine CoTemplate (previously known as XTemplate). Recent additions to the engine include nested logic blocks (conditionals and loops) and callbacks. Simple IF statements will be familiar to most developers, but there's more than just the regular equals comparison. Here's an overview of what's possible:
Name | Operator | Description |
---|---|---|
Equal | == | Values are equal |
Not Equal | != | Values are not equal |
Less Than | < | Left is smaller than right |
Greater Than | > | Left is larger than right |
Less Than or Equal | <= | Left is smaller or equal to right |
Greater Than or Equal | >= | Left is larger or equal to right |
Has | HAS | Left (array) contains right (string) |
Contains | ~= | Left (string) contains right (string) |
Addition | + | Adds two values |
Subtraction | - | Subtracts two values |
Multiplication | * | Multiplies two values |
Division | / | Devides two values |
Modulus | % | Calculates modulus of two values |
AND | AND | Groups two conditions, both must be true |
OR | OR | Groups two conditions, at least one must be true |
Exclusive OR | XOR | Groups two conditions, only one may be true |
NOT | ! | Negates (inverts) boolean |
These operators can be used in IF conditions in your template files. Here's an example that combines several operations:
<!-- IF {PHP.i} % 2 == 0 AND {PHP.usr.isadmin} --> The row is even and the user has administrative rights. <!-- ENDIF -->
Since Siena 0.9.0, which includes CoTemplate 2.5, conditional blocks can be nested. This means that you can put conditions within conditions, or loops within conditions, etc. This can also be useful if you want to have an ELSE IF (which isn't normally supported) by putting an IF statement within the ELSE block.
A very powerful feature that is included with CoTemplate 2.5 is callbacks. A callback is a PHP function call from within your template, which can take a regular template tag as parameter. Instead of the template tag's value, the return value of the callback function is inserted into your HTML. Any template tag can accept a callback function, including PHP variable calls such as {PHP.myvar} (which refers to $myvar in the script). This is achieved by appending a pipe | sign to the template tag, as well as the name of a PHP function (including user defined functions and Cotonti's core functions). The function call itself is the same as in regular PHP code, meaning any parameters are enclosed in parentheses. There is one exception however which involves the callback value. Template callbacks have one special variable named $this which contains the value of the template tag preceding the callback. By using this variable you gain the ability to pass on a template tag to a regular PHP function and use the result in your template. Here's some examples of interesting ways to use callbacks:
{PAGE_BEGIN_STAMP|cot_date('date_full', $this)} |
2011-01-01 (depends on locale settings) |
{LIST_ROW_BEGIN_STAMP|cot_date('date_text', $this)} |
January 1, 2011 (depends on locale settings) |
Copyright {PHP|date('Y')} |
Copyright 2011 |
{PHP|cot_url('page', 'c=news')} |
page.php?c=news (depends on URL rewrite rules) |
{PHP.sys.xk|cot_url('users', 'm=logout&x=$this')} |
users.php?m=logout&x=1234567890abcdef (depends on URL rewrite rules) |
In the above list you also see the use of a 'PHP' tag. This basically does nothing, it has no value. It's a way to use a callback without linking it to a template tag.
Since the list of functions is enormous and can easily be extended by writing custom functions (for example in system/functions.custom.php), the possibilities with this are virtually endless. However, you should be aware that in many cases, the easiest solution is not the best. Putting logic in your template has some drawbacks. Firstly, it's slow if used a lot. For more complex situations you're better off writing a plugin instead. Secondly, it undermines the principles of MVC, in which logic should be kept seperate from layout. This can be a problem if you work with designers that have no knowledge of Cotonti or even PHP.
Разделы: Download
What's new in 0.6.17
lang/en/admin.lang.php lang/ru/admin.lang.php core/message/message.inc.php core/admin/admin.page.structure.inc.php functions.php
Разделы: Documentation / Extending Cotonti / Themes
Since Cotonti 0.9.1 a new set of debugging facilities is available to template designers.
The first one is block/tags listing mode. It outputs a plain tree of blocks and assigned tags in them for the current page. Example:
To get such a debug page, you need to make sure debug_mode is enabled for your Cotonti instance first. Open datas/config.php and make sure you have debug_mode enabled:
$cfg['debug_mode'] = TRUE;
Then you can see a TPL dump of any page by simply appending tpl_debug=1 parameter to the URL of the page, e.g.
There are several notes about TPL Debug functioning:
Another useful feature which is now available is variable dumps. To see a dump of the variable instead of its content, you add special dump()
callback to it using a pipe sign, e.g.
{MY_TAG|dump} {PHP.usr.profile|dump} or even {PHP|dump}
For example, if you place {PHP.out|dump} in header.tpl, you will see somewhat like this:
And finally, one of the most frequently asked questions: