Templates: Rendering Commands
Variable
The simplest templates command is showing variable. The syntax is trivial:
NAME
For example, if you want to show a content value message
just write:
<% message %>
It is actually translated to C++ code:
cout<<escape(message);
Where escape
template function is defined as
if parameter is std::string perform HTML escaping and return it. else if parameter is std::tm render it to string else render it using `std::ostringstram`, like cout<<v
Thus, the shown variable can be from any type that can be written to std::ostream
.
Variable with filters
You can add arbitrary filters to the variable you show. The syntax is following:
VARIABLE [ '|' filter [ '|' filter ] ... ]
Where filter
is
[ 'ext' ] NAME [ '(' ( VARIABLE | STRING | NUMBER ) [ ',' ( VARIABLE | STRING | NUMBER ) ] ... ]
Description
If no filters, are given the variable is automatically escaped, but if you provide any filter they are used instead of escaping.
Each variable is actually function call with given parameters, where first parameter is the "filtered" variable and others are filter parameters. For example:
<% birthday | strftime("%d/%m/%Y") %>
Is translated into:
cout<<strftime(content.birthday,"%d/%m/%Y");
Where strftime(std::tm const &date,string format)
is a member function of base_view
class, that every
view class is derived from it.
You can also concatenate filters using pipe symbol:
<% birthday | strftime("%d %m %Y") | urlencode %>
Would be rendered as:
cout<<urlencode(strftime(content.birthday,"%d/%m/%Y"));
You can specify arbitrary external filters that are defined in content
class. For example:
namespace data { struct page { ... virtual string toupper(string const &); ... }; }
Then in template we can specify:
<% class page uses data::page %> <% template render() %> <% message | escape | ext toupper %> <% end %> <% end %>
Note: Under Windows platform, dynamically loaded libraries (dll) do not allow undefined symbols.
Thus, if you want to support Windows, you should create your filters as virtual functions or
callbacks like boost::function<string(string)>
in order to prevent referring to external symbol.
Predefined filters
There is a set of filters predefined for you in base_view
class.
template<typename T> string escape(T const &v)
This filters performs HTML escaping forstd::string
, rendering to string ofstd::tm
or converting to string of any other "ostream writeable" object. This filter is applied by default if no other filters are given.string raw(string s)
Does nothing, returnss
. It is used for bypassing default filter;string intf(int value,string f)
Format integer usingboost::format
. For example:<% n %> in decimal is <% n | intf("%x") %> in hexadecimal.
string strftime(std::tm const &time,string format)
Converttime
to string using strftime(3) function.string data(std::tm const &v)
Same as strftime(v,"%Y-%m-%d") -- display ISO date like, 2008-12-32string time(std:;tm const &v)
Same as strftime(v,"%H:%M"), display 24 hours clock like, 21:00string timesec(std::tm const &v)
Same as strftime(v,"%T"), display 24 hours clock like, 21:59:59string urlencode(string const &s)
Encode strings
for URL.
Internationalization with gettext
Syntax
'gt' STRING [ 'using' using-options ] 'ngt' STRING ',' STRING ',' VARIABLE [ 'using' using-options
Where using-options
is:
display-variable-block [ ',' display-variable-block [ ',' ... ] ]
Where display-variable-block
is any variable is optional filters as described above. For example:
<% 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 %>
Description
gt
-- gettext
translates given string according to locale defined in current worker thread. For example:
<% gt "Press the button" %>
Would be translated as "Press the button" in English locale and "Нажмите кнопку" under Russian locale.
You can specify additional parameters using using
option. You provide a list of comma separated values
as you would display a variable. You can use any other filters as usual. "%1%", "%2%" etc, specify the order of
input variables. It uses boost::format
for such substitutions.
ngt
-- ngettext
translate plural form for given integer. Where first parameter is single form, second plural and the
third should be the variable is used.
Notes:
- When you use
ngt
you encouraged to useusing
syntax, because you should provide an actual number to display. - Exceptions are disables for boost::format in context of
gettext
. So you may provide not matching number of parameters -- this is important for pluralngettext
forms. You may use
<% if rtl %>
or<% if not rtl %>
in order to test direction of text. This is actually equivalent to:<% if (strcmp(gettext("LTR"),"RTL")==0) %>
See
if
statement for further description.
Including other templates
Syntax
'include' IDENTIFIER '(' [ parameter [ ',' parameter ...] ] ')'
Where parameter
is one of VARIABLE, STRING or NUMBER. For example:
<% include title() %> <% include parent::foo() %> <% include bar(x,"test",-1.0) %>
Description
This command allows inclusion of other functions in place. You can include existing implementation in parent templates in order to extend them. For example:
<% class 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 class %> <% class sales uses data::sales extends master %> <% template menu() %> <% include master::menu() %> <li><a href="#3">Orders</a></li> <% end %> <% end %>
The above code extends menu for class sales
with an additional option.
Rendering Forms
Syntax
'form' ('as_p' | 'as_table' | 'as_ul' | 'as_dl' | 'as_space' ) ['no' 'error'] VARIABLE
Render cppcms::form
, widget
or cppcms::widgetset
with selected delimiter. no error
disables rendering of error
marks for invalidated form fields.
'form' 'error' VARIABLE
Render widget error message. Used for custom rendering method for widgets.
'form' 'input' VARIABLE
Render HTML input of given widget. Used for custom rendering of widgets.
Description
Forms are organized as form object or sets of widgets. Each set can be rendered using different delimiters:
as_p
-- use HTML paragraphs.as_table
-- use table. Note:<table>...</table>
tags are not added user should specify them.as_ul
-- as list (using<li>..</li>
).<ul>..</ul>
are not specified.as_dl
-- as definition list.<dl>
tags are not specified,<dt>..</dt>
and<dd>..</dd>
are used.as_space
-- put blanks between elements.
For example:
<table> <% form as_table form.fields %> </table> <p><% form as_space form.submit_buttons %></p>
May be rendered as:
<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>
Usually when certain field is invalid, error message (or '*') is displayed near problematic widget. If you
want provide your own messages at your own position, you may specify no error
and disable automatic error
messages generation.
You may also render each specific widget in form as you want. You can render only its input filed using:
<% form input some_widget %>
You may generate only error message using:
<% form error some_widget %>
Selecting HTML/XHTML
You may request generation HTML or XHTML code in forms using following command:
( 'xhtml' | 'html' )
Note, this command has global effect on all template without connection to specific class. You should include it in the topmost class of your view.
<% c++ #include "all_data.h" %> <% xhtml %> <% namespace vary %> <% class 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">
Currently, this option affects only forms code generation.
Injecting C++ Code
You can always inject any kind of C++ code using:
"c++" any-c++-statement
For example:
<% c++ #include "all_content.h" %>
Notes:
If you want to refer to content variables in your code, do not forget to use
content
member of your class. For example:<% a %> + <% b %> = <% c++ cout<<content.a+content.b; %>
- Generally you should not use C++ code in template, use it if it is absolutely necessary.
- If you want use special conditions prefer specialized if statement over
<% c++ if() { %>...<% c++ } %>