Templates: General Concepts
Basic Structure of CppCMS template file
When we build templates, we put their content in their own namespace. Each namespace corresponds to separate skin. Thus when we build any template we specify its namespace as first level command.
The second level is class. Each class withing this namespace represents certain page that should be rendered.
Each class should implement render()
virtual member function, unless it is already implemented in its parent.
Example:
<% namespace skin1 %> <% class master uses data::master %> <% template render() %> ... <% end template %> <% end class %> <% end namespace %>
All classes may be organized to inheritance hierarchy. For example, we can have following hierarchy for typical blog:
[master] / \ [page] [summary] / \ / \ [post] [info.] [archive] [recent_posts]
Where master
defines general appearance of the page --- theme. page
uses for displaying general page
in blog that can be post
or info
-- information page. On the other hand summary
represents list of recent posts
or archive by category.
Each inherited class may redefine its parent templates that are actually virtual functions.
Syntax
HTML and Controls separation
Template system of CppCMS is bases on HTML pages with injected flow control commands between <% %>
tags.
Each template command starts with <%
and should be closed with %>
in same line.
Each template command should be closed with these "brackets".
For example --- correct code:
<% if not empty Name %> Hello <% Name %> <% else %> Hello Visitor <% end %>
It is incorrect to "merge different commands. For example (incorrect):
Hello <% if not empty name ; name ; else %>Visitor<% end %>
You should not split command on different rows as well. The following is incorrect:
<% if not empty name %> Not empty <% end %>
Symbols inside commands can not include %
or >
. You may include them inside double quotes using C++/C escaping
rules. For example:
<% number | intf("<%04x>") %>
Syntax Description Rules
Describing syntax of template commands is done in following way:
- All keywords will be shown in small caps in single quotes. For example 'namespace'
- NAME is sequence of Latin letters, digits and underscore starting with letter. They represent identifiers
and can be defined by regular expression as:
[a-zA-Z][a-zA-Z0-9_]*
. For exampleskin_1
. - VARIABLE is non-empty sequence of NAMES separated by dot "
.
" or "->
". No blanks are allowed. For example:data->point.x
- STRING is standard C++/C string with standard escape characters like
"Hello \"World\""
. Note: No string concatenation is allowed like"Hello " "World"
that is equivalent of"Hello World"
. - NUMBER is a number -- sequence of digits that may start with
-
and include.
. It can be defined by regular expression:\-?\d+(\.\d*)?
- IDENTIFIER is a sequence of NAME separated with
::
symbol. No blanks are allowed. For example:data::page
- All punctuation symbols are enclosed with single quotes. Like
','
. - Non-mandatory elements are displayed withing rectangular brackets
[]
and mandatory using round brackets()
. Options are separated using|
symbol. There is no limit on blanks between the words.
For example:
'class' NAME 'uses' IDENTIFIER ['extends' NAME]
Means that following definitions are legal:
<% class page uses data::page extends master %> <% class test uses data::test %> <% class test uses data_test %>
And these are not:
<% class 1page uses data::page extends master %> <% class page %> <% class page uses data::page extends other::master %>