What if a Wiki page doesn’t exist? We’ll take a simple approach: if the page doesn’t exist, you get an edit page to use to create it.
In the default method, we’ll check to see if the page exists. If it doesn’t, we’ll redirect to a new notfound method. We’ll add this method after the index method and before the edit method. Here are the changes we make to the controller:
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 41 42 43 44 45 46 47 48 | """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
from wiki20.model.page import Page
import re
from docutils.core import publish_parts
from sqlalchemy.exceptions import InvalidRequestError
wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)")
class RootController(BaseController):
error = ErrorController()
@expose('wiki20.templates.page')
def default(self, pagename="FrontPage"):
try:
page = DBSession.query(Page).filter_by(pagename=pagename).one()
except InvalidRequestError:
raise tg.redirect("notfound", pagename = pagename)
content = publish_parts(page.data, writer_name="html")["html_body"]
root = tg.url('/')
content = wikiwords.sub(r'<a href="%s\\1">\\1</a>' % root, content)
return dict(content=content, wikipage=page)
@expose(template="wiki20.templates.edit")
def edit(self, pagename):
page = DBSession.query(Page).filter_by(pagename=pagename).one()
return dict(wikipage=page)
@expose('wiki20.templates.about')
def about(self):
return dict(page='about')
@expose()
def save(self, pagename, data, submit):
page = DBSession.query(Page).filter_by(pagename=pagename).one()
page.data = data
redirect("/" + pagename)
@expose("wiki20.templates.edit")
def notfound(self, pagename):
page = Page(pagename=pagename, data="")
DBSession.add(page)
return dict(wikipage=page)
|
19: The default code changes illustrate the “better to beg forgiveness than ask permission” pattern which is favored by most Pythonistas – we first try to get the page and then deal with the exception by redirecting to a method that will make a new page.
38: We’re also leaking a bit of our model into our controller. For a larger project, we might create a facade in the model, but here we’ll favor simplicity. Notice that we can use the redirect() to pass parameters into the destination method.
45: the first two lines of the notfound method add a row to the page table. From there, the path is exactly the same it would be for our edit method.
With these changes in place, we have a fully functional wiki. Give it a try! You should be able to create new pages now.