For some strange reason I decided to have a play with the pylons framework this weekend. Seen as I've been playing with django recently I thought it would be cool to see how a different python framework did things. So I check out the pylons website and run through the getting started tutorial. Pretty straight forward tutorial, introduces some of the pylons concepts and worked well.  I moved onto the QuickWiki tutorial and things become troublesome. The tutorial doesn't work, so I did some digging and made some changes. This got it working. It looks like the tutorial hasn't been properly updated since the 1.0 version release.

So below I'm posting the changes I've made to the tutorial code in the hope that it will help someone else.

I'm sure there maybe changes I've missed but most of the changes should be below. I didn't run through the Publishing the Finished Product section of the tutorial so I've no idea what that part is like.

In the "Model" section of the tutorial there seems to be a couple of errors. First off the tutorial tells you to create two classes in the models/__init__.py file, this seems to be wrong. Instead of adding two "Page" classes only add one which inherits from 'Base'. So the single class in models/__init__.py becomes:

models/__init__.py

class Page(Base):
    __tablename__ = 'pages'
    title = Column(Unicode(40), primary_key=True)
    content = Column(UnicodeText(), default=u'')

    def __init__(self, title, content=None):
        self.title = title
        self.content = content

    def get_wiki_content(self):
        content = publish_parts(self.content, writer_name='html',
                                settings_overrides=SAFE_DOCUTILS)['html_body']
        title = sets.Set(wikiwords.findall(content))
        for title in title:
            title_url =  url(controller='pages', action='show', title=title)
            content = content.replacec(title, link_to(title, title_url))
        return content

    def __unicode__(self):
        return self.title

    __str__ = __unicode__

On top of that the tutorial tells you to put the following line orm.mapper(Page, pages_table) at the bottom of the "Page" class, don't it causes issues as page_table hasn't been defined anywhere.

The next set of changes I had to make were to the websetup.py so this now becomes:

websetup.py

import logging

import pylons.test

from quickwiki.config.environment import load_environment
from quickwiki import model
from quickwiki.model.meta import Session, Base

log = logging.getLogger(__name__)

def setup_app(command, conf, vars):
    """Place any commands to setup quickwiki here"""
    load_environment(conf.global_conf, conf.local_conf)

    log.info('Creating tables ...')
    Base.metadata.create_all(bind=Session.bind)
    log.info('Successfully set up')

    log.info('Adding front page data ...')
    page = model.Page(title=u'FrontPage',
                     content=u'**Welcome** to the QuickWiki front page')
    Session.add(page)
    Session.commit()
    log.info('Successfully set up')

Next up was a small error in one line of the lib/helpers.py. One import in the tutorial is:

from webhelpers.html.secure_form import secure_form

it should have been:

from webhelpers.pylonslib.secure_form import secure_form

Within the file controllers/pages.py make sure that you import the render function:

from quickwiki.lib.base import BaseController, render

Also in the same file make sure that in the show function you set c.title, the show function should be:

def show(self, title):
    page = self.page_q.filter_by(title=title).first()
    c.title = title
    if page:
        c.content = page.get_wiki_content()
        return render('/pages/show.mako')
    elif wikiwords.match(title):
        return render('/pages/new.mako')
    abort(404)

You will also need to set c.title for the edit function. Another change is to add the line c.content = '' to the edit function. In the text of the tutorial it says:

We are making use of the fact that the c object returns an empty string

That didn't seem to work for me so I had to make sure that c.content was explicitly set in the edit function.

Changes also need to be made to the save function in controllers/pages.py. As of pylons 1.0 there has been a change that removed the redirect_to function and replaced it with redirect. To quote the 1.0 release notes:

redirect_to processed arguments in a slightly ‘magical’ manner in that some of them went to the url_for while sometimes... not. redirect() issues a redirect and nothing more, so to generate a url, the url instance should be used (import: from pylons import url).

So this means that the last line of the save function changes from:

redirect_to('show_page', title=title)

to

redirect(url('show_page', title=title))

A similar change is needed to the delete function change:

redirect_to('pages')

to

redirect(url('pages'))

And thats the end of my changes :)