Page Layout
Views can extend and include other views in a tree-like structure, as in the following example (an upward arrow means extend, while a downward arrow means include):
- layout.html
header.html index.html sidebar.html footer.html header.html index.html sidebar.html footer.html body.html
In this example, the view "index.html" extends "layout.html" and includes "body.html". "layout.html" includes "header.html", "sidebar.html" and "footer.html".
The root of the tree is what we call a layout view. Just like any other HTML template file, you can edit it using the web2py administrative interface. The file name "layout.html" is just a convention.
Here is a minimalist page that extends the "layout.html" view and includes the "page.html" view:
The extended layout file must contain an {{include}} directive, something like:
1 <html><head><title>Page Title</title></head>
When the view is called, the extended (layout) view is loaded, and the calling view replaces the {{include}} directive inside the layout. Processing continues recursively until all extend and include directives have been processed. The resulting template is then translated into Python code.
extend and include are special template directives, not Python commands.
Layouts are used to encapsulate page commonality (headers, footers, menus), and though they are not mandatory, they will make your application easier to write and maintain. In particular, we suggest writing layouts that take advantage of the following variables that can be set in the controller. Using these well known variables will help make your layouts interchangeable:
1 response.title
2 response.subtitle
3 response.author
4 response.keywords
5 response.description
6 response.flash
7 response.menu
These are all strings and their meaning should be obvious, except for response.menu. The response .menu menu is a list of three-element tuples. The three elements are: the link name, a boolean representing whether the link is active (is the current link), and the URL of the linked page. For example:
1 response.menu = [['Google', False', 'http://www.google.com'],
2 /"'Index', True, URL(r=request, f='index')]]
We also recommend that you use:
in the HTML head, since this will include the jQuery libraries and define some backward-compatible JavaScript functions for special effects and Ajax.
Here is a minimal "layout.html" page based on the preceding recommendations:
1 <1DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.
w3.org/TR/xhtmll/DTD/xhtmll-strict.dtd">
2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang= "en" lang="en">
5 <meta http-equiv="content-type" content= "text/html; charset=utf-8"
6 <meta name="keywords" content="{{=response.keywords}}" />
7 <meta name="description" content="{{=response.description}}" />
8 <meta name="author" content= "{{=response.author}}" />
10 <!-- choose a title or use the application name -- >
11 <title>{{=response.title or request.application)}}</title>
13 <!-- include jQuery and other ajax functions -->
16 <!-- include a style.css file and optional js files -- >
17 <link href= "{{=URL (r=request, c='static', f='style.css')}}"
18 rel= "stylesheet" type= "text/css"/>
23 <div class= "header"> [Here goes the header]</div>
30 {{ = for _name, _active, _link in response .menu:}}
31 <li><a href= "{{=_link}}" class= "{{='active' if _active else '
inactive'}}">{{=_name}}</a></li>
38 <div id= "flash">{{=response.flash or ''}}</div>
40 <!-- here the extending view is included -- >
44 <div class= "footer"> [created by {{=response .author}} with web2py]</
div>
In the layout, it may sometimes be necessary to display variables that are defined in the extending view. This will not be a problem as long as the variables are defined before the "extend" directive. This behavior can be used to extend a layout in more than one place (a standard layout is extended at the point where the {{include}} directive occurs). The idea is to define view functions that generate separate portions of the page (for example: sidebar, maincontent) and render them in different parts of the layout. The view functions are called in the layout at the points we want them rendered.
For example in the following layout:
2 {{include}} <!-- must come before the two blocks below -- >
3 whatever html
5 whatever html
7 whatever html
The functions "maincontent" and "sidebar" are defined in the extending view, although in this example we allowed for the possibility that view does not define "sidebar" function. Here is the corresponding view:
5 <h1>This is the maincontent</h1>
Notice that the functions are defined in HTML (although they can also contain Python code) so that response.write is used to write their content (the functions do not return the content). This is why the layout calls the view function using {{maincontent () }} rather than {{=maincontent () }}.
Average user rating: 5 stars out of 1 votes
Post a comment