<!--toc--> |
|
## Переменная |
|
Простейшая команда темплейта - отобразить переменную. Синтаксис тривиален: |
|
VARIABLE |
|
Например, если необходимо отобразить содержимое значения `message`, достаточно написать: |
|
<% message %> |
|
Это, в действительности, транслируется в следующий код C++: |
|
out()<<cppcms::filters::escape(content.message); |
|
, где функция `escape` записывает в поток переменную-член содержимого `message` и экранирует специальные HTML-символы `<`, `>`, `&`, `"` в их HTML представление - такое как `<` |
|
Если необходимо получить значение какого-либо свойства, достаточно написать: |
|
<% some_property() %> |
|
, которое транслируется в: |
|
out()<<cppcms::filters::escape(content.some_property()); |
|
|
## Переменная с фильтрами |
|
Вы можете добавить произвольные фильтры отображаемой переменной. Синтаксис следующий: |
|
VARIABLE [ '|' filter [ '|' filter ] ... ] |
|
, где `filter`: |
|
[ 'ext' ] NAME [ '(' ( VARIABLE | STRING | NUMBER ) [ ',' ( VARIABLE | STRING | NUMBER ) ] ... ] |
|
### Описание |
|
Если фильтры не указаны - переменная экранируется автоматичски, но если указаны - они будут использованы вместо экранирования. |
|
Каждая переменная - в действительности создание или вызов специального объекта фильтра с указанными параметрами, где первый параметр - "фильтруемая" переменная, а другие - параметры фильтра. Например: |
|
<% birthday | strftime("%d/%m/%Y") %> |
|
Транслируется в: |
|
out()<<cppcms::filters::strftime(content.birthday,"%d/%m/%Y"); |
|
Вы также можете конкатенировать фильтры, используя символ `|`: |
|
<% birthday | strftime("%d %m %Y") | urlencode %> |
|
Будет рендериться как: |
out()<<cppcms::filters::urlencode(cppcms::filters::strftime(content.birthday,"%d/%m/%Y")); |
|
Доступно множество предопределенных фильтров, см. ссылку на namespace [cppcms::filters](/cppcms_ref_v0_99_1/namespacecppcms_1_1filters.html). |
|
Один из фильтров, о котором стоит упомянуть - фильтр `raw`, позволяющий записать выходную переменную в чистом виде без HTML-экранирования. |
|
<% ready_html | raw %> |
|
Переменная `ready_html` будет записана в выходной поток в чистом виде без экранирования HTML-символов, таких как `<`. |
|
Вы можете указать произвольные внешние фильтры, определенные в классе `content`. Например: |
|
namespace data { |
struct page { |
... |
virtual string bbcode(string const &); |
... |
}; |
} |
|
Затем, в темплейте можно указать: |
|
<% class page uses data::page %> |
<% template render() %> |
<% message | ext bbcode %> |
<% end %> |
<% end %> |
|
__Примечание:__ В платформе Windows динамически подгружаемые библиотеки (dll) не допускают неизвестные символы. |
Поэтому, если необходима поддержка Windows, необходимо создать Ваши фильтры как виртуальные функции или обратные вызовы - типа `booster::function<>` чтобы предотвратить ссылочность на внешние символы. |
|
## Интернационализация |
|
### Синтаксис |
|
'gt' STRING [ 'using' using-options ] |
'ngt' STRING ',' STRING ',' VARIABLE [ 'using' using-options |
|
, где `using-options`: |
|
display-variable-block [ ',' display-variable-block [ ',' ... ] ] |
|
Где `display-variable-block` - любая переменная из опциональных фильтров, описанных выше. Например: |
|
<% gt "Press the button" %> |
<% gt "Hello Dear {1}, we are glad to see you!" using name %> |
<% gt "Hello <a href=\"{1}\">{2}</a> you have {3}" using link | urlencode , name , something %> |
<% ngt "You have one apple","You have {2} apples",n using n %> |
|
### Описание |
|
`gt` -- `gettext` переводит данную строку в соответствии с локалью, определенной в выводимом потоке. Например: |
|
<% gt "Press the button" %> |
|
Будет переведено как "Press the button" в English-локали и "Нажмите кнопку" - в Russian-локали. |
|
Можно указать дополнительные параметры, используя опцию `using`. Можно передать список, разделенный запятой, в том виде, в котором собирались отображаться переменные. Как обычно, можно использовать любые другие фильтры. "{1}", "{2}" и т.д., определяя очередность входных переменных. Для таких замен используется [`booster::locale::format`](/cppcms_ref_v0_99_1/classbooster_1_1locale_1_1basic__format.html) или [`cppcms::locale::format`](/cppcms_ref_v0_99_1/classcppcms_1_1locale_1_1basic__format.html) (в соответствии с backend'ом локализации, с которым компилировался CppCMS). |
|
|
`ngt` -- `ngettext` переводит множественную форму данного целого, где первый параметр - единственное число, второй - множественное и третий должен быть используемой переменной. |
|
_Примечание:_ |
|
1. При использовании `ngt` предполагается использование синтаксиса `using`, потому что необходимо обеспечить отображение действительного числа. |
3. Для проверки направления текста можно использовать `<% if rtl %>` или `<% if not rtl %>`. В действительности, это эквивалент: |
|
<% if (cppcms::locale::gettext("LTR",out().getloc())=="RTL") %> |
|
Описание оператора `if` см. в дальнейшем тексте. |
|
## Подключение других темплейтов |
|
### Синтаксис |
|
'include' IDENTIFIER '(' [ parameter [ ',' parameter ...] ] ')' |
|
, где `parameter` - одно из VARIABLE, STRING или NUMBER. Например: |
|
<% include title() %> |
<% include parent::foo() %> |
<% include bar(x,"test",-1.0) %> |
|
### Описание |
|
Эта команда позволяет включить в это место другие темплейты (в действительности вызывая другие функции-члены). Вы можете включить существующие реализации в родительские view для их расширения. Например: |
|
<% view master uses data::master %> |
<% template menu() %> |
<li><a href="#1">Main</a></li> |
<li><a href="#2">Products</a></li> |
<% end template %> |
<% template render() %> |
<ul><% include menu() %></ul> |
<% end template %> |
<% end view %> |
<% view sales uses data::sales extends master %> |
<% template menu() %> |
<% include master::menu() %> |
<li><a href="#3">Orders</a></li> |
<% end %> |
<% end %> |
|
Этот код расширяет menu, добавляя в него view `sales` с дополнительными опциями. |
|
## Рендеринг форм |
|
### Синтаксис |
|
'form' ('as_p' | 'as_table' | 'as_ul' | 'as_dl' | 'as_space' | 'input' | 'begin' | 'end' ) VARIABLE |
|
флаги `as_*` позволяют рендерить `cppcms::form` со специфичными разделителями, в то время как флаги `input`, `begin` и `end` - позволяют рендерить отдельную часть widget'а. |
|
### Описание |
|
Формы организованы как объект формы или набор widget'ов. Каждый набор может рендериться с использованием различных разделителей: |
|
- `as_p` -- используя HTML-параграфы. |
- `as_table` -- используя таблицы. _Примечание_: теги `<table>...</table>` не добавляются, пользователь должен указать их. |
- `as_ul` -- как список (используя `<li>..</li>`). `<ul>..</ul>` - не определяются. |
- `as_dl` -- как определяемый список. `<dl>`-тэги не определяются, используются `<dt>..</dt>` и `<dd>..</dd>`. |
- `as_space` -- вставляет пробелы между элементами. |
|
Например: |
|
<table> |
<% form as_table form.fields %> |
</table> |
<p><% form as_space form.submit_buttons %></p> |
|
Может отрендериться как: |
|
<table> |
<tr><th>User Name:</th><td><input ... /></td></tr> |
<tr><th>Password: </th><td><input ... /></td></tr> |
</table> |
<p><input ... value="Login" /> <input ... value="Forgot Password" /></p> |
|
Иногда, необходимо выполнить произвольный рендеринг widget'ов, не предопределенный из этого списка. |
В этом случае можно рендерить только поле `<input ...>` вызывая |
<% form input some_button %> |
|
, который отрендериться в виде: |
|
<input type="submit" name="_3" value="Press" /> |
|
Заметьте, `input` - не означает строгое ограничение для widget'ов, использующих HTML-тег `input`, он работает в любых других widget'ах, ограниченных только фактическим рендерингом содержимого без "help"-сообщений. Например, для widget'а |
`cppcms::widgets::textarea` это будет `<textarea ...>some text</textarea>` |
|
Иногда, необходим более точный доступ к визуализируемым частям widget'а, например, необходимо добавить некоторые атрибуты для widget'а в view. |
|
Вы можете рендерить `begin` или `end` часть widget'а так, что можно будет вставить между ними HTML-атрибуты или даже JavaScript: |
|
<% form begin some_button %> onclick="return foo()" <% form end some_button %> |
|
Который рендериться как |
|
<input type="submit" name="_3" onclick="return foo()" value="Press" /> |
|
|
Для генерации произвольного HTML для widget'ов, всегда можно использовать свойства widget'а напрямую: |
|
<input type="submit" name="<% button.name() %>" value="Press" /> ( <% button.help() %> ) |
|
См.: [`cppcms::widgets` namespace](/cppcms_ref_v0_99_1/namespacecppcms_1_1widgets.html) для описания специфичных свойств widget'а. |
|
|
|
## Selecting HTML/XHTML |
## Выбор генерации HTML/XHTML |
|
Вы можете запросить генерацию HTML- или XHTML-кода в формах, используя следующую команду: |
|
( 'xhtml' | 'html' ) |
|
Заметьте, эта команда распространяется глобально на весь темплейт не соединяясь с определенным классом. Вы должны включить ее в самый верхний класс Вашего view. |
|
<% c++ #include "all_data.h" %> |
<% xhtml %> |
<% skin %> |
<% view master uses data::master %> |
<% template render() %> |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|
На данный момент, эта опция влияет только на генерацию кода форм. |
|
## Встраивание кода C++ |
|
Вы всегда можете встроить любой C++-код, используя: |
|
"c++" any-c++-statement |
|
Например: |
|
<% c++ #include "all_content.h" %> |
|
__Примечания:__ |
|
1. Если хотите ссылаться в коде на переменные содержимого темплейта, не забудьте использовать `content` член класса. Например: |
|
<% a %> + <% b %> = <% c++ out()<<content.a+content.b; %> |
2. Вообще, использовать С++-код в темплейте нежелательно. Используйте его только в крайней необходимости. |
3. Если необходимо использовать специальные условия, предпочтительнее использовать специальный оператор if, чем `<% c++ if() { %>...<% c++ } %>` |
|