Edgewall Software

Changes between Version 4 and Version 5 of GenshiTutorial


Ignore:
Timestamp:
Aug 29, 2007, 12:14:09 PM (17 years ago)
Author:
cmlenz
Comment:

Added basic templating

Legend:

Unmodified
Added
Removed
Modified
  • GenshiTutorial

    v4 v5  
    7575    cherrypy.config.update({
    7676        'request.throw_errors': True,
    77         'tools.encode.on': True,
     77        'tools.encode.on': True, 'tools.encode.encoding': 'utf-8',
    7878        'tools.decode.on': True,
    7979        'tools.trailing_slash.on': True,
     
    103103You should see a log message pointing you to the URL where the application is being served, which is usually http://localhost:8080/. Visiting that page will respond with just the string “Geddit”, as that's what the `index()` method of the `Root` object returns.
    104104
    105 Note that we've configured !CherryPy to serve static files from the `geddit/media` directory. !CherryPy will complain that that directory does not exist, so create it, but leave it empty for now. We'll add static resources later on in the tutorial.
    106 
    107 == Rendering from a Genshi Template ==
     105Note that we've configured !CherryPy to serve static files from the `geddit/static` directory. !CherryPy will complain that that directory does not exist, so create it, but leave it empty for now. We'll add static resources later on in the tutorial.
     106
     107== Basic Template Rendering ==
    108108
    109109So far the code doesn't actually use Genshi, or even any kind of templating. Let's change that.
     110
     111Inside of the `geddit` directory, create a directory called `templates`, and inside that directory create a file called `index.html`, with the following content:
     112
     113{{{
     114#!genshi
     115<html xmlns="http://www.w3.org/1999/xhtml"
     116      xmlns:py="http://genshi.edgewall.org/">
     117  <head>
     118    <title>$title</title>
     119  </head>
     120  <body>
     121    <h1>$title</h1>
     122    <p>Welcome!</p>
     123  </body>
     124</html>
     125}}}
     126
     127This is basically an almost static HTML file with some simple variable substitution.
     128
     129We now need to change the controller code so that this template is used. First, add the Genshi `TemplateLoader` to the imports at the top of the `genshi/controller.py` file, and instantiate a loader for the `geddit/templates` directory:
     130
     131{{{
     132#!python
     133import cherrypy
     134from genshi.template import TemplateLoader
     135from paste.evalexception.middleware import EvalException
     136
     137loader = TemplateLoader(
     138    os.path.join(os.path.dirname(__file__), 'templates'),
     139    auto_reload=True
     140)
     141}}}
     142
     143Next, change the implementation of the `index()` method of the `Root` class to look like this:
     144
     145{{{
     146#!python
     147    @cherrypy.expose
     148    def index(self):
     149        tmpl = loader.load('index.html')
     150        return tmpl.generate(title='Geddit').render('html', doctype='html')
     151}}}
     152
     153This asks the template loader for a template named `index.html`, generates the output stream, and finally serializes the output to HTML. You you now reload the page in your browser, you should get back the following HTML:
     154
     155{{{
     156#!xml
     157<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
     158<html>
     159  <head>
     160    <title>Geddit</title>
     161  </head>
     162  <body>
     163    <h1>Geddit</h1>
     164    <p>Welcome!</p>
     165  </body>
     166</html>
     167}}}
     168
     169== Data Model ==
     170
     171To continue, we'll need to first add some classes to define the data model the application will use. As mentioned above, we're using a simple pickle file for persistence, so all we need to do here is create a couple of very simply Python classes.
     172
     173Inside the `geddit` directory, create a file named `model.py`, with the following content:
     174
     175{{{
     176#!python
     177from datetime import datetime
     178
     179
     180class Submission(object):
     181
     182    def __init__(self, username, url, title):
     183        self.username = username
     184        self.url = url
     185        self.title = title
     186        self.time = datetime.utcnow()
     187        self.comments = []
     188
     189    def add_comment(self, username, content):
     190        self.comments.append(Comment(username, content))
     191
     192
     193class Comment(object):
     194
     195    def __init__(self, username, content, in_reply_to=None):
     196        self.username = username
     197        self.content = content
     198        self.in_reply_to = in_reply_to
     199        self.time = datetime.utcnow()
     200        self.replies = []
     201
     202    def add_reply(self, username, content):
     203        self.replies.append(Comment(username, content, in_reply_to=self))
     204}}}
     205
     206And import those classes in `geddit/controllers.py`, just below the other imports:
     207
     208{{{
     209#!python
     210from geddit.model import Submission, Comment
     211}}}