aboutsummaryrefslogtreecommitdiffstats
path: root/src/ivicore/doc/src/ivigenerator/template-syntax.qdoc
diff options
context:
space:
mode:
Diffstat (limited to 'src/ivicore/doc/src/ivigenerator/template-syntax.qdoc')
-rw-r--r--src/ivicore/doc/src/ivigenerator/template-syntax.qdoc477
1 files changed, 477 insertions, 0 deletions
diff --git a/src/ivicore/doc/src/ivigenerator/template-syntax.qdoc b/src/ivicore/doc/src/ivigenerator/template-syntax.qdoc
new file mode 100644
index 0000000..96a4b78
--- /dev/null
+++ b/src/ivicore/doc/src/ivigenerator/template-syntax.qdoc
@@ -0,0 +1,477 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Pelagicore AG
+** Copyright (C) 2017 Jinja Team.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+/*
+ NOTE: Some content in this file was copied from the Jinja Template Engine Documentation
+ and from the QFace Documentation
+*/
+/*!
+\page template-syntax.html
+\title Jinja template syntax
+\previouspage QFace IDL syntax
+\nextpage Autogenerator usage
+
+This page is about the Jinja template engine. While the most detailed description of the template
+language can be found at \l {http://jinja.pocoo.org/docs/dev/templates/}{Jinja documentation},
+some basic concepts are given in this article.
+
+
+\section1 Code Generation Principle
+
+The code generation is driven by a small script which iterates over the domain model and writes
+files using the Python Jinja template language.
+
+
+Given that generator script has read and parsed the IDL file into a domain model, this latter one
+is then used as the root object for the code generation inside the template language. Below is an
+example of the code traversing the domain model:
+
+\code
+{% for module in system.modules %}
+ {%- for interface in module.interfaces -%}
+ SERVICE, {{module}}.{{interface}}
+ {% endfor -%}
+ {%- for struct in module.structs -%}
+ STRUCT , {{module}}.{{struct}}
+ {% endfor -%}
+ {%- for enum in module.enums -%}
+ ENUM , {{module}}.{{enum}}
+ {% endfor -%}
+{% endfor %}
+\endcode
+
+The template iterates over the domain objects and generates text which is written into a file.
+
+\section1 Laguage constructs
+\section2 Synopsis
+
+A template contains variables and/or expressions, which get replaced with values when a template
+is rendered; and tags, which control the logic of the template.
+
+There are a few kinds of delimiters. The default Jinja delimiters are configured as follows:
+
+\list
+ \li {% ... %} for Statements
+ \li {{ ... }} for Expressions to print to the template output
+ \li {# ... #} for Comments not included in the template output
+ \li # ... ## for \l {line_statements}{Line Statements}
+\endlist
+
+\section2 Control structures
+
+A control structure refers to all those things that control the flow of a program - conditionals
+(i.e. if/elif/else), for-loops, as well as things like macros and blocks. With the default syntax,
+control structures appear inside {% ... %} blocks.
+
+\section3 For
+
+Loop over each item in a sequence. For example, to display a list of users provided in a variable
+called users:
+
+\code
+<h1>Members</h1>
+<ul>
+{% for user in users %}
+ <li>{{ user.username|e }}</li>
+{% endfor %}
+</ul>
+\endcode
+
+As variables in templates retain their object properties, it is possible to iterate over
+containers like dict:
+
+\code
+<dl>
+{% for key, value in my_dict.iteritems() %}
+ <dt>{{ key|e }}</dt>
+ <dd>{{ value|e }}</dd>
+{% endfor %}
+</dl>
+\endcode
+
+Inside of a for-loop block some special variables are available:
+
+\table
+ \header
+ \li Variable
+ \li Description
+ \row
+ \li loop.index
+ \li The current iteration of the loop. (starting with \e 1)
+ \row
+ \li loop.index0
+ \li The current iteration of the loop. (starting with \e 0)
+ \row
+ \li loop.revindex
+ \li The number of iterations from the end of the loop (starting with \e 1)
+ \row
+ \li loop.revindex0
+ \li The number of iterations from the end of the loop (starting with \e 0)
+ \row
+ \li loop.first
+ \li True if first iteration.
+ \row
+ \li loop.last
+ \li True if last iteration.
+ \row
+ \li loop.length
+ \li The number of items in the sequence.
+\endtable
+
+See for more \l{http://jinja.pocoo.org/docs/2.9/templates/#list-of-control-structures}{Jinja
+documentation}
+
+
+Unlike in Python, it’s not possible to break or continue in a loop. One can, however, filter the
+sequence during iteration, which allows one to skip items. The following example skips all the
+users which are hidden:
+
+\code
+{% for user in users if not user.hidden %}
+ <li>{{ user.username|e }}</li>
+{% endfor %}
+\endcode
+
+The advantage is that the special loop variable will count correctly; thus not counting the users
+not iterated over.
+
+If no iteration took place because the sequence was empty or the filtering removed all the items
+from the sequence, one can render a default block by using else:
+
+\code
+<ul>
+{% for user in users %}
+ <li>{{ user.username|e }}</li>
+{% else %}
+ <li><em>no users found</em></li>
+{% endfor %}
+</ul>
+\endcode
+
+In Python, \e {else} blocks are executed whenever the corresponding loop did not break. Since
+Jinja loops cannot break anyway, a slightly different behavior of the \e {else} keyword was chosen.
+
+It is also possible to use loops recursively. This is useful when dealing with recursive data such
+as sitemaps or RDFa. To use loops recursively, one basically has to add the recursive modifier to
+the loop definition and call the loop variable with the new iterable where recursion is needed.
+
+The following example implements a sitemap with recursive loops:
+
+\code
+<ul class="sitemap">
+{%- for item in sitemap recursive %}
+ <li><a href="{{ item.href|e }}">{{ item.title }}</a>
+ {%- if item.children -%}
+ <ul class="submenu">{{ loop(item.children) }}</ul>
+ {%- endif %}</li>
+{%- endfor %}
+</ul>
+\endcode
+
+The loop variable always refers to the closest (innermost) loop. If we there is more than one
+level of loops, we can rebind the variable loop by writing {% set outer_loop = loop %} after the
+loop that we want to use recursively. Then, we can call it using {{ outer_loop(...) }}
+
+Please note that assignments in loops will be cleared at the end of the iteration and cannot
+outlive the loop scope. Older versions of Jinja2 had a bug where in some circumstances it appeared
+that assignments would work. This is not supported.
+
+\section3 If
+
+The if statement in Jinja is comparable with the Python if statement. In the simplest form, one
+can use it to test if a variable is defined, not empty and not false:
+
+\code
+{% if users %}
+<ul>
+{% for user in users %}
+ <li>{{ user.username|e }}</li>
+{% endfor %}
+</ul>
+{% endif %}
+\endcode
+
+For multiple branches, elif and else can be used like in Python. One can use more complex
+Expressions there, too:
+
+\code
+{% if kenny.sick %}
+ Kenny is sick.
+{% elif kenny.dead %}
+ You killed Kenny! You bastard!!!
+{% else %}
+ Kenny looks okay --- so far
+{% endif %}
+\endcode
+
+\section2 Tests
+Beside filters, there are also so-called “tests” available. Tests can be used to test a variable
+against a common expression. To test a variable or expression, its name is used followed by the
+name of the test. For example, to find out if a variable is defined, one can try \e {name is
+defined}, which will then return true or false depending on whether name is defined in the current
+template context.
+
+Tests can accept arguments, too. If the test only takes one argument, one can leave out the
+parentheses. For example, the following two expressions do the same thing:
+
+\code
+{% if loop.index is divisibleby 3 %}
+{% if loop.index is divisibleby(3) %}
+\endcode
+
+The List of builtin tests can be found on the \l{http://jinja.pocoo.org/docs/2.9/
+templates/#builtin-tests}{Jinja documentation page}.
+\section2 Filters
+
+Variables can be modified by functions called filters. Filters are separated from the variable by
+a pipe symbol (|) and may have optional arguments in parentheses. Multiple filters can be chained.
+The output of one filter is applied to the next.
+
+For example, {{ name|striptags|title }} will remove all HTML Tags from variable name and
+title-case the output (title(striptags(name))).
+
+Filters that accept arguments have parentheses around the arguments, just like a function call.
+For example: \code {{ listx|join(', ') }}\endcode will join a list with commas (equivalent to
+\code str.join(', ', listx)\endcode). Nevertheless, the variable filter is applying to is always
+passed as a first argument to the filter function.
+
+One can define custom filters by registering a Python function as a new filter with the
+Environment object:
+
+\code
+def lower_first_filter(s):
+ s = str(s)
+ return s[0].lower() + s[1:]
+
+
+env = Environment(
+ loader=FileSystemLoader(search_path),
+ trim_blocks=True,
+ lstrip_blocks=True
+ )
+env.filters['lowerfirst'] = lower_first_filter
+\endcode
+
+After that filter called lower first will be available from the template:
+\code
+{{ var | lowerfirst }}
+\endcode
+
+A list of all supported filters can be found in the \l{Filter Reference}.
+
+
+\section2 Variables
+Template variables are defined by the context dictionary passed to the template. Variables can be
+complex object having their own attributes.
+
+One can use a dot (.) to access attributes of a variable in addition to the standard Python
+__getitem__ “subscript” syntax ([]).
+
+The following lines are equivalent:
+
+\code
+{{ foo.bar }}
+{{ foo['bar'] }}
+\endcode
+
+If a variable or attribute does not exist, its value will result to undefined value. The
+interpretation of that kind of value depends on the application configuration: the default
+behavior is to evaluate to an empty string if printed or iterated over, and to fail for every
+other operation.
+
+\section2 Comments
+
+To comment-out part of a line in a template, use the comment syntax which is by default set to {#
+... #}. This is useful to comment out parts of the template for debugging or to add information
+for other template designers or yourself:
+
+\code
+{# note: commented-out template because we no longer use this
+ {% for user in users %}
+ ...
+ {% endfor %}
+#}
+\endcode
+
+\section2 Line Statements
+\target line_statements
+
+If line statements are enabled by the application, it’s possible to mark a line as a statement.
+For example, if the line statement prefix is configured to #, the following two examples are
+equivalent:
+
+\code
+<ul>
+# for item in seq
+ <li>{{ item }}</li>
+# endfor
+</ul>
+\endcode
+
+\code
+<ul>
+{% for item in seq %}
+ <li>{{ item }}</li>
+{% endfor %}
+</ul>
+\endcode
+
+The line statement prefix can appear anywhere on the line as long as no text precedes it. For
+better readability, statements that start a block (such as for, if, elif etc.) may end with a
+colon:
+
+\code
+# for item in seq:
+ ...
+# endfor
+\endcode
+
+Line statements can span multiple lines if there are open parentheses, braces or brackets:
+
+\code
+<ul>
+# for href, caption in [('index.html', 'Index'),
+ ('about.html', 'About')]:
+ <li><a href="{{ href }}">{{ caption }}</a></li>
+# endfor
+</ul>
+\endcode
+
+Since Jinja 2.2, line-based comments are available as well. For example, if the line-comment
+prefix is configured to be ##, everything from ## to the end of the line is ignored (excluding the
+newline sign):
+
+\code
+# for item in seq:
+ <li>{{ item }}</li> ## this comment is ignored
+# endfor
+\endcode
+
+\section2 Assignments
+
+Inside code blocks, you can also assign values to variables. Assignments at top level (outside of
+blocks, macros or loops) are exported from the template like top level macros and can be imported
+by other templates.
+
+Assignments use the set tag and can have multiple targets:
+
+\code
+{% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
+{% set key, value = call_something() %}
+\endcode
+
+It is not possible to set variables inside a block and have them show up outside of it. This also
+applies to loops. The only exception to that rule are if statements which do not introduce a scope.
+
+
+\section2 Whitespace Control
+
+In the default configuration:
+
+\list
+ \li a single trailing newline is stripped if present
+ \li other whitespace (spaces, tabs, newlines etc.) is returned unchanged
+\endlist
+
+If an application configures Jinja to trim_blocks, the first newline after a template tag is
+removed automatically (like in PHP). The lstrip_blocks option can also be set to strip tabs and
+spaces from the beginning of a line to the start of a block. (Nothing will be stripped if there
+are other characters before the start of the block)
+
+With both trim_blocks and lstrip_blocks enabled, you can put block tags on their own lines, and
+the entire block line will be removed when rendered, preserving the whitespace of the contents.
+For example, without the trim_blocks and lstrip_blocks options, this template:
+
+\code
+<div>
+ {% if True %}
+ yay
+ {% endif %}
+</div>
+\endcode
+
+gets rendered with blank lines inside the div:
+
+\code
+<div>
+
+ yay
+
+</div>
+\endcode
+
+But with both trim_blocks and lstrip_blocks enabled, the template block lines are removed and
+other whitespace is preserved:
+
+\code
+<div>
+ yay
+</div>
+\endcode
+
+One can manually disable the lstrip_blocks behavior by putting a plus sign (+) at the start of a
+block:
+
+\code
+<div>
+ {%+ if something %}yay{% endif %}
+</div>
+\endcode
+
+It's also possible to strip whitespace in templates by hand. With a minus sign (-) at the start or
+end of a block (e.g. a For tag), a comment, or a variable expression, the whitespaces before or
+after that block will be removed:
+
+\code
+{% for item in seq -%}
+ {{ item }}
+{%- endfor %}
+\endcode
+
+This will yield all elements without whitespace between them. If seq was a list of numbers from 1
+to 9, the output would be 123456789.
+
+If Line Statements are enabled, they strip leading whitespace automatically up to the beginning of
+the line.
+
+By default, Jinja2 also removes trailing newlines. To keep single trailing newlines, configure
+Jinja to keep_trailing_newline.
+
+\note
+
+One must not add whitespace between the tag and the minus sign.
+
+valid:
+\code
+{%- if foo -%}...{% endif %}
+\endcode
+invalid:
+\code
+{% - if foo - %}...{% endif %}
+\endcode
+
+*/