User:Datagrok/A simple wiki
From DreamHost
Contents |
A little CGI wiki powered mostly by Apache .htaccess directives
Introduction
Yet another wiki/cms thingy. It's small, fast, and simple. If you're a programmer, you can hack on it in your favorite CGI-capable language to add whatever features you like while still keeping the core "let apache do the work" design.
I built this to achieve this combination of features, which I could not find elsewhere:
- Optimized for speed under many reads, few writes.
- All wiki pages are saved as static files and served by apache.
- The only time a script is run is when a page is edited.
- Thus, the only time a database (if any!) is queried (if at all!) is when a page is edited.
- Nice, clean URLs with multi-level heiarchy.
- Wiki pages may exist along side any other content, including HTML authored by other tools, or CGI scripts.
- No dependence on a database.
- No dependence on mod_rewrite.
- Apache does most of the work.
- Apache serves all the flat files.
- Apache provides (somewhat weak) authentication via mod_auth or mod_auth_db.
- Options +MultiViews in .htaccess gives nice clean URLs.
Core idea
- Configure the 404 error page for the wiki-ized folder to point instead to a "create new page" script.
- Thus, links into the wiki will result in a 404 which has a "create this page now" form at the bottom, or a redirect to an editor script.
That's enough for wiki-like functionality. Other features are orthogonal to this design. For my purposes, I'll also add:
- Multiple content types for modular, specialized editors. (Wiki pages, images, etc.)
- History tracked with standard version control tools.
- I like Subversion because I already use it a lot on Dreamhost.
- I might use Mercurial because I think I can "flatten" parts of the history, to completely eliminate any overhead caused by spam.
- I hope to make this modular, so the user may use the VC they like.
- Smart markup using my own twist on Python's reStructuredText/Markdown
But what about...
- Common look-and-feel: Editor script wraps content in template or shtml includes.
- Wrapping in a template would require re-rendering the entire site in the case of template change.
- SSI incurs a small CPU/disk performance hit.
- Dynamic site map: Sitemap data written in JSON to base directory, HTML generated by javascript.
- Care must be taken to make the site still navigable for Google and non-javascript browsers.
Details
/wiki/.htaccess contains:
Options +MultiViews ErrorDocument 404 /wiki/edit/
/wiki/edit/.htaccess contains:
DirectoryIndex editor.py # This is for password-protecting it: AuthUserFile /full/path/to/htpasswd AuthName "web editor" AuthType Basic <Limit POST> require valid-user </Limit>
/wiki/edit/editor.py performs a few tricks with CGI variables to figure out which file to edit:
import os
class Editor(object):
def __init__(self):
e = os.environ.get
self.user = e('REMOTE_USER')
self.host = e('HTTP_HOST')
self.root = e('DOCUMENT_ROOT')
edit_dir, dummy = os.path.split(e('SCRIPT_NAME'))
parent, dummy = os.path.split(edit_dir[1:])
path = None
for prefix in [e('SCRIPT_NAME')+'/', e('REDIRECT_URL'), '/'+parent+'/']:
if e('SCRIPT_URL').startswith(prefix):
path = e('SCRIPT_URL')[len(prefix):]
break
path, file = os.path.split(path)
if not file:
file = "contents"
self.parent = parent
self.path = path
self.file = file
e = Editor()
print 'Content-type:text/plain'
print
print repr((e.root, e.parent, e.path, e.file))
I'm still building this for my purposes, but that should be a good start...