Writing Training Missions

Training Missions are tools which help people learn the skills needed to contribute to open source projects without burning their fingers. They can be background information (Windows Setup), or more involved (Subversion Training, which creates repositories for each user to work on).

Missions are made up of some Python code ("views"), and some HTML ("templates"). OpenHatch uses some conventions to make developing new training missions as simple as possible.

Note

This document currently covers Simple (non-interactive) Training Missions. We are working to update it to describe interactive missions, as well.

Simple Training Missions

Simple Training Missions provide users with step by step documentation. As an example we'll start a new mission to document how to make missions (how meta!), cunningly named "Make a Mission".

To begin developing a new mission, we need to create two directories: one for the mission code, and one for the mission templates. Both are stored in sub-directories of the OpenHatch repository (oh-mainline; see Getting Started for more information).

To create the new directories:

$ cd oh-mainline/mysite/missions
$ mkdir makeamission
$ mkdir templates/missions/makeamission

The first directory we create is the code directory. The second is the template directory.

It will help other developers work on your code if you use the same name for both directories. Note that we're making directories named makeamission, not "Make a Mission". That's because the directory name needs to be a valid Python package name, which means no spaces or non-alphanumeric characters.

Within the code directory (makeamission), you'll need to create an empty file named __init__.py; this tells Python that this directory is a package. On Mac OS X and Linux, you can do this by running the touch command:

$ touch makeamission/__init__.py

On Windows, just create the file with your favorite (or second favorite) text editor.

Defining Steps

Missions are made up of a sequence of steps: each step has a little bit of Python code and an HTML template.

Note

It may be helpful to refer to existing Mission code as you work on yours: examples are a great way to learn. The Windows Setup mission (in the setup directories) is an especially simple example.

Create a file named views.py in your code directory; we'll start writing the Mission steps there.

The simplest type of Mission Step just renders a template. That's what we'll start with. In views.py, start with the following code:

from mysite.missions.base import MissionBaseView


class StepOne(MissionBaseView):
    url = '/'
    template_name = 'missions/makeamission/index.html'
    view_name = 'main-page'
    title = 'Setting up Your Mission'

This Python code defines the first step in our new Mission. There are a few things to note:

  • StepOne is the name of the step's class. This needs to be unique for your steps in the Mission.
  • MissionBaseView is the basic building block of Mission Steps and provides some helpers you can use in the template.
  • The url defines what the URL of this mission will be within the Mission. This must begin with a /.
  • The view_name (main-page in this case) allows us to refer to this view in other views.
  • The title will be displayed in the sidebar of the Mission.

After you've added the first step, let's add a second step:

class StepTwo(MissionBaseView):
    url = '/templates'
    template_name = 'missions/makeamission/steptwo.html'
    title = 'Writing Mission Templates'

Note that here we've omitted view_name. When it's omitted OpenHatch uses the url setting (omitting the leading /) for the view name.

Step Templates

Each of the Steps we've defined refer to a template: these templates will contain the text content for each step. OpenHatch uses Django templates, which add some logical functionality to plain HTML.

Let's start with the first step, StepOne. In a new file (templates/missions/makeamission/index.html), add the following content:

{% extends 'missions/mission_base.html' %}
{% load base_extras %}

{% block mission_main %}
<div class='submodule fat'>
  <div class='head'>
    <h3>{{ title }}</h3>
  </div>
  <div class="body">

    <p>Real content here, please!</p>

    <p class="next_mission_link">
        <a href="{{ next_step_url }}">Go forward and make a template!</a></p>
  </div>
</div>

{% endblock mission_main %}

There are a few interesting things here:

  • The first line tells OpenHatch that this page should be based on the common Mission template.
  • {{ title }} and {{ next_step_url }} are substitutions: Mission views provide several conveniences so you don't have to repeat yourself. These include title (the step title), next_step_url (the URL of the next step), and prev_step_url (the URL of the previous step).

The template for the second step should be named steptwo.html, which is what you specified in the class (StepTwo) above.

Mission Information

Missions are made up of a sequence of steps, so we need to define what order those steps come in. Missions also have some information of their own, like their name and an identifier.

We'll define the sequence of steps and the metadata by adding the following to our mission's views.py:

class MakeAMission(Mission):

    mission_id = 'make-a-mission'
    name = 'Writing New Missions'

    view_classes = (
        StepOne,
        StepTwo,
    )

We also need to modify the import at the top of that file to read:

from mysite.missions.base import Mission, MissionBaseView

Making it Accessible

The final step to writing your Mission is to make it accessible on the site by telling OpenHatch how to route the URLs. Django projects define URL routing in a file cunningly named urls.py. You can find this in the mysite directory. You can begin by opening urls.py. You'll need to tell it where the file views.py for your new mission lives by adding an import statement near the top of urls.py right after the import statements for the existing training missions like so:

import mysite.missions.makeamission.views

In urls.py, you'll also find a list of URL patterns -- regular expressions which Django will use to match URLs and figure out where to send requests. Finally, add the new mission by adding a new item after the other missions:

(r'^missions/makeamission',
    include(mysite.missions.makeamission.views.MakeAMission.urls())),

Two important things to note:

  • makeamission in the include and import statements above refer to the directory you created, so you'll need to make sure the name matches.
  • MakeAMission is the name you give your Mission class.

Once you've added it to the URLs, you can start the server and visit http://localhost:8000/missions/makeamission/ to see your new mission!