Locked History Actions

MoinMoinDev

Moin Moin Development

One of the disappointments that come with MoinMoin is the realization that there is little documentation on how to do MoinMoin development. There is the MoinDev page which includes information about Developer Tools and Coding Standards, but other than that there are no tutorials or "Hello World" type of examples to get one started with. MoinMoin offers several types of extensions one of the most common being macros. This article introduces even the novice Python program an introduction to MoinMoin macro development. There are many resources for learning about python development starting with the Python Language Web site located at http://www.python.org so I’m going to assume at least a rudimentary understanding. Developers coming from other languages shouldn’t have too much difficulty following what is presented here. For the latter just need to keep in mind that Python is a dynamically typed language so you C++, Java and C# developers should be prepared to open your statically typed mind.

Before we jump into code, there are few basics that you'll need to know. These are where/how to deploy a Macro, and some API docs that you'll find handy so you can reference what objects and methods are available to you when developing. A macro is simply a python script that has an entry point call "execute" that is located in the "data/plugin/macro directory within your MoinMoin web site instance. The MoinMoin API docs can be found at here. As of the time of this writing documentation exists for versions 1.5, 1.6 and 1.7.

So let’s begin with our new MoinMoin Macro. First we create a new file in the macro directory, give it a name of FormDemo.py. The first thing we add to the file is an execute method. The method should accept 2 parameters. The first parameter is typically named macro which is an instance of an object of type MoinMoin.Macro. MoinMoin.Macro provides access to a number of object and methods useful for writing your own macro. The second parameter is typically named args and is a tuple containing whatever arguments that were passed from the MoinMoin page from where the macro was involked. (Tuples are just immutable lists.) Here’s what it should look like:def execute(macro, args):    passNotice I’ve given the function no implementation by using the Python keyword “pass”. While you can define your method here I’m going to define a class that will represent our macro as an object. I”ll give my macro class an execute method and have the module function delegate to it. Again, here is what it should look like:

class FormDemo:

    def __init__(self, macro, args):
        self.macro = macro
        self.args = args    
    def execute():

    def execute(macro, args):
        pass


def execut(macro, args):
    return FormDemo(macro, args).execute()

At this point you can see that the class’s init method simply accepts the macro and args parameters from the module’s execute function and stores them as members. In the module’s execute function you can see that an FormDemo instance is created and it’s execute method called. We again have an execute method with no implementation, but we you can now see the basic structure of the design we have begun.

So let's talk about what our macro is going to do. This macro isn't going to do anything useful except demonstrate how to write out some basic HTML to render a form. Submission of the form will simply write some values from the controls on the form itself. You'll be able to use some of the basics introduced here to develop more advanced macros that actually accomplish something.

The macro object has an attribute named formatter. The formatter object has methods to write out various HTML elements however there is no support for writing out forms. That being the case we'll write out raw HTML by using a format string so that we can insert some variable values into it that come from form input.

class FormDemo:
    form = """
<div id=form >
              <form id='debugform'>
                  <input type='text' name='field1'>
                  <input type='submit' value='submit'>
              </form>
              </div>        
    """

Now that we've got a rendering for the page how to we deliver it to the end user? Return it it.

class FormDemo:
    def execute():
        return self.form

Now the last thing we need to do is capture the form data upon submission and write it back to the user to confirm it is received on the server side. We'll out the captured input just above the form. Here's the entire macro file now with everything we've done so far.