The 20 Minute Wiki by Kevin Dangoor

There is a printable version of this document.

This is the text version of the "20 Minute Wiki" video (40MB QuickTime). (See video help for more information about viewing the videos.)

To go through this tutorial, you'll want:

1. docutils 0.3.9 or later, which is used for formatting. You could get away with not having docutils, but it's not as much fun. easy_install docutils should get you what you need. 2. A web browser 3. Your favorite editor 4. Two command line windows (you only need one, but two is nicer.) 5. A . If you don't have one, your best bet is 3.2+ with pysqlite 2.0+.

This tutorial doesn't cover Python at all. Check the docs section for more coverage of Python. The Quickstart TurboGears has a command line tool with a few features that will be touched upon in this tutorial. The first is "quickstart", which will get us up and running quickly.

tg-admin quickstart

You'll be prompted for the name of the project (this is the pretty name that human beings would appreciate), and the name of the package (this is the less-pretty name that Python will like). For this tutorial, we'll be using these values:

Enter project name: Wiki 20 Enter package name [wiki20]: wiki20 Do you need Identity (usernames/passwords) in this project? [no] no

This creates a few files in a directory tree just below your current directory. Let's go in there and you can take a look around.

cd Wiki-20 Now Serving: Number 1 You may have spotted a file called start-wiki20.py. This is the startup script for the built-in web server. Let's run it!

python start-wiki20.py

Point your browser at http://localhost:8080/, and you'll see a nice little welcome page with the current time. (If you're on a Mac and have Bonjour bookmarks turned on in Safari, you'll see your new server show up there!) That was easy! Easy indeed. And, if you take a look at the code that the quickstart created, you'll see that there isn't much involved in getting up and running. Two interesting things to look at:

wiki20/controllers.py has the code that's generating the welcome page. CherryPy makes things very easy... you just write methods and expose them to the web! TurboGears adds the automatic template processing to go from a dictionary of values to HTML for the browser. wiki20/templates/welcome.kid is the template you view on the welcome screen. Did you notice that it's standard XHTML with some simple namespaced attributes? Very designer-friendly. You can even open it directly in your browser! Let's make a wiki! If you're not familiar with a Wiki, you might want to check out the Wikipedia entry. The whole idea is that it's an easily-editable web content system that makes it trivial to link to pages and create new pages.

TurboGears follows the Model-View-Controller paradigm, as do most web frameworks these days. Kid templates are your view, your CherryPy classes are your controllers and basically any object can be your model. In practice, since we're in a database-driven world, your model objects will be SQLObjects.

Since this is all about pages, why don't we go ahead and set up a place to store our pages. TurboGears quickstart gave us a "model.py" module with enough in it to start creating model classes. Here's our Page class:

view plain | print | ? 1 class Page(SQLObject): 2 pagename = UnicodeCol(alternateID= True , length=30) 3 data = UnicodeCol()

My own personal preference is to work with objects (and not SQL) as much as possible. SQLObject does support creating objects based on the database definition. I prefer to work the other way and create the database definition based on the objects.

For the pagename, we specified alternateID=True, which will guarantee that the column is unique and allow us to easily do searches on pagename. Some require the length to be specified on columns you want indexed, we'll just use the arbitrary length of 30 here.

Continue on to page 2 http://www.turbogears.org/preview/docs/tutorials/wiki20/printable.html 24.08.2006 15:39 Pointing to a database TurboGears has a minimum of required configuration. It does need to know where your database lives. The quickstart creates a couple of simple config files for you.

If you have sqlite installed, you can get started in development without configuring anything (skip the rest of this section).

Since we're working in a development environment and not a production deployment one, edit the "dev.cfg" file. You'll just need to uncomment the sqlobject.dburi line that corresponds to your database and provide the proper connection info.

Restart the web server by hitting control-C and running the startup script again:

python start-wiki20.py Creating the Database Since we've created, in Python code, the schema for our simple database and we've also told TurboGears where to look for the database, we're ready to actually create it.

tg-admin create

The "tg-admin sql" command is a wrapper around SQLObject's sqlobject-admin command. It looks in the config file to figure out where to find the database. Let's display a wiki page! Hard to believe it, but we're already ready to start displaying pages. The first step, is to rename our template. "welcome.kid" just won't do. Rename the template using whatever commands do the trick for your operating system:

cd wiki20/templates mv welcome.kid page.kid cd ../..

Now, let's replace the body of the template with something more reasonable for a wiki page:

view plain | print | ? 1

2 Viewing Page Name Goes Here 3
4 You can return to the FrontPage . 5 6 7
Page text goes here.

Notice that you can open page.kid in your web browser, and it is still perfectly viewable. That placeholder text can really help see a layout before it's put in action!

TurboGears greatly reduces the amount of code you need to write, but it does not eliminate it. Let's add a couple of imports to the top of controllers.py:

view plain | print | ? 1 from wiki20.model import Page 2 from docutils.core import publish_parts

Then, we'll replace the index method with one that:

1. Sets the template to our newly named "page" (line 1) 2. Has a default pagename of "FrontPage" (line 2) 3. Retrieves the page from the database (line 3) 4. Formats the text as HTML (line 4) 5. Deals with unicode properly (always a good habit, on line 5) 6. Returns the data for the template to use (line 6)

view plain | print | ? 1 @expose( "wiki20.templates.page" ) 2 def index (self , pagename= "FrontPage" ): 3 page = Page.byPagename(pagename) 4 content = publish_parts(page.data, writer_name= "html" )[ "html_body" ] 5 return dict (data=content, page=page)

All that in six, very readable lines. The dictionary that we're returning at the end provides the data that populates the template and has other magical powers that we'll see later. The "." at the beginning of the template name says that this name is relative to the controller's package. In other workds, this is referring to the full name of "wiki20.templates.page".

If you get a KeyError on the publish_parts line when you try to access the page, you are using an older version of docutils and should upgrade to the latest.

Previous Page | Continue on to page 3 Let's check out that first page! The code is in place... Point your browser to http://localhost:8080/ and let's see what we've got!

Oh, we've got an error. Since we're in development mode, CherryPy gives us the whole traceback, which is very convenient. The traceback is telling us that we got an SQLObjectNotFound exception. D'oh! We forgot to put a page in the database! Let's do that using CatWalk, the model browser

tg-admin toolbox http://www.turbogears.org/preview/docs/tutorials/wiki20/printable.html 24.08.2006 15:39 A new browser window will open with the TurboGears toolbox. Click on the CatWalk model browser. You'll see "Page" listed on the left. Click on that, select the "Add Page" tab and create a page with the name "FrontPage" and with whatever text you want for the data.

That's all there is to it. We just created a new page in the database.

Reload your browser window, and you'll see our beautiful page. How do we make a better page? One of the hallmarks of wikis is that you can edit the page just by clicking "Edit This Page". That and the wikispam that follows... hopefully, spammers won't find your Wiki 20 before we're done with it!

Let's start by creating a template for editing. Let's start with a copy of "page.kid":

cd wiki20/templates cp page.kid edit.kid cd ../..

In edit.kid, change the text at the top from "Viewing" to "Editing" and replace the

for the data with:

view plain | print | ? 1

2 3