Templates: Rendering Commands (v 1.x)
Variable
The simplest templates command is showing variable. The syntax is trivial:
'=' VARIABLE
For example, if you want to show a content value message
just write:
<%= message %>
It is actually translated to C++ code:
out()<<cppcms::filters::escape(content.message);
Where escape
function writes the message
member variable
of the content to the stream and escapes special HTML
characters <
, >
, &
, "
with their HTML representations like <
If you want to get a value of some property, you just write.
<%= some_property() %>
Which is translated to:
out()<<cppcms::filters::escape(content.some_property());
Note: since CppCMS 1.1 it is possible to change default filter using filter block.
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 a creation or call of special filter object 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:
out()<<cppcms::filters::strftime(content.birthday,"%d/%m/%Y");
You can also concatenate filters using pipe symbol:
<%= birthday | strftime("%d %m %Y") | urlencode %>
Would be rendered as: out()<<cppcms::filters::urlencode(cppcms::filters::strftime(content.birthday,"%d/%m/%Y"));
There is a set of filters predefined available for you, see cppcms::filters namespace reference.
One of the filters that is worth to noticing is raw
: it allows to write a variable as-is, without any
HTML escaping.
<%= ready_html | raw %>
The ready_html
variable will be written as-is to the output stream without escaping HTML symbols like <
.
You can specify arbitrary external filters that are defined in content
class. For example:
namespace data { struct page { ... virtual string bbcode(string const &); ... }; }
Then in template we can specify:
<% class page uses data::page %> <% template render() %> <%= message | ext bbcode %> <% 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 booster::function<>
in order to prevent referring to external symbol.
Variable - Deprecated Syntax
CppCMS supports older deprecated syntax (without "="):
VARIABLE [ '|' filter [ '|' filter ] ... ]
However it is not recommended due to fact that new template keywords may be introduced that would hide the existing variable and cause syntax error.
Default Escape Filter Block
Since: CppCMS 1.1
Block command filter allows in its current scope to change the default escape filter to a different one:
filter [ ext ] VARIABLE
For example
<p>Hello <%= name %></p> <% filter jsescape %> <script> var name = "<%= name %>"; alert('Hello ' + name); </script> <% end %> <p>You work at <%= job %></p>
First appearance of name
would be escaped using standard HTML escape filter and the second one would allow safely include the text in JavaScript or JSON strings.
Upon end of filter block the filter is reverted to previous thus job
would be escaped again using default HTML filter.
By pre-pending the filter name with ext
it is possible to use a filter defined at content level - custom external filter.
Note: it does not change default urlencode
filter for <% url ... %>
commands
Internationalization
Syntax
'gt' STRING [ 'using' using-options ] 'ngt' STRING ',' STRING ',' VARIABLE [ 'using' using-options ] // since 1.2 'gt' STRING [',' STRING ] [ 'using' using-options ] 'ngt' STRING ',' STRING [',' STRING ] ',' VARIABLE [ 'using' using-options ]
Where using-options
is:
display-variable-block [ ',' display-variable-block [ ',' ... ] ]
Where display-variable-block
is any variable of 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 {1} apples",n using n %>
Description
gt
-- gettext
translates given string according to locale defined in the output stream. 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 booster::locale::format
or cppcms::locale::format
for such substitutions (according to localization backend
CppCMS compiled with.)
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. You may use
<% if rtl %>
or<% if not rtl %>
in order to test direction of text. This is actually equivalent to:<% if (cppcms::locale::gettext("LTR",out().getloc())=="RTL") %>
See
if
statement for further description.
Since 1.2: it is possible to add a context to help the translation as the first element of gt
and ngt
commands:
<% gt "form element", "Use the button" %> <% gt "clothing", "Use the button" %> <% ngt "form element", "there is one button","there are {1} buttons", n using n %> <% ngt "form element", "there is one button","there are {1} buttons", n using n %> <% ngt "closthing", "there is one button","there are {1} buttons", n using n %>
That will show by default "Use the button" in English but may require different translation for different types of buttons one for UI and one for clothing.
URL Mapping
Syntax
'url' STRING [ 'using' using-options ]
Where using-options
is:
display-variable-block [ ',' display-variable-block [ ',' ... ] ]
Where display-variable-block
is any variable of optional filters as described above. For example:
For example:
<% url "/blog/summary" %> <% url "../summary" %> <% url "/blog/post" using post_id %> <% url "/blog/post" using post_id , slug | ext filter_for_url %>
Description
The url
tag is a templates interface to cppcms::url_mapper
interface accessible
from the cppcms::application
This tag allows to access to abstract URLs of the
application with given parameters. To learn how
to use URL mapping read the description of url_mapper
class given above.
The using
parameters are passes for the formatting
of the URL parameters.
Note: unlike the variable rendering the default escaping
for the parameters is urlencode
and not escape
For example
<% url "/blog/post" using slug %><p>Where
slug
is "Hi <you>" would generate something
like</p>
"/myblog/Hi%20%3cyou%3e/"
and not
"/myblog/Hi <you>/"
Including other templates
Syntax
'include' IDENTIFIER '(' [ parameter [ ',' parameter ...] ] ')' [ 'from' IDENTIFIER | 'using' IDENTIFIER [ 'with' VARIABLE ] ]
Where parameter
is one of VARIABLE, STRING or NUMBER. For example:
<% include title() %> <% include parent::foo() %> <% include bar(x,"test",-1.0) from foo %> <% include bar(x,"test",-1.0) using baz %>
Description
This command allows inclusion of other templates in place (actually calling other member functions.) You can include existing implementation in parent views in order to extend them. For example:
<% 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 %>
The above code extends menu for view sales
with an additional option.
The from
option allows to include templates from
locally initialized views withing using
blocks.
For more details read Views Helpers section
Rendering Forms
Syntax
'form' ('as_p' | 'as_table' | 'as_ul' | 'as_dl' | 'as_space' | 'input' | 'block' | 'begin' | 'end' ) VARIABLE
as_*
flags allow you to render cppcms::form
, with
specific delimiters, when input
, begin
, end
and block
flags
allow you to render single part of the widget.
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>
Sometimes you want to perform custom rendering
of widgets that is not predefined by this list.
In such case you may render only <input ...>
field
of the widget by calling
<% form input some_button %>
Which would be rendered like this:
<input type="submit" name="_3" value="Press" />
Note, input
does not strictly means that it is limited
for widgets using HTML input
tag, it works for
any other widget just limited to actual content rendering
without "help" messages, for example, for widget
cppcms::widgets::textarea
it would be <textarea ...>some text</textarea>
Sometimes you need even more fine grained access to widget rendering parts, for example you may want to add some attributes to the widget in the view.
You may render begin
or end
part of the widget, such that you can insert HTML attributes between them or even JavaScript.
<% form begin some_button %> onclick="return foo()" <% form end some_button %>
Which would be rendered as
<input type="submit" name="_3" onclick="return foo()" value="Press" />
Alternatively it can be shortened to
<% form block some_button %> onclick="return foo()" <% end %>
Which is much shorter and more clear syntax that is recommended for the use. It is implemented starting from CppCMS 0.99.12.
For generation of custom HTML for widgets you can always use widget properties directly:
<input type="submit" name="<% button.name() %>" value="Press" /> ( <% button.help() %> )
See: cppcms::widgets
namespace for documentation of
each specific widget properties.
CSRF Prevention
When using forms it is important to prevent an
attempts of CSRF. It is possible by setting
security.csrf.enable
settings value to true
and by including a special CSRF token.
Syntax
'csrf' ['token' | 'cookie' | 'script' ]
Options:
- None - inject the hidden input form that keeps the CSRF token.
token
- inject the token itself rather then input formcookie
- inject the cookie name that keeps the tokenscript
- create a javascript code that injects the input form reading the token from the cookie.
Description
By default <% csrf %>
inject a hidden form input
that contains a session specific token. It is used like
this:
<form method="post" action="/path/to"><% csrf %> <% form as_p my_form %> </form>
It creates a hidden input that keeps this token.
Notes:
- it must be used only on POST forms and never on GET forms as it would disclose the token in the referrer url.
Caching pages the generated token would be invalid as it would be cached for some used and would not be session specific.
In such case it is possible to set security.csrf.exposed settings value to true and it would keep the CSRF token in a special cookie, this cookie value should be used as CSRF token.
The cookie name can be fetched using
cookie
option.It is also possible to inject a short javascript code that would read the cookie and dynamically generate the input form. This way it would be safe to use it with cached pages.
Rendering other views
Implemented in CppCMS 0.99.12
Syntax
'render' [ ( VARIABLE | STRING ) , ] ( VARIABLE | STRING ) [ 'with' VARIABLE ]
- First optional parameter - template name
- Second parameter view name
with
optional parameter content name
Description
This function allows to render different views by their names that can be defined in constant strings or in variables allowing dynamic selection of views/skins.
If the skin name is not provided current skin is used.
The optional parameter is the content that is rendered. If no content given current "this" content is used.
For example:
<% render "sidebar" with sidebar_data %> <% render skin_name, "sidebar" with sidebar_data %>
Views Helpers
Implemented in CppCMS 0.99.12
Syntax
This command is block command that comes in pair with <% end %>
block.
'using' IDENTIFIER [ 'with' VARIABLE ] as IDENTIFIER 'using' IDENTIFIER [ 'with' VARIABLE ] as IDENTIFIER [ 'from' (VARIABLE|STRING) [, (VARIABLE|STRING) ] ] // since 1.2
Description
For example:
<% using foo with some_content as bar %> <% include baz() from bar %> <% include beep(10) from bar %> <% end using %>
The using
block creates local view object bar
of
a type foo
that uses some_content
as the content
for the rendering.
This local object bar
can be accessed using include
command with from
syntax. So technically the example
above is something like (after removing some details)
{ foo bar(content.some_content); bar.baz(); bar.beep(10); }
This is very useful for creating "helper" views that include common routines or patterns.
If with
part is not defined the current content
is used as the content that should be rendered.
If you need to call only a single function of some helper view there is a simple shortcut:
<% include baz() using foo with some_content %>
Which is equivalent to:
<% using foo with some_content as _some_variable %> <% include baz() from _some_variable %> <% end using %>
Since 1.2:
from
part allows to select dynamically a view by name or view by name from certain skin by name. It should be derived from the view specified as first parameter.
For example:
<% using master_api as m from a_skin, "api" %>
Define m
as "api" view defined in skin selected by variable a_skin
. Note "api" should be derived from master_api
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 %> <% 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">
Currently, this option affects only forms code generation.
Selecting localization domain
Since 1.2:
You can select localization domain using following command
domain IDENTIFIER
Note, this command has global effect on all views and is defined globally for all skin.
<% c++ #include "all_data.h" %> <% domain my_domain %> <% skin my_skin %> ...
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++ out()<<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++ } %>