TurboGears: 20 Minute Wiki, 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 a special version of the Python interactive shell:

    tg-admin shell
    Page(pagename="FrontPage", data="Welcome to my front page")

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 <div> for the data with:

<![CDATA[ <form action="save" method="post"> <input type="hidden" name="pagename" py:attrs="value=pagename"/> <textarea name="data" py:content="data" rows="10" cols="60"/> <input type="submit" name="submit" value="Save"/> </form> ]]>

We need something to use this template now. We'll add an "edit" method to our controller:

<![CDATA[ @turbogears.expose(html="wiki20.templates.edit") def edit(self, pagename): page = Page.byPagename(pagename) return dict(pagename=page.pagename, data=page.data) ]]>

This method is very similar to our index method. The main difference is that the index method renders the wiki content as HTML, and this one returns the straight text.

We need a way to get to our edit method, so we'll edit page.kid to add this to the bottom:

<![CDATA[ <p><a href="$${std.url('/edit', pagename=pagename)}">Edit this page</a></p> ]]>

That should do it! Reload the page in your browser, and you'll see the edit link. Follow that link, and you'll get a page that lets you edit. Don't click that save button, yet! We still need to write that method.

## Saving our edits

The form we made in the last section had an action of "save". So, we need to make a method called save in our controller. Here's what it looks like:

<![CDATA[ @turbogears.expose() def save(self, pagename, data, submit): hub.begin() page = Page.byPagename(pagename) page.data = data hub.commit() hub.end() turbogears.flash("Changes saved!") raise cherrypy.HTTPRedirect(turbogears.url("/", pagename=pagename)) ]]>

We also need to add cherrypy to our imports so that we can do the redirect:

    import cherrypy

Interesting things to note about this:

1. Unlike the previous methods we've made, this one is just exposed without any template specified. That's because we're only redirecting the user back to the viewing page.
2. hub.begin() starts a transaction. We don't have to use transactions, but they're generally a good idea.
3. The "page.data = data" is all it takes to run the UPDATE SQL statement.
4. The turbogears.flash() call is setting a notification message to appear in the user's browser on the next screen. You'll see a reference to the "tg_flash" variable in the master.kid template.
5. Since an HTTPRedirect is raised as an exception, all other processing is short circuited. Very handy!

Go ahead and try it out! You can make changes and save the page we were editing. Pretty wiki-like, no?

Continue on to page 4