Modifying a MoinMoin Twisted Server to Serve Static Pages
Contents
Background
I have been using MoinMoin as a "web server", which allows me to quickly edit pages using a light mark-up, and it has worked well for both this website and my fctx project.
However, I ran into a bit of stumbling block when I wanted to serve "static web pages" via the built-in Twisted Server. I found I could through the process of using Apache, and figure out re-direction tricks, but I decided: wouldn't be simpler to piggy back on my Twisted server?
The problem is that with a MoinMoin wiki (as with most wikis), the URL becomes the definition of the Wiki Page, so for example, if you where trying to serve out a page called "index.html" in a static directory,
http://www.wildbearsoftware.com/static/index.html
MoinMoin would want to create a wiki page called "static/index.html". Not exactly what I wanted.
The Plan
What follows is one way to approach the problem. I didn't have time to put together a formal patch against the MoinMoin distribution, but I didn't want create some fork of the Twisted Server that they ship, and loose out on future upgrades.
The plan then was to take advantage of Python and import the MoinMoin server, override some key bits, and install it back into the MoinMoin's Twisted module.
What follows isn't pretty, but it works.
Assumptions
I am assuming that you have managed to get a Twisted MoinMoin server up and running. There are plenty of excellent docs on the web that explain how to proceed. Before you begin you should be able to locate your mointwisted.py configuration script. This script is responsible for "setting up the Twisted Server" in the MoinMoin context.
The script we are working with should have a line like class Config(TwistedConfig): in it.
The Steps
Step 1: Import the Twisted Server, but do it a little differently.
You may see a line like,
1 from MoinMoin.server.server_twisted import TwistedConfig, makeApp
Instead replace it with the following,
1 from MoinMoin.server import server_twisted 2 from twisted.web import resource, static
The first import just puts everything back into the server_twisted namespace. The second import grabs some features of Twisted itself for serving "static resources".
Step 2: Save the Twisted Wiki Root.
Add a line like this,
1 MoinWikiRoot = server_twisted.WikiRoot
This saves a reference to the WikiRoot, we will use this reference later as part of our "extending" of the MoinMoin Twisted server.
Step 3: Extend the MoinMoin Twisted Root
Now we create our own root extending the one supplied by MoinMoin.
1 class MyRoot(MoinWikiRoot): 2 def __init__(self, *args): 3 # Initialize the standard MoinMoin Root! 4 MoinWikiRoot.__init__(self, *args) 5 self.putChild("static", static.File("/your/local/htdocs")) 6 7 def getChild(self, name, request): 8 if request.prepath == [] and name == "static": 9 return resource.Resource.getChild(self, name, request) 10 # Extend all other requests to the MoinMoin definition. 11 return MoinWikiRoot.getChild(self, name, request)
Not much to this, what it is saying is that anytime you get a request with "static" in the URL, process it as a static file from the /your/local/htdocs directory. So a URL request,
http://www.wildbearsoftware.com/static/index.html
really translates to /your/local/htdocs/index.html. You will notice that the word "static" helps to differentiate between http://myweb.com/static/index.html and http://myweb.com/other/index.html. In the second case, the other/index.html will still lead to generating a wiki page.
In addition, we are extending the MoinWikiRoot, so any request we don't understand merely moves upwards to the MoinWikiRoot object.
Step 4: Install Your New Twisted Root
Now that you defined a new object, lets "install" it back into the MoinMoin server module. At this point we are clearly abusing Python.
server_twisted.WikiRoot = MyRoot
The idea is that when the MoinMoin server eventual gets around to "booting up", it will call upon its WikiRoot object, which now points to MyRoot, which is our extended version that we built in step 3.
Step 5: Fix the Config Class
Before we mucked with the import statement, this line should have worked,
1 class Config(TwistedConfig):
but now you have to fix it with a call to the module,
1 class Config(server_twisted.TwistedConfig):
Remember we loaded in the module so we can make sure we can "install" our new Modified Twisted Root.
Example
The following web page is served from static files on my Twisted web server,
the key part is the "static" which signals to the Twisted Server to use a different resource for loading the page.
Download
The mointwisted.py file contains the full code. Search for "xxx" to find locations you need to modify in addition to the standard fields for the Moin Twisted Server.
