Submission Deadline: Tuesday February 3, 11:59pm
Submission URL: https://www.crowdgrader.org/crowdgrader/venues/view_venue/768
Review Deadline: Monday February 9, 11:59pm
In this homework, you have to create a simple web2py-powered wiki.
To start, clone the repository at https://bitbucket.org/luca_de_alfaro/slugwiki , using for instance this command in your web2py applications directory:
git clone https://bitbucket.org/luca_de_alfaro/slugwiki
(you can also clone via ssh; the page contains instructions).
It is indispensible for you to clone this repository. There is no way you can do the homework without this code, and if you opt to download the code rather than clone it, you will not be able to easily pull in any changes I may make to the codebase to help you do the homework. And I will do these changes, if not else to prepare the way for homework 4. So please clone it. This code contains many interesting things (you might want to look at my commits, which indicate changes from a standard web2py application). Among other things:
As a second step, I suggest that you create the tables that you will need. You will find placeholders in models/tables.py
. In particular:
pagetable
table (the name table is reserved, sorry), which contains pages. Every page has a title, but actually, not much else is needed, at least in a simple implementation. revision
table, which contains revisions. Each revision must contain the following information (you can also add more information if you find it useful, of course): Most of the wiki page is implemented via the main controller at /default/index. This controller should behave as follows:
request.args(0)
is the title of the page that a user wants to see. If this title is missing, assume it is "main page". request.vars.edit
can be None, in which case the user wants to just view the page, or it can be "y", in which case the user wants to edit the page. You can get the title with
title = request.args(0) or 'main page'
Once you have the title, you need to look for the most recent revision of the page.
{{=represent_wiki(revision_text)}}
, as noted in the main homework page.Whenever you show a page, add a button that allows the user to edit it. The button should lead to a URL created via: URL('default', 'index', args=[title], vars=dict(edit='y')).
If a user clicks on the edit button, then:
request.args(0)
will contain the page title request.vars.edit
, which is normally None, will be 'y'
In this case, you need to read the most recent revision of the page, offer it to the user for editing, and once done, store it as the new most recent revision for that page. Careful! Do not overwrite the current revision of the page with what the user writes, but rather, generate a new most recent revision!
Behind the scenes: how the wiki links are generated
The wiki links to /default/index/title
are generated as follows. When a user enters text like <<cats>>
or <<hot air balloons>>
, these are translated (thanks to function represent_wiki
in tables.py
) into links to /index/default/cats
and /index/default/hot%20air%20balloons
(or something similar to that). When the user clicks on those links, you can get the title via request.args(0)
and display the appropriate page.
Logging might be quite helpful to you to develop the application. To use logging, you need to start web2py from the command line. If you have the source distribution, you can do python web2py.py . Otherwise, you have to run the web2py script. On a Mac, you can do:
cd /Applications/web2py.app/Contents/MacOS/
./web2py
I expect similar methods to work in Windows. To use logging, see this example. The logs are printed on the console (in the window where you started web2py).
Rendering pages. When people access a page, they should be presented with the latest revision of the page.
You should render pages in one of two ways:
wikitext
, and in the view you do: {{=represent_wiki(wikitext)}}
(see tables.py
for how represent_wiki
is defined). db.table.field.represent = represent_content
(again, see tables.py
for the definition of represent_content
). The purpose of this is twofold. First, the wiki links like <<cats>>
are replaced by URLs like /default/index/cats
. Second, the other markup in the page is rendered via MARKMIN (see the web2py book for more information on MARKMIN).
I suggest that you use SQLFORM.factory to create forms that you can customize, as we did in class.
Important: Each time a user enters a page, this should not overwrite the most recent revision of the wiki. Rather, you should create a new revision, with its own timestamp, author, and content, referring to the page being edited.
Here is how you can get the most recent revision for a page with id page_id
:
rev = db(db.revision.page_id == page_id).select(orderby=~db.revision.date_created).first()
(more details here). And here is how you can insert something:
revision_id = db.revision.insert(content=..., author=...)
Here is something for those among you who like a good challenge. In some wikis, links to non-existent pages are rendered differently (in a different color) from links to existent pages. Can you do the same for our slugwiki? You will have to modify create_wiki_links
in tables.py
, and likely add some css, for this to work.
As usual, submit your packed application to CrowdGrader.