Flow Control Statements

The flow control statements allow you to perform check on the variables and select different parts of the template that will be rendered accordingly. You can also use these statements to repeat a piece of the template when generating structures such as tables or lists.

The for ...in loop statement can iterate through these iterable Python objects, returning one element at a time:

<h1>Available products</h1> <ul>

<li>{{ item }}</li> {% endfor %} </ul>

Once in the loop, the following special variables are defined. You can use them to check exactly where you are in the loop.

Table 1-4. The loop property variables




The current iteration of the loop. The index starts with 1; use loop. index0 for a count indexed from 0 .


Similar to loop. index, but counts iterations from the end of the loop.


Set to True if the first iteration.


Set to True if the last iteration.


The total number of elements in the sequence.

The logical test function if is used as a Boolean check, similar to the use of the Python if statement:

<li>{{ item.description }}</li> {% endif %} {% endfor %} </ul> {% else %}

The Jinja2 framework also allows for template inheritance. That is, you can define a base template and then inherit from it. Each child template then redefines the blocks from the main template file with appropriate content. For example, the parent template (parent .tpl) may look like this:

<title> MyCompany - {% block title %}Default title{% endblock %}</title> </head> <html>

{% block content %} There is no content {% endblock %} </html>

The child template then inherits from the base template and extends the blocks with its own content:

Generating Web Site Pages

The script that generates the pages and the images uses the same configuration file used by the check script. It iterates through all system and check sections and builds a dictionary tree. The whole tree is passed to the index generation function, which in turn passes it to the index template.

The detailed information for each check is generated by a separate function. The same function also calls the rrdtool method to plot the graph. All files are saved in the web site root directory, which is defined in the global variable but can be overruled in the function call. You can see the whole script in Listing 1-9.

Listing 1-9. Generating the web site pages #!/usr/bin/env python from jinja2 import Environment, FileSystemLoader from ConfigParser import SafeConfigParser import rrdtool import sys

WEBSITE_ROOT = '/home/rytis/public_html/snmp-monitor/'

def generate_index(systems, env, website_root): template = env.get_template('index.tpl') f = open("%s/index.html" % website_root, 'w') f.write(template.render({'systems': systems})) f.close()

def generate_details(system, env, website_root): template = env.get_template('details.tpl') for check_name, check_obj in system['checks'].iteritems(): rrdtool.graph ("%s/%s.png" % (website_root, check_name), '--title', "%s" % check_obj['description'], "DEF:data=%(name)s.rrd:%(name)s:AVERAGE" % {'name':


'AREA:data#0c0c0c') f = open("%s/%s.html" % (website_root, str(check_name)), 'w') f.write(template.render({'check': check_obj, 'name': check_name})) f.close()

def generate_website(conf_file="", website_root=WEBSITE_ROOT): if not conf_file: sys.exit(-1) config = SafeConfigParser() config.read(conf_file) loader = FileSystemLoader('.') env = Environment(loader=loader) systems = {}

for system in [s for s in config.sections() if s.startswith('system')]:

systems[system] = {'description' 'address' 'port' 'checks'

config.get(system, 'description'), config.get(system, 'address'), config.get(system, 'port'), {}

for check in [c for c in config.sections() if c.startswith('check')]: systems[config.get(check, 'system')]['checks'][check] = {

'description': config.get(check,

generate_index(systems, env, website_root) for system in systems.values():

generate_details(system, env, website_root)


Most of the presentation logic, such as checking whether a variable is defined and iterating through the list items, is implemented in the templates. In Listing 1-10, we first define the index template, which is responsible for generating the contents of the index.html page. As you know, in this page we're going to list all defined systems with a complete list of checks available for each system.

Listing 1-10. The index template

<h1>System checks</h1> {% if systems %}

<h2>{{ systems[system].description }}</h2>

<p>{{ systems[system].address }}:{{ systems[system].port }}</p> {% if systems[system].checks %}

The following checks are available: <ul>

{% for check in systems[system].checks %} <li><a href="{{ check }}.html">

{{ systems[system].checks[check].description }}</a></li> {% endfor %} </ul> {% else %}

There are no checks defined for this system {% endif %} {% endfor %} {% else %}

No system configuration available {% endif %}

The web page generated by this template is rendered as shown in Figure 1-7.

** ^ ^

[TTTj [+]^hctp// C|k ; 0." I llttp:// -f

Was this article helpful?

0 0

Post a comment