home > Basic wiki in 0.3

Basic wiki in 0.3

Basic wiki in Webpy 0.3. Demonstrates basic idea behind wiki. Lacks revisions.

Files

/schema.sql
/wiki.py
/templates:
    /templates/view.html
    /templates/new.html
    /templates/base.html
    /templates/index.html
    /templates/edit.html
/model.py

/schema.sql

CREATE TABLE pages (
    id INT AUTO_INCREMENT,
    url TEXT,
    title TEXT,
    content TEXT,
    primary key (id)
);

/wiki.py

""" Basic wiki using webpy 0.3 """
import web
import model
import markdown

### Url mappings

urls = (
    '/', 'Index',
    '/new', 'New',
    '/edit/(\d+)', 'Edit',
    '/delete/(\d+)', 'Delete',
    '/(.*)', 'Page',
)


### Templates
t_globals = {
    'datestr': web.datestr,
    'markdown': markdown.markdown,
}
render = web.template.render('templates', base='base', globals=t_globals)


class Index:

    def GET(self):
        """ Show page """
        pages = model.get_pages()
        return render.index(pages)


class Page:

    def GET(self, url):
        """ View single page """
        page = model.get_page_by_url(url)
        if not page:
            raise web.seeother('/new?url=%s' % web.websafe(url))
        return render.view(page)


class New:

    def not_page_exists(url):
        return not bool(model.get_page_by_url(url))

    page_exists_validator = web.form.Validator('Page already exists', 
                                not_page_exists)

    form = web.form.Form(
        web.form.Textbox('url', web.form.notnull, page_exists_validator,
            size=30,
            description="Location:"),
        web.form.Textbox('title', web.form.notnull, 
            size=30,
            description="Page title:"),
        web.form.Textarea('content', web.form.notnull, 
            rows=30, cols=80,
            description="Page content:", post="Use markdown syntax"),
        web.form.Button('Create page'),
    )

    def GET(self):
        url = web.input(url='').url
        form = self.form()
        form.fill({'url':url})
        return render.new(form)

    def POST(self):
        form = self.form()
        if not form.validates():
            return render.new(form)
        model.new_page(form.d.url, form.d.title, form.d.content)
        raise web.seeother('/' + form.d.url)


class Delete:

    def POST(self, id):
        model.del_page(int(id))
        raise web.seeother('/')


class Edit:

    form = web.form.Form(
        web.form.Textbox('url', web.form.notnull, 
            size=30,
            description="Location:"),
        web.form.Textbox('title', web.form.notnull, 
            size=30,
            description="Page title:"),
        web.form.Textarea('content', web.form.notnull, 
            rows=30, cols=80,
            description="Page content:", post="Use markdown syntax"),
        web.form.Button('Update page'),
    )

    def GET(self, id):
        page = model.get_page_by_id(int(id))
        form = self.form()
        form.fill(page)
        return render.edit(page, form)


    def POST(self, id):
        form = self.form()
        page = model.get_page_by_id(int(id))
        if not form.validates():
            return render.edit(page, form)
        model.update_page(int(id), form.d.url, form.d.title, form.d.content)
        raise web.seeother('/')


app = web.application(urls, globals())

if __name__ == '__main__':
    app.run()

/templates/view.html

$def with (page)

$var title: $page.title

<h1>$page.title</h1>

$:markdown(page.content)


<a href="/edit/$page.id">Edit</a>

/templates/new.html

$def with (form)


<h1>New Wiki Page</h1>
<form action="" method="post">
$:form.render()
</form>

/templates/base.html

$def with (page)

<html>
<head>
    $if page.has_key('title'):
        <title>$page.title</title>
    $else:
        <title>My Wiki</title>
    <style>
    </style>
</head>
<body>

<ul>
    <li><a href="/">Home</a></li>
    <li><a href="/new">New Page</a></li>
</ul>

$:page

</body>
</html>

/templates/index.html

$def with (pages)

<h1>Webpy Wiki</h1>

<h2>Pages:</h2>

<ul>
$for page in pages:
    <li><a href="/$page.url">$page.url</a></li>

</ul>

/templates/edit.html

$def with (page, form)

<h1>Edit $form.d.title</h1>

<form action="" method="post">
$:form.render()
</form>


<h2>Delete page?</h2>
<form action="/delete/$page.id" method="post">
    <input type="submit" value="Delete page"/>
</form>

/model.py

import web

db = web.database(dbn='mysql', db='wiki', user='justin')

def get_pages():
    return db.select('pages', order='id DESC')

def get_page_by_url(url):
    try:
        return db.select('pages', where='url=$url', vars=locals())[0]
    except IndexError:
        return None

def get_page_by_id(id):
    try:
        return db.select('pages', where='id=$id', vars=locals())[0]
    except IndexError:
        return None

def new_page(url, title, text):
    db.insert('pages', url=url, title=title, content=text)

def del_page(id):
    db.delete('pages', where="id=$id", vars=locals())

def update_page(id, url, title, text):
    db.update('pages', where="id=$id", vars=locals(),
        url=url, title=title, content=text)