The Maiko forum
Advanced
Maiko's templates can be readily modified and enhanced using Python
scripts. The forum can also be made available over the web using
Apache's mod_wsgi
as explained below.
Templates
Maiko uses the SimpleTemplate Engine provided by Bottle, please refer to its manual for details. Below is an overview of its functionality.
Templates and CSS files are stored under maiko/static/
.
The three basic templates maiko requires are CONFIG['topics.tpl']
(topics.tpl
by default),
CONFIG['posts.tpl']
(posts.tpl
by default),
and CONFIG['added_item.tpl']
(added.tpl
by default).
They render the topics list, the list of posts within a given topic, and the submission
status page, respectively.
All the templates are provided with the config
dictionary
(see Settings). In turn, each template receives additional
data as explained below.
The topics.tpl
template is provided with the dictionary check
:
check
['num1']
— the first MAPTCHA number (e.g.two
)['num2']
— the second MAPTCHA number['maptcha']
— a combination of the above two, should be returned as the value ofmaptcha
from the template
and the dictionary topics
with topic_id
as keys, each a dictionary in turn:
topics[topic_id]
['timestamp']
— a float of the topic's creation time (e.g.1388685361.789254
)['type']
— the type of entry (alwaystopic
)['title']
— the title of the topic['ip']
— the author's IP address e.g.127.0.0.1
['author']
— the author's name
If CONFIG['enable_maptcha'] = False
then the values of check
default to {'num1': 0, 'num2': 0, 'maptcha': ''}
.
Also provided is all_topic_ids
, a list from lowest (oldest) to highest (newest) topic ID.
Finally, the integer numbers first
and last
, indicating
the range of topics to display.
The posts.tpl
template is also provided with config
,
check
, first
and last
, but
instead of topics
the posts
dictionary is provided:
posts[post_id]['metadata']
['timestamp']
— a float of the post's creation time['type']
— the type of entry (alwayspost
)['response_to']
— the post it's responding to, if any (e.g.00033
)['ip']
— the author's IP address e.g.127.0.0.1
['author']
— the author's name
posts[post_id]['content']
— the post's sanitized content
and one topic
dictionary:
topic
['timestamp']
— a float of the topic's creation time['type']
— the type of entry (alwaystopic
)['title']
— the title of the topic the post belongs to['topic_id']
— the topic ID e.g.00621
['ip']
— the topic author's IP address e.g.127.0.0.1
['author']
— the topic author's name
Also provided is all_post_ids
, a list from lowest (oldest) to highest (newest) post ID
in that topic. If, for whatever reason, a topic or post metadata is not available, only the timestamp will
be present in the metadata dictionary and set to -1
(the value of content
will be an empty string). This allows for loops over all entries to skip missing entries by checking the timestamp.
The added.tpl
template is only given config
and the following dictionary:
metadata
['timestamp']
— a float of the item's creation time['type']
— eithertopic
orpost
['uri']
— either/
or the topic's path if it's an added post e.g./12345
['ip']
— the author's IP address e.g.127.0.0.1
['author']
— the author's name['title']
— (topics only) the title of the topic['topic_id']
— (topics only) the topic ID e.g.12345
['response_to']
— (posts only) the post being responded to e.g.00412
['post_id']
— (posts only) the post ID e.g.00034
By default each template imports two CSS files: global.css
and
<local>.css
, where <local>
can be topics
, posts
or
added
. All of these, however, can be set via
CONFIG
. Static files are served from the static/
directory. By default file names are restricted to the following RE (regular expression) pattern:
CONFIG['file_re'] = '[^\.]{1,80}\.[^\.]{0,3}[^~]'
Regardless of the above, the following is enforced in-code for file names: cannot start with a dot, contain a filesystem path separator, or have sequential dots anywhere.
Backup, recovery and filesystem permissions
An entire maiko forum can be backed up at any given time (e.g. 12dec2013) as follows:
zip -r -9 maiko.12dec2013.zip forum/
The site can be recovered from backups as so:
unzip maiko.12dec2013.zip
Any other archiving scheme (e.g. tar
) is, of course, acceptable.
Individual areas and/or items may be backed up the same way. Furthermore, the underlying
filesystem permissions and attributes may be leveraged, for example, by changing
directory permissions or the
immutability bit.
Error pages and Unicode
Error 404 (not found), 403 (forbidden) and 500 (server error) are handled by the
template defined by CONFIG['error_tpl']
. The template is
provided, in addition to the CONFIG
dictionary, the
values of code
(the numeric error code string), and details about
the error in details
.
Maiko should be able to handle topics and posts in any language, but
if using the lynx browser make sure to set
the Display character set
to UNICODE (UTF-8)
.
Configuring Apache
If you've followed the tutorial thus far it'd be best to start from a clean slate by unzipping the original download in a new directory to start over.
So far maiko has been running on localhost:9393
using the bottle HTTP server. To replace it with an Apache
server running mod_wsgi the first thing
to do is modify the maiko.wsgi
(inside maiko/
)
to specify the full path in which the maiko root directory resides. For
example, if the maiko
directory
is transferred into /www/wsgi/
it would be necessary to replace
the line sys.path = ['/maiko/'] + sys.path
in
maiko.wsgi
with sys.path = ['/www/wsgi/maiko/'] + sys.path
so that maiko.wsgi
now reads:
import os, sys sys.stdout = sys.stderr sys.path = ['/www/wsgi/maiko/'] + sys.path import bottle import maiko os.chdir(os.path.dirname(__file__)) application = bottle.default_app()
Apache versions and configurations vary considerably, so use
the following as a guideline only. In this scenario Apache
runs as user apache
in group
apache
, and the maiko administrator
is user ninja
in group
ninja
. Initial setup is done by
root
.
Permissions are pre-configured in the zip file, but can be set as follows:
zsh -f chmod 555 /www /www/wsgi /www/wsgi/maiko cd /www/wsgi chmod 500 maiko/static chmod 700 maiko/topics chmod 400 maiko/**/*(.) chmod 500 maiko/maiko.py chown -R ninja:ninja maiko
Assuming the server name is www.example.com
(IP address
93.184.216.119), the following
code can be appended to an httpd.conf
file in order to create
a maiko virtual host server
(remember these are just basic/example configurations to get started,
tested with Apache 2.2.15):
NameVirtualHost 93.184.216.119:80 WSGISocketPrefix run/wsgi <VirtualHost 93.184.216.119:80> ServerName www.example.com DocumentRoot /www/html WSGIDaemonProcess maiko user=ninja group=ninja WSGIScriptAlias / /www/wsgi/maiko/maiko.wsgi WSGIProcessGroup maiko </VirtualHost>
Note that, for extra security, maiko should run outside the apache
DocumentRoot
.
If you already have the NameVirtualHost
and
WSGISocketPrefix
directives it is not necessary
to add them again. Note that NameVirtualHost
is
deprecated in more recent versions of Apache (2.3.11 and greater).
Stopping the bottle server on port 8080 with Ctrl-C
and
starting Apache should now provide maiko access at http://www.example.com. See
the Apache documentation and the
mod_wsgi documentation
for details.
For more information regarding some advanced Apache configuration please see Ukiyoe and Maiko in the ukiyoe manual.
Regarding security and authentication
Maiko has no concept of cookies, sessions or accounts, and tries its best to
sanitize data and thwart XSS attacks. Its main weakness is probably the
simple MAPTCHA, but this can be ameliorated by enabling moderation. Furthermore,
the Apache .htpasswd
mechanism may be used to provide some
means of authentication (which should be done over an encrypted channel).
It is dangerous to upload untrusted templates as these are essentially Python programs.
Paranoid admins might want to
take extra steps such as making all static files and directories outside
topics/
immutable.
Updating maiko
Maiko can be updated by performing the following steps:
- Back up
bottle.py
andmaiko.py
- Stop the web server
- Over-write
bottle.py
andmaiko.py
with the new versions - Start the web server
Previous: Tutorial
Next: Settings