Basic syntax

The web2py template language supports all Python control structures. Here we provide some examples of each of them. They can be nested according to usual programming practice.

for...in

In templates you can loop over any iterable object:

  1. {{items = ['a', 'b', 'c']}}
  2. <ul>
  3. {{for item in items:}}<li>{{=item}}</li>{{pass}}
  4. </ul>

which produces:

  1. <ul>
  2. <li>a</li>
  3. <li>b</li>
  4. <li>c</li>
  5. </ul>

Here items is any iterable object such as a Python list, Python tuple, or Rows object, or any object that is implemented as an iterator. The elements displayed are first serialized and escaped.

while

You can create a loop using the while keyword:

  1. {{k = 3}}
  2. <ul>
  3. {{while k > 0:}}<li>{{=k}}{{k = k - 1}}</li>{{pass}}
  4. </ul>

which produces:

  1. <ul>
  2. <li>3</li>
  3. <li>2</li>
  4. <li>1</li>
  5. </ul>

if...elif...else

You can use conditional clauses:

  1. {{
  2. import random
  3. k = random.randint(0, 100)
  4. }}
  5. <h2>
  6. {{=k}}
  7. {{if k % 2:}}is odd{{else:}}is even{{pass}}
  8. </h2>

which produces:

  1. <h2>
  2. 45 is odd
  3. </h2>

Since it is obvious that else closes the first if block, there is no need for a pass statement, and using one would be incorrect. However, you must explicitly close the else block with a pass.

Recall that in Python “else if” is written elif as in the following example:

  1. {{
  2. import random
  3. k = random.randint(0, 100)
  4. }}
  5. <h2>
  6. {{=k}}
  7. {{if k % 4 == 0:}}is divisible by 4
  8. {{elif k % 2 == 0:}}is even
  9. {{else:}}is odd
  10. {{pass}}
  11. </h2>

It produces:

  1. <h2>
  2. 64 is divisible by 4
  3. </h2>

try...except...else...finally

It is also possible to use try...except statements in views with one caveat. Consider the following example:

  1. {{try:}}
  2. Hello {{= 1 / 0}}
  3. {{except:}}
  4. division by zero
  5. {{else:}}
  6. no division by zero
  7. {{finally:}}
  8. <br />
  9. {{pass}}

It will produce the following output:

  1. Hello division by zero
  2. <br />

This example illustrates that all output generated before an exception occurs is rendered (including output that preceded the exception) inside the try block. “Hello” is written because it precedes the exception.

def...return

The web2py template language allows the developer to define and implement functions that can return any Python object or a text/html string. Here we consider two examples:

  1. {{def itemize1(link): return LI(A(link, _href="http://" + link))}}
  2. <ul>
  3. {{=itemize1('www.google.com')}}
  4. </ul>

produces the following output:

  1. <ul>
  2. <li><a href="http:/www.google.com">www.google.com</a></li>
  3. </ul>

The function itemize1 returns a helper object that is inserted at the location where the function is called.

Consider now the following code:

  1. {{def itemize2(link):}}
  2. <li><a href="http://{{=link}}">{{=link}}</a></li>
  3. {{return}}
  4. <ul>
  5. {{itemize2('www.google.com')}}
  6. </ul>

It produces exactly the same output as above. In this case, the function itemize2 represents a piece of HTML that is going to replace the web2py tag where the function is called. Notice that there is no ‘=’ in front of the call to itemize2, since the function does not return the text, but it writes it directly into the response.

There is one caveat: functions defined inside a view must terminate with a return statement, or the automatic indentation will fail.