The LC Framework
This page is about a generic framework — called constrained wiki (or Light Constraints wiki) — that supports wiki communities in establishing guidelines and soft constraints on wiki content, that can be mechanically checked. The overall goal is to help users in respecting such constraints without sacrificing the wiki editing freedom.
Basically, we propose to change as few as possible the usual wiki work-flow, in particular by limiting ourselves to:
- enrich the traditional page viewing, used by random users, with a validation report that fully disclose (non-) adherences to community guidelines;
- turn page saving to a conditional, yet overrodable, step controlled by an intermediate validation process that encourages the submission of “community-correct” content.
Further details about the need of light-constraints and the proposed solution can be found in .
The LC framework does not mandate a specific implementation, but rather shows how it can be easily implemented on top of existing wiki software.
This page contains the source code of a proof-of-concept implementation of the framework that showcases multiple techniques to deploy and code multiple validators and to make them interact with multiple wikis.
The LC Validator Engine
The core of the framework - the validation engine including demo validators - has been implemented in python
and designed as a library internally named
The package (available here
The module engine.py implements the public entry-points to invoke validation services. Two deployments are possible:
- as MoinMoin internal plugin
- as external webservice
The sub-packages formatter
contain modules to
- parse wiki-page
- extract validators declarations from wiki-syntax
- render the validation results according with the markup of the wiki-clone which the lc-framework communicates with.
Both these packages have been designed to be easily extended. Check respectively
for the source code of the Formatter and the API Parser.
The package validator
actually invokes all the validators declared for a given page. Validators are implemented as python modules, in a package named as the wiki-clone they were implemented for. Also the validator
package has been designed to be extensible.
The current implementation includes two demo validators:
- V1: checks the length of a given section in the page. The control is performed by parsing the page source, extracting the required section (whose title is passed as a parameter) and running python string functions.
- V2: checks whether or not a page is compliant to a given template. The validation is performed through regular expression matching on the page source. Further details about templating mechanisms can be found in .
Requirements and dependencies
- python 2.4/.5/.6
xmlrpclib (python library)
SOAPpy (python library)
Using LC with MoinMoin
The LC framework is deliberately independent on the position
of validators and the interaction with the wiki.We have investigated different options for of deployment. Find below install instructions for each of them.
To run an instance of MoinMoin wiki with LC validation engine deployed internally, proceed as follows:
- download moin-1.9.3-lc.tar.gz
- unpack the archive
- execute moin-1.9.3-lc/wikiserver.py python script
- browse http://localhost:8080
All the plugins requested by the wiki to access to the validation functionalities of
are positioned in
and consist of:
directory was added by us and contains
moin.py a wrapper of the lc-framework's public entry-point
We had to patch two MoinMoin core files to implement the conditional-save workflow.
--- moin-1.9.3/MoinMoin/events/__init__.py 2010-06-26 23:46:41.000000000 +0200
+++ moin-1.9.3-lc/MoinMoin/events/__init__.py 2010-06-27 17:49:46.000000000 +0200
@@ -204,6 +204,19 @@
self.new_text = new_text
+ """ Event sent at end phase of save process """
+ """ This can be used to change standard behaviour of wiki at the end of save process
+ For example to propose PageEditor.
+ name = u"PagePostSaveEvent"
+ def __init__(self, request, page_editor):
+ Event.__init__(self, request)
+ self.page_editor = page_editor
""" This is a base class for messages passed from event handlers """
--- moin-1.9.3/MoinMoin/action/edit.py 2010-06-26 23:46:40.000000000 +0200
+++ moin-1.9.3-lc/MoinMoin/action/edit.py 2010-06-27 17:48:37.000000000 +0200
@@ -177,11 +177,18 @@
# msg contains a unicode string
savemsg = unicode(msg)
- # Send new page after save or after unsuccessful conflict merge.
- pg = Page(request, pagename)
+ # patch: ConditionalSave
+ # event to control end phase of save process
+ from MoinMoin.events import send_event,PagePostSaveEvent
+ event = PagePostSaveEvent(request,pg)
+ results = send_event(event)
- # sets revision number to default for further actions
- request.rev = 0
- request.theme.add_msg(savemsg, "info")
+ if not results:
+ # Send new page after save or after unsuccessful conflict merge.
+ pg = Page(request, pagename)
+ # sets revision number to default for further actions
+ request.rev = 0
+ request.theme.add_msg(savemsg, "info")
As you can see from the unified diff outcomes the patches are not very invasive. They produce changes in the order of 20 lines.
External (web-service) deployment
To access to the externally deployed validation-engine, the wiki uses the same Moin plugins mentioned above. The only difference is that the
exposes a webservice and the wiki uses a different validation entry-point.
To do so, edit
file, removing comments on line
#from cowlib.engine import WebService as engine
and run the webservice interface:
for host configuration.
The Ajax deployment requires two plugins:
a graphical theme
xmlrpc plugin which are based on wikiRPC API
To run the lc-framework according with Ajax-based deployment, you need to download
and install a running instance of MoinMoin on your server. If you have problem, please check the installation doc
Once installation is completed:
wikiconfig.py to permit wikirpc connections, adding the following line in the
actions_excluded = 
- install the cow theme
- unpack the archive.
- copy the cow/ and common/ directory to the /wiki/htdocs directory.
- copy the cow.py file to the /wiki/data/plugin/theme directory.
- apply the
PageEditor.py patch just overwriting
--- moin-1.9.3/MoinMoin/PageEditor.py 2010-06-26 23:46:40.000000000 +0200
+++ patch/MoinMoin/PageEditor.py 2010-06-27 19:21:31.000000000 +0200
@@ -372,9 +372,9 @@
-<input class="button" type="submit" name="button_save" value="%s" onClick="flgChange = false;">
-<input class="button" type="submit" name="button_preview" value="%s" onClick="flgChange = false;">
-''' % (save_button_text, _('Preview'), ))
+<input class="button" type="submit" name="button_save" value="%s" onClick="flgChange = false;return conditional_save(this.form.savetext.value,'%s')">
+<input class="button" type="submit" name="button_preview" value="%s" onClick="flgChange = false;return annotated_preview(this.form.savetext.value,'%s')">
+''' % (save_button_text,self.request.page.page_name,_('Preview'), self.request.page.page_name, ))
if not (request.cfg.editor_force and request.cfg.editor_default == 'text'):
Using LC with MediaWiki
Will be available soon.
Here you can download the source code of the proof-of-concept implementation. Find above information about the installation and dependencies.
- cowlib.tar.gz: The Cowlib installation package for either internal or external deployment.
- patch.tar.gz: The MoinMoin patch needed for the Ajax-based deployment.
- Di Iorio A., Zacchiroli S. "Constrained Wiki: an Oxymoron?". In the Proceedings of the ACM Symposyum on Wikis 2006, August, 2006, Odense, Denmark, pp. 89-98.
- Di Iorio A., Vitali, F., Zacchiroli S., "Wiki Content Templating". In the Proceedings of the World Wide Web Conference 2008, Beijing, China, 2008, pp.615-624.
- Set ALLOWTOPICVIEW =
- Set ALLOWTOPICCHANGE =