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 [1].
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
cowlib.
The package (available
here) contains:
- conf.py
- engine.py
- formatter
- webservice.py
- validator:
- core.py
- moin:
- fail.py
- succeed.py
- template_check.py
- words_limit.py
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 and
parser 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
cowlib/formatter/moin.py and
cowlib/parser/moin.py 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 [2].
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.
Internal deployment
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
cowlib are positioned in
moin-1.9.3-lc/wiki/data/plugin and consist of:
-
validate.py parser
-
conditional_save.py events
validation directory was added by us and contains
-
cowlib
-
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-lc/MoinMoin/action/edit.py
-
moin-1.9.3-lc/MoinMoin/events/__init__.py
--- 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
+class PagePostSaveEvent(Event):
+ """ 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
+
+
class EventResult:
""" This is a base class for messages passed from event handlers """
pass
--- 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.
- request.reset()
- 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")
- pg.send_page()
+ if not results:
+ # Send new page after save or after unsuccessful conflict merge.
+ request.reset()
+ pg = Page(request, pagename)
+
+ # sets revision number to default for further actions
+ request.rev = 0
+ request.theme.add_msg(savemsg, "info")
+ pg.send_page()
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
cowlib exposes a webservice and the wiki uses a different validation entry-point.
To do so, edit
moin-1.9.3-lib/wiki/data/plugin/validation/moin.py file, removing comments on line
#from cowlib.engine import WebService as engine
and run the webservice interface:
python moin-1.9.3-lib/wiki/data/plugin/validation/cowlib/webservice.py
Check
cowlib/conf.py for host configuration.
Ajax-based deployment
The Ajax deployment requires two plugins:
*
cow a graphical theme
*
validate and
formatter xmlrpc plugin which are based on wikiRPC API
The theme is use to add a JavaScript client on the wiki pages. The JS client interacts with the validation webservice. The wikiRPC plugins provide dispatcher services between the JS client and the webservice.
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:
- edit
wikiconfig.py to permit wikirpc connections, adding the following line in the security section
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 MoinMoin/PageEditor.py to attach JavaScript functions to MoinMoin page editor
--- 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 @@
request.write('''
-<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'):
request.write('''
Using LC with MediaWiki
Will be available soon.
Download
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.
Bibliography
- 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 =
to top