web2pyTM Examples

Simple Examples

Here are some working and complete examples that explain the basic syntax of the framework.
You can click on the web2py keywords (in the highlighted code!) to get documentation.

Example 1

In controller: simple_examples.py
1.
2.
def hello1():
return "Hello World"

If the controller function returns a string, that is the body of the rendered page.
Try it here: hello1

Example 2

In controller: simple_examples.py
1.
2.
def hello2():
return T("Hello World")

The function T() marks strings that need to be translated. Translation dictionaries can be created at /admin/default/design
Try it here: hello2

Example 3

In controller: simple_examples.py
1.
2.
def hello3():
return dict(message=T("Hello World"))
and view: simple_examples/hello3.html
1.
2.
3.
4.
{{extend 'layout.html'}}
<h1>{{=message}}</h1>

If you return a dictionary, the variables defined in the dictionery are visible to the view (template).
Try it here: hello3

Actions can also be be rendered in other formsts like JSON, hello3.json, and XML, hello3.xml

Example 4

In controller: simple_examples.py
1.
2.
3.
def hello4():
response.view='simple_examples/hello3.html'
return dict(message=T("Hello World"))

You can change the view, but the default is /[controller]/[function].html. If the default is not found web2py tries to render the page using the generic.html view.
Try it here: hello4

Example 5

In controller: simple_examples.py
1.
2.
def hello5():
return HTML(BODY(H1(T('Hello World'),_style="color: red;"))).xml() # .xml to serialize

You can also generate HTML using helper objects HTML, BODY, H1, etc. Each of these tags is a class and the views know how to render the corresponding objects. The method .xml() serializes them and produce html/xml code for the page. Each tag, DIV for example, takes three types of arguments:

  • unnamed arguments, they correspond to nested tags
  • named arguments and name starts with '_'. These are mapped blindly into tag attributes and the '_' is removed. attributes without value like "READONLY" can be created with the argument "_readonly=ON".
  • named arguments and name does not start with '_'. They have a special meaning. See "value=" for INPUT, TEXTAREA, SELECT tags later.

Try it here: hello5

Example 6

In controller: simple_examples.py
1.
2.
3.
def hello6():
response.flash=T("Hello World in a flash!")
return dict(message=T("Hello World"))

response.flash allows you to flash a message to the user when the page is returned. Use session.flash instead of response.flash to display a message after redirection. With default layout, you can click on the flash to make it disappear.
Try it here: hello6

Example 7

In controller: simple_examples.py
1.
2.
def status():
return dict(toobar=response.toolbar())

Here we are showing the request, session and response objects using the generic.html template.

Example 8

In controller: simple_examples.py
1.
2.
def redirectme():
redirect(URL('hello3'))

You can do redirect.
Try it here: redirectme

Example 9

In controller: simple_examples.py
1.
2.
def raisehttp():
raise HTTP(400,"internal error")

You can raise HTTP exceptions to return an error page.
Try it here: raisehttp

Example 10

In controller: simple_examples.py
1.
2.
3.
def raiseexception():
1/0
return 'oops'

If an exception occurs (other than HTTP) a ticket is generated and the event is logged for the administrator. These tickets and logs can be accessed, reviewed and deleted at any later time.

Example 11

In controller: simple_examples.py
1.
2.
3.
4.
def servejs():
import gluon.contenttype
response.headers['Content-Type']=gluon.contenttype.contenttype('.js')
return 'alert("This is a Javascript document, it is not supposed to run!");'

You can serve other than HTML pages by changing the contenttype via the response.headers. The gluon.contenttype module can help you figure the type of the file to be served. NOTICE: this is not necessary for static files unless you want to require authorization.
Try it here: servejs

Example 12

In controller: simple_examples.py
1.
2.
def makejson():
return response.json(['foo', {'bar': ('baz', None, 1.0, 2)}])

If you are into Ajax, web2py includes gluon.contrib.simplejson, developed by Bob Ippolito. This module provides a fast and easy way to serve asynchronous content to your Ajax page. gluon.simplesjson.dumps(...) can serialize most Python types into JSON. gluon.contrib.simplejson.loads(...) performs the reverse operation.
Try it here: makejson

New in web2py 1.63: Any normal action returning a dict is automatically serialized in JSON if '.json' is appended to the URL.

Example 13

In controller: simple_examples.py
1.
2.
3.
4.
5.
6.
7.
8.
9.
def makertf():
import gluon.contrib.pyrtf as q
doc=q.Document()
section=q.Section()
doc.Sections.append(section)
section.append('Section Title')
section.append('web2py is great. '*100)
response.headers['Content-Type']='text/rtf'
return q.dumps(doc)

web2py also includes gluon.contrib.pyrtf, developed by Simon Cusack and revised by Grant Edwards. This module allows you to generate Rich Text Format documents including colored formatted text and pictures.
Try it here: makertf

Example 14

In controller: simple_examples.py
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
def rss_aggregator():
import datetime
import gluon.contrib.rss2 as rss2
import gluon.contrib.feedparser as feedparser
d = feedparser.parse("http://rss.slashdot.org/Slashdot/slashdot/to")

rss = rss2.RSS2(title=d.channel.title,
link = d.channel.link,
description = d.channel.description,
lastBuildDate = datetime.datetime.now(),
items = [
rss2.RSSItem(
title = entry.title,
link = entry.link,
description = entry.description,
# guid = rss2.Guid('unkown'),
pubDate = datetime.datetime.now()) for entry in d.entries]
)
response.headers['Content-Type']='application/rss+xml'
return rss2.dumps(rss)

web2py includes gluon.contrib.rss2, developed by Dalke Scientific Software, which generates RSS2 feeds, and gluon.contrib.feedparser, developed by Mark Pilgrim, which collects RSS and ATOM feeds. The above controller collects a slashdot feed and makes new one.
Try it here: rss_aggregator

Example 15

In controller: simple_examples.py
1.
2.
3.
4.
5.
6.
7.
8.
def ajaxwiki():
form=FORM(TEXTAREA(_id='text',_name='text'),
INPUT(_type='button',_value='markmin',
_onclick="ajax('ajaxwiki_onclick',['text'],'html')"))
return dict(form=form,html=DIV(_id='html'))

def ajaxwiki_onclick():
return MARKMIN(request.vars.text).xml()

The markmin wiki markup is described here. web2py also includes gluon.contrib.markdown.WIKI helper (markdown2) which converts WIKI markup to HTML following this syntax. In this example we added a fancy ajax effect.
Try it here: ajaxwiki

Session Examples

Example 16

In controller: session_examples.py
1.
2.
3.
def counter():
session.counter = (sesstion.counter or 0) + 1
return dict(counter=session.counter)
and view: session_examples/counter.html
1.
2.
3.
4.
5.
6.
7.
8.
9.
{{extend 'layout.html'}}
<h1>session counter</h1>

<h2>{{for i in range(counter):}}{{=i}}... {{pass}}</h2>

<a href="{{=URL(r=request)}}">{{=T('click me to count')}}</a>

{{block sidebar}} {{end}}

Click to count. The session.counter is persistent for this user and application. Every applicaiton within the system has its own separate session management.
Try it here: counter

Template Examples

Example 17

In controller: template_examples.py
1.
2.
def variables():
return dict(a=10, b=20)
and view: template_examples/variables.html
1.
2.
3.
4.
5.
{{extend 'layout.html'}}
<h1>Your variables</h1>
<h2>a={{=a}}</h2>
<h2>a={{=b}}</h2>

A view (also known as template) is just an HTML file with {{...}} tags. You can put ANY python code into the tags, no need to indent but you must use pass to close blocks. The view is transformed into a python code and then executed. {{=a}} prints a.xml() or escape(str(a)).
Try it here: variables

Example 18

In controller: template_examples.py
1.
2.
def test_for():
return dict()
and view: template_examples/test_for.html
1.
2.
3.
4.
5.
6.
7.
8.
{{extend 'layout.html'}}
<h1>For loop</h1>

{{for number in ['one','two','three']:}}
<h2>{{=number.capitalize()}}</h2>
{{pass}}

You can do for and while loops.
Try it here: test_for

Example 19

In controller: template_examples.py
1.
2.
def test_if():
return dict()
and view: template_examples/test_if.html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
{{extend 'layout.html'}}
<h1>If statement</h1>

{{a=10}}

{{if a%2==0:}}
<h2>{{=a}} is even</h2>
{{else:}}
<h2>{{=a}} is odd</h2>
{{pass}}

You can do if, elif, else.
Try it here: test_if

Example 20

In controller: template_examples.py
1.
2.
def test_try():
return dict()
and view: template_examples/test_try.html
1.
2.
3.
4.
5.
6.
7.
8.
9.
{{extend 'layout.html'}}
<h1>Try... except</h1>

{{try:}}
<h2>a={{=1/0}}</h2>
{{except:}}
infinity</h2>
{{pass}}

You can do try, except, finally.
Try it here: test_try

Example 21

In controller: template_examples.py
1.
2.
def test_def():
return dict()
and view: template_examples/test_def.html
1.
2.
3.
4.
5.
6.
7.
8.
{{extend 'layout.html'}}
{{def itemlink(name):}}<li>{{=A(name,_href=name)}}</li>{{return}}
<ul>
{{itemlink('http://www.google.com')}}
{{itemlink('http://www.yahoo.com')}}
{{itemlink('http://www.nyt.com')}}
</ul>

You can write functions in HTML too.
Try it here: test_def

Example 22

In controller: template_examples.py
1.
2.
def escape():
return dict(message='<h1>text is escaped</h1>')
and view: template_examples/escape.html
1.
2.
3.
4.
5.
6.
{{extend 'layout.html'}}
<h1>Strings are automatically escaped</h1>

<h2>Message is</h2>
{{=message}}

The argument of {{=...}} is always escaped unless it is an object with a .xml() method such as link, A(...), a FORM(...), a XML(...) block, etc.
Try it here: escape

Example 23

In controller: template_examples.py
1.
2.
def xml():
return dict(message=XML('<h1>text is not escaped</h1>'))
and view: template_examples/xml.html
1.
2.
3.
4.
5.
6.
{{extend 'layout.html'}}
<h1>XML</h1>

<h2>Message is</h2>
{{=message}}

If you do not want to escape the argument of {{=...}} mark it as XML.
Try it here: xml

Example 24

In controller: template_examples.py
1.
2.
def beautify():
dict(message=BEAUTIFY(dict(a=1,b=[2,3,dict(hello='world')])))
and view: template_examples/beautify.html
1.
2.
3.
4.
5.
6.
{{extend 'layout.html'}}
<h1>BEAUTIFY</h1>

<h2>Message is</h2>
{{=message}}

You can use BEAUTIFY to turn lists and dictionaries into organized HTML.
Try it here: beautify

Layout Examples

Example 25

In controller: layout_examples.py
1.
2.
3.
4.
5.
6.
def civilized():
response.menu=[['civilized',True,URL('civilized')],
[
'slick',False,URL('slick')],
[
'basic',False,URL('basic')]]
response.flash='you clicked on civilized'
return dict(message="you clicked on civilized")
and view: layout_examples/civilized.html
1.
2.
3.
4.
{{extend 'layout_examples/layout_civilized.html'}}
<h2>{{=message}}</h2>
<p>{{for i in range