Part 1: Getting Started

Getting Started

Apache Allura (incubating) is an open-source platform for hosting software projects. The platform provides a variety of tools for managing a software project: SCM repo tools, a ticket tracker, wiki, blog, discussion forums, and more. These tools are all plugins to the main platform.

Because Allura is pluggable, it's possible to extend the functionality of the platform by creating new plugins. And it's easier than you may think! In this series of blog posts I'll provide a step-by-step guide to Allura plugin development. Let's get started!

Installing Allura

First, you'll need to have Allura itself installed in order to run and test your plugin. If you haven't already set up Allura, the easiest way to get up-and-running is by following our Vagrant Installation Guide. Go do that, then come back. If you'd prefer to install from scratch without using Vagrant, you can follow the guide here.

The Code

In this tutorial we'll be building everything from scratch, but if you'd prefer to just clone the git repo, you can find it here:

$ git clone git://git.code.sf.net/u/vansteenburgh/plugin-tutorial
$ cd plugin-tutorial
$ git checkout part1

Creating the Plugin File Structure

Let's create the initial directory structure for our plugin. During this tutorial we'll be creating a pastebin plugin, so I'll name my folders accordingly:

Pastebin/
    setup.py
    pastebin/
        __init__.py
        app.py
        templates/
            index.html

You can create the Pastebin folder anywhere on the filesystem you'd like. If you're using Vagrant, I recommend creating it in the folder with your 'Vagrantfile' so you can edit on your host machine while still making the files available to the guest machine which is running Allura. Leave the *.(html|py) files empty for now - we'll fill them in as we go.

Creating the Plugin Application

Time to add some code! Edit app.py and add the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/python
from tg import expose

from allura.app import Application
from allura.controllers import BaseController

class Pastebin(Application):
    """Pastebin plugin for the Allura platform"""

    tool_label='Pastebin'
    default_mount_label='Pastebin'
    default_mount_point='pastebin'

    def __init__(self, project, config):
        Application.__init__(self, project, config)
        self.root = PastebinController()

class PastebinController(BaseController):
    """Root controller for the Pastebin Application"""

    @expose('jinja:pastebin:templates/index.html')
    def index(self, **kw):
        return dict(message='Hello from my pastebin!')

Lines 7-16: This is our plugin! We inherit from Application (the base class for all Allura plugins) and then override a few key class and instance attributes.
Line 10: tool_label - name used by the Allura platform when rendering the list of available plugins.
Line 11: default_mount_label - default label used when a new instance of this plugin is installed into an Allura project. This label will be displayed in the project nav bar, and can be changed by a project admin.
Line 12: default_mount_point - the name of this plugin as it will be rendered in a URL; can be overridden when installing a new instance of the plugin in an Allura project.
Lines 14-16: Call the superclass controller, then attach an instance of our root controller. In order for a plugin to handle HTTP requests, it must have a root attribute that is a BaseController instance.
Lines 21-23: The index() method of the root controller handles requests to the 'root' URL of our plugin. More concretely, this code will be called when a user clicks on our plugin in a project nav bar. The returned dict is passed to the @expose()'d template, and the resulting html is returned to the browser.

Creating the Template

Our controller is using a template, so we'd better create that next. Edit index.html and add the following content:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{% extends g.theme.master %}

{% block title %}
{{c.project.name}} / {{c.app.config.options.mount_label}}
{% endblock %}

{% block header %}
Pastebin Home
{% endblock %}

{% block content %}
<p>{{ message }}</p>
{% endblock %}

Line 1: Extend the template provided by Allura's default theme. This master template sets up the main page structure and provides content blocks that we can populate with the content for our plugin.
Lines 3-5: Populate the <title> tag of the page. Every template has access to a global context variable c. When a request is made to a plugin controller, the platform will set c.app and c.project to the plugin instance and the project in which the plugin is installed, respectively.
Lines 7-9: Populate the header block, which is the dark 'page title' area at the top of the main content.
Lines 11-13: Populate the main content block. In this case, we're rendering the message variable returned from our controller.

Building the Plugin

The first simple version of our plugin is done! Before we can see it in action though, we need to register our plugin with the Allura framework. Edit setup.py and copy in the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/bin/python
from setuptools import setup

setup(name='Pastebin',
      version='0.1.0',
      description="Pastebin Allura plugin",
      packages=['pastebin'],
      include_package_data=True,
      zip_safe=True,
      entry_points="""
      # -*- Entry points: -*-
      [allura]
      Pastebin=pastebin.app:Pastebin
      """,
      )

I'll skip over most of the details of setuptools.setup(). The important part is lines 10-14, where we register our package as an Allura plugin. On line 13 we specify that our plugin is the Pastebin class in the pastebin.app module.

Before you run the setup script make sure your Allura virtualenv is active. If you're using the Vagrant environment, you'll want to cd to the directory containing your Vagrantfile, then run:

$ vagrant ssh
$ cd /vagrant/Pastebin
$ python setup.py develop
$ pkill -f "paster serve" # kill the web server if it's running
$ ~/start_allura

Seeing the Results

From your host machine, log in to your running Allura instance at http://localhost (root/foo), then navigate to http://localhost:8080/p/test/admin/tools. You should see the Pastebin plugin in the list of available tools (image). Click on it to install it. Once installed, navigate to the plugin home page by clicking on 'Pastebin' in the project navbar. You should see a page containing the content we created in our root controller template (image).

Next Steps

In Part 2, we'll expand on this simple start by making our plugin do something useful. In the meantime, if you'd like to learn more about the base plugin classes provided by Allura, check out the API docs: http://allura.sourceforge.net/docs/#api-documentation.

Posted by Tim Van Steenburgh 2013-06-24

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks