Edgewall Software

Changes between Version 3 and Version 4 of GenshiTutorial

Aug 29, 2007, 11:44:31 AM (15 years ago)

First baby steps


  • GenshiTutorial

    v3 v4  
    1111The application is a stripped-down version of sites such as [http://reddit.com/ reddit] or [http://digg.com/ digg]: it lets users submit links to online articles they find interesting, and then lets other users vote on those stories and post comments.
     13The project is kept as simple as possible, while still showing many of Genshi features and how to best use them:
     14 * For persistence, we'll use native Python object serialization (via the `pickle` module), instead of an SQL database and an ORM.
     15 * There's no authentication of any kind. Anyone can submit links, anyone can comment.
     17== Prerequisites ==
     19First, make sure you have !CherryPy 3.0.x installed, as well as recent versions of [http://formencode.org/ FormEncode], Genshi (obviously), and [http://pythonpaste.org/ Paste]. You can download and install those manually, or just use [http://peak.telecommunity.com/DevCenter/EasyInstall easy_install]:
     22$ easy_install CherryPy
     23$ easy_install FormEncode
     24$ easy_install Genshi
     25$ easy_install Paste
     28== Getting Started ==
     30Next, set up the basic !CherryPy application. Create a directory that should contain the application, and inside that directory create a Python package named `geddit` (basically a `geddit` directory containing an empty file called `__init__.py`. Inside that package, create a file called `controller.py` with the following content:
     34#!/usr/bin/env python
     36import os
     37import pickle
     38import sys
     40import cherrypy
     41from paste.evalexception.middleware import EvalException
     44class Root(object):
     46    def __init__(self, data):
     47        self.data = data
     49    @cherrypy.expose
     50    def index(self):
     51        return 'Geddit'
     54def main(filename):
     55    # load data from the pickle file, or initialize it to an empty list
     56    if os.path.exists(filename):
     57        fileobj = open(filename, 'rb')
     58        try:
     59            data = pickle.load(fileobj)
     60        finally:
     61            fileobj.close()
     62    else:
     63        data = []
     65    # save data back to the pickle file when the server is stopped
     66    def _save_data():
     67        fileobj = open(filename, 'wb')
     68        try:
     69            pickle.dump(data, fileobj)
     70        finally:
     71            fileobj.close()
     72    cherrypy.engine.on_stop_engine_list.append(_save_data)
     74    # Some global configuration; note that this could be moved into a configuration file
     75    cherrypy.config.update({
     76        'request.throw_errors': True,
     77        'tools.encode.on': True,
     78        'tools.decode.on': True,
     79        'tools.trailing_slash.on': True,
     80        'tools.staticdir.root': os.path.abspath(os.path.dirname(__file__)),
     81    })
     83    # Initialize the application, and add EvalException for more helpful error messages
     84    app = cherrypy.Application(Root(data))
     85    app.wsgiapp.pipeline.append(('paste_exc', EvalException))
     86    cherrypy.quickstart(app, '/', {
     87        '/media': {
     88            'tools.staticdir.on': True,
     89            'tools.staticdir.dir': 'static'
     90        }
     91    })
     93if __name__ == '__main__':
     94    main(sys.argv[1])
     97Make that file executable, enter the tutorial directory in the terminal, and run:
     100$ geddit/controller.py geddit.db
     103You 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.
     105Note 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.
     107== Rendering from a Genshi Template ==
     109So far the code doesn't actually use Genshi, or even any kind of templating. Let's change that.