The index page you see at http://localhost:8080/index is a static web-page. It doesn’t accept any input, and it appears the same every time you call it up. It’s the simplest type of page to code:
wiki20/controllers/root.py contains the code that causes the welcome page at http://localhost:8080/ to be produced.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | """Main Controller"""
from wiki20.lib.base import BaseController
from tg import expose, flash, require, url, request, redirect
from pylons.i18n import ugettext as _, lazy_ugettext as l_
#from tg import redirect, validate
from wiki20.model import DBSession, metadata
from wiki20.controllers.error import ErrorController
class RootController(BaseController):
error = ErrorController()
@expose('wiki20.templates.index')
def index(self):
return dict(page='index')
@expose('wiki20.templates.about')
def about(self):
return dict(page='about')
|
(The numbers preceding items that follow refer to line numbers in the above code.)
9: creates our main controller class by inheriting from TurboGears’ BaseController
12-14, 16-18: The TurboGears 2 controller is a simple object-publishing system; you write controller methods and @expose() them to the web. In our case, there are just two controller methods, index and about.
As you might guess, the name index is not accidental: this becomes the default page your browser views if you go to this URL without specifying a particular destination, just as you end up at index.html on an ordinary web server if you don’t give a specific file name. You’ll also go to this page if you explicitly name it, with http://localhost:8080/index. We’ll see other controller methods later in the tutorial so this naming system will become clear.
12-14: Each controller method returns a dictionary. The @expose() decorator immediately preceding the method (line 10) tells TurboGears to expose the data “returned” by the controller using the template wiki20/templates/index.html — we’ll look at this file shortly. TG takes the key:value pairs in this dictionary {'page': 'index'} and turns them into local variables that can be used in the template.
wiki20/templates/index.html is the template specified by the @expose() decorator, so it formats what you view on the welcome screen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="master.html" />
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type" py:replace="''"/>
<title>Welcome to TurboGears 2.0, standing on the
shoulders of giants, since 2007</title>
</head>
<body>
${sidebar_top()}
<div id="getting_started">
<h2>Presentation</h2>
<p>TurboGears 2 is rapid web application development toolkit designed to make your life easier.</p>
<ol id="getting_started_steps">
<li class="getting_started">
<h3>Code your data model</h3>
<p> Design your data model, Create the database, and Add some bootstrap data.</p>
</li>
<li class="getting_started">
<h3>Design your URL architecture</h3>
<p> Decide your URLs, Program your controller methods, Design your
templates, and place some static files (CSS and/or JavaScript). </p>
</li>
<li class="getting_started">
<h3>Distribute your app</h3>
<p> Test your source, Generate project documents, Build a distribution.</p>
</li>
</ol>
</div>
<div class="clearingdiv" />
<div class="notice"> Thank you for choosing TurboGears.
</div>
</body>
</html>
|
The file is standard XHTML with some simple namespaced attributes. This makes it very designer-friendly, and well-behaved design tools will respect all the Genshi attributes and tags. You can even open it directly in your browser.
Non-essential reading:
The lines you may not be familiar with are
<py: ...> designates a Genshi-defined python statement
current xhtml file of the named file.
This is nothing new. Line 3 occurs in every XHTML file:
xmlns="http://www.w3.org/1999/xhtml"
— the * default* XML namespace declaration for this document, (i.e. any tag without a namespace prefix) is xhtml.
7: xi:include href="master.html" is an XML-include: the file master.html is to be “included” in this file
Genshi directives are elements and/or attributes in the template that are usually prefixed with py:. They can affect how the template is rendered in a number of ways: Genshi provides directives for conditionals and looping, among others. We’ll see some simple Genshi directives in the sections on Editing pages and Adding views.
There is also an about method in wiki20/controllers/root.py, and a corresponding about.html template in wiki20/templates/.
Point your browser to http://localhost:8080/about to see that page rendered:
The content of the about and index pages differs, but you’ll notice a similarity of structure between the two pages: the same header, footer and form of sidebars. This is a common feature of associated web-pages: their content varies, but there is a similar look to them.
Notice how the top sidebar of these two pages varies at the first link:
The file wiki20/templates/master.html is included in both files with the line
<xi:include href="master.html" />
This file in turn includes the files header.html, sidebars.html and footers.html with the lines:
<xi:include href="header.html" />
<xi:include href="sidebars.html" />
<xi:include href="footer.html" />
This ensures that index and about pages have the same header and footer, and similar structure for their sidebars.
index.html and about.html both make an identical call to ${sidebar_top()} - a Python function in wiki20/templates/sidebars.html, lines 5-18:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <html xmlns:py="http://genshi.edgewall.org/"
xmlns:xi="http://www.w3.org/2001/XInclude"
py:strip="">
<py:def function="sidebar_top">
<div id="sb_top" class="sidebar">
<h2>Get Started with TG2</h2>
<ul class="links">
<li py:choose="">
<span py:when="page=='index'"><a href="${tg.url('/about')}">About this page</a> A quick guide to this TG2 site </span>
<span py:otherwise=""><a href="${tg.url('/')}">Home</a> Back to your Quickstart Home page </span>
</li>
<li><a href="http://www.turbogears.org/2.0/docs/">TG2 Documents</a> - Read everything in the Getting Started section</li>
<li><a href="http://docs.turbogears.org/1.0">TG1 docs</a> (still useful, although a lot has changed for TG2) </li>
<li><a href="http://groups.google.com/group/turbogears"> Join the TG Mail List</a> for general TG use/topics </li>
</ul>
</div>
</py:def>
<py:def function="sidebar_bottom">
<div id="sb_bottom" class="sidebar">
<h2>Developing TG2</h2>
<ul class="links">
<li><a href="http://docs.turbogears.org/2.0/RoughDocs/">More TG2 Documents</a> in progress</li>
<li><a href="http://trac.turbogears.org/query?status=new&status=assigned&status=reopened&group=type&milestone=2.0&order=priority">TG2 Trac tickets</a> What's happening now in TG2 development</li>
<li><a href="http://trac.turbogears.org/timeline">TG Dev timeline</a> (recent ticket updates, svn checkins, wiki changes)</li>
<li><a href="http://svn.turbogears.org/trunk">TG2 SVN repository</a> For checking out a copy</li>
<li><a href="http://turbogears.org/2.0/docs/main/Contributing.html#installing-the-development-version-of-turbogears-2-from-source">Follow these instructions</a> For installing your copy</li>
<li><a href="http://trac.turbogears.org/browser/trunk">TG2 Trac's svn view</a> In case you need a quick look</li>
<li><a href="http://groups.google.com/group/turbogears-trunk"> Join the TG-Trunk Mail List</a> for TG2 discuss/dev </li>
</ul>
</div>
</py:def>
</html>
|
The dictionary {'page': 'index'} passed from the index method of wiki20/controllers/root.py to wiki20/templates/index.html is used by sidebar_top() at lines 9-12, to determines that the top sidebar of the index page contains the link About this page, while the about page has a corresponding link Back to your Quickstart Home page.
—
Next, we’ll set up our data model and create a database.