CKAN 2.2.3 documentation » Contributing to CKAN »

Documentation guidelines

This section gives some guidelines to help us to write consistent and good quality documentation for CKAN.

Documentation isn’t source code, and documentation standards don’t need to be followed as rigidly as coding standards do. In the end, some documentation is better than no documentation, it can always be improved later. So the guidelines below are soft rules.

Having said that, we suggest just one hard rule: no new feature (or change to an existing feature) should be missing from the docs (but see todo).

See also

Jacob Kaplon-Moss’s Writing Great Documentation
A series of blog posts about writing technical docs, a lot of our guidelines were based on this.

1. Getting started

This section will walk you through downloading the source files for CKAN’s docs, editing them, and submitting your work to the CKAN project.

CKAN’s documentation is created using Sphinx, which in turn uses Docutils (reStructuredText is part of Docutils). Some useful links to bookmark:

The source files for the docs are in the doc directory of the CKAN git repo. The following sections will walk you through the process of making changes to these source files, and submitting your work to the CKAN project.

a. Install CKAN into a virtualenv

Create a Python virtual environment (virtualenv), activate it, install CKAN into the virtual environment, and install the dependencies necessary for building CKAN. In this example we’ll create a virtualenv in a folder called pyenv. Run these commands in a terminal:

Changed in version 2.1: In CKAN 2.0 and earlier the requirements file was called pip-requirements-docs.txt, not dev-requirements.txt as below.

virtualenv --no-site-packages pyenv
. pyenv/bin/activate
pip install -e 'git+'
pip install -r pyenv/src/ckan/dev-requirements.txt

b. Fetch CKAN’s git submodules

CKAN’s custom Sphinx theme is a kept in a git submodule, so before you can build the docs you have to run these commands in a terminal to download the submodule:

cd pyenv/src/ckan
git submodule init
git submodule update

You may occasionally have to run git submodule update again, when someone updates the theme, but this doesn’t happen often.

c. Build the docs

You should now be able to build the CKAN documentation locally. Make sure your virtual environment is activated, and then run this command:

python build_sphinx

Now you can open the built HTML files in pyenv/src/ckan/build/sphinx/html, e.g.:

firefox pyenv/src/ckan/build/sphinx/html/index.html

d. Edit the reStructuredText files

To make changes to the documentation, use a text editor to edit the .rst files in pyenv/src/ckan/doc/. Save your changes and then build the docs again (python build_sphinx) and open the HTML files in a web browser to preview your changes.

Once your docs are ready to submit to the CKAN project, follow the steps in Making a pull request.

2. Structure and audience

Welcome to CKAN’s Documentation describes the overall structure of the docs, and the intended audience for each part. This structure is intended to be clear, simple and extendable. If you’re adding a new section to the docs, try to fit it into this structure.

Within a particular page, for example a new page documenting a new feature, our suggestion for what sections the page should have is:

  1. Overview: a conceptual overview of or introduction to the feature. Explain what the feature provides, why someone might want to use it, and introduce any key concepts users need to understand. This is the why of the feature.

    If it’s developer documentation (extension writing, theming, API, or core developer docs), maybe put an architecture guide here.

  2. Tutorials: tutorials and examples for how to setup the feature, and how to use the feature. This is the how.

  3. Reference: any reference docs such as config options or API functions.

  4. Troubleshooting: common error messages and problems, FAQs, how to diagnose problems.

3. Style

This section covers things like what tone to use, how to capitalize section titles, etc. Having a consistent style will make the docs nice and easy to read and give them a complete, quality feel.

Use American spelling

Use American spellings everywhere: organization, authorization, realize, customize, initialize, color, etc. There’s a list here:


Please spellcheck documentation before merging it into master!

Commonly used terms

Should be written in ALL-CAPS.
Use email not e-mail.
PostgreSQL, SQLAlchemy, Nginx, Python, SQLite, JavaScript, etc.
These should always be capitalized as shown above (including capital first letters for Python and Nginx even when they’re not the first word in a sentence). doc/ defines substitutions for each of these so you don’t have to remember them, see Substitutions.
Web site
Two words, with Web always capitalized
Not front-end
command line
Two words, not commandline or command-line (this is because we want to be like Neal Stephenson)
CKAN config file or configuration file
Not settings file, ini file, etc. Also, the config file contains config options such as ckan.site_id, and each config option is set to a certain setting or value such as ckan.site_id =

Section titles

Capitalization in section titles should follow the same rules as in normal sentences: you capitalize the first word and any proper nouns.

This seems like the easiest way to do consistent capitalization in section titles because it’s a capitalization rule that we all know already (instead of inventing a new one just for section titles).


  • Installing CKAN from package
  • Getting started
  • Command line interface
  • Writing extensions
  • Making an API request
  • You’re done!
  • Libraries available to extensions


  • Installing CKAN from Package
  • Getting Started
  • Command Line Interface
  • Writing Extensions
  • Making an API Request
  • You’re Done!
  • Libraries Available To Extensions

For lots of examples of this done right, see Django’s table of contents.

In Sphinx, use the following section title styles:

Top-level title

Second-level title

Third-level title

Fourth-level title

If you need more than four levels of headings, you’re probably doing something wrong, but see:

Be conversational

Write in a friendly, conversational and personal tone:

  • Use contractions like don’t, doesn’t, it’s etc.
  • Use “we”, for example “We’ll publish a call for translations to the ckan-dev and ckan-discuss mailing lists, announcing that the new version is ready to be translated” instead of “A call for translations will be published”.
  • Refer to the reader personally as “you”, as if you’re giving verbal instructions to someone in the room: “First, you’ll need to do X. Then, when you’ve done Y, you can start working on Z” (instead of stuff like “First X must be done, and then Y must be done...”).

Write clearly and concretely, not vaguely and abstractly

Politics and the English Language has some good tips about this, including:

  1. Never use a metaphor, simile, or other figure of speech which you are used to seeing in print.
  2. Never use a long word where a short one will do.
  3. If it’s possible to cut out a word, always cut it out.
  4. Never use the passive when you can be active.
  5. Never use a foreign phrase, scientific word or jargon word if you can think of an everyday English equivalent.

This will make your meaning clearer and easier to understand, especially for people whose first language isn’t English.

Facilitate skimming

Readers skim technical documentation trying to quickly find what’s important or what they need, so break walls of text up into small, visually identifiable pieces:

  • Use lots of inline markup:


    For code samples or filenames with variable parts, uses Sphinx’s :samp: and :file: directives.

  • Use lists to break up text.

  • Use .. note:: and .. warning::, see Sphinx’s paragraph-level markup.

    (reStructuredText actually supports lots more of these: attention, error, tip, important, etc. but most Sphinx themes only style note and warning.)

  • Break text into short paragraphs of 5-6 sentences each max.

  • Use section and subsection headers to visualize the structure of a page.

4. Sphinx

This section gives some useful tips about using Sphinx.

Don’t introduce any new Sphinx warnings

When you build the docs, Sphinx prints out warnings about any broken cross-references, syntax errors, etc. We aim not to have any of these warnings, so when adding to or editing the docs make sure your changes don’t introduce any new ones.

It’s best to delete the build directory and completely rebuild the docs, to check for any warnings:

rm -rf build; python build_sphinx

Maximum line length

As with Python code, try to limit all lines to a maximum of 79 characters.


Substitutions are a useful way to define a value that’s needed in many places (eg. a command, the location of a file, etc.) in one place and then reuse it many times.

You define the value once like this:

.. |production.ini| replace:: /etc/ckan/default/production.ini

and then reuse it like this:

Now open your |production.ini| file.

|production.ini| will be replaced with the full value /etc/ckan/default/production.ini.

Substitutions can also be useful for achieving consistent spelling and capitalization of names like reStructuredText, PostgreSQL, Nginx, etc.

The rst_epilog setting in doc/ contains a list of global substitutions that can be used from any file.

Substitutions can’t immediately follow certain characters (with no space in-between) or the substitution won’t work. If this is a problem, you can insert an escaped space, the space won’t show up in the generated output and the substitution will work:

pip install -e 'git+\ |git_url|'

Similarly, certain characters are not allowed to immediately follow a substitution (without a space) or the substitution won’t work. In this case you can just escape the following characters, the escaped character will show up in the output and the substitution will work:

pip install -e 'git+\ |git_url|\#egg=ckan'

Also see Parsed literals below for using substitutions in code blocks.

Parsed literals

Normally things like links and substitutions don’t work within a literal code block. You can make them work by using a parsed-literal block, for example:

Copy your development.ini file to create a new production.ini file::

.. parsed-literal::

   cp |development.ini| |production.ini|


We try to use autodoc to pull documentation from source code docstrings into our Sphinx docs, wherever appropriate. This helps to avoid duplicating documentation and also to keep the documentation closer to the code and therefore more likely to be kept up to date.

Whenever you’re writing reference documentation for modules, classes, functions or methods, exceptions, attributes, etc. you should probably be using autodoc. For example, we use autodoc for the Action API reference, the Plugin interfaces reference, etc.

For how to write docstrings, see Docstrings.


No new feature (or change to an existing feature) should be missing from the docs. It’s best to document new features or changes as you implement them, but if you really need to merge something without docs then at least add a todo directive to mark where docs need to be added or updated (if it’s a new feature, make a new page or section just to contain the todo):

CKAN's Builtin Social Network Feature

.. todo::

   Add docs for CKAN's builtin social network for data hackers.

versionadded and versionchanged

Use Sphinx’s versionadded and versionchanged directives to mark new or changed features. For example:

Tag vocabularies

.. versionadded:: 1.7

CKAN sites can have *tag vocabularies*, which are a way of grouping related
tags together into custom fields.


With versionchanged you usually need to add a sentence explaining what changed (you can also do this with versionadded if you want):


.. versionchanged:: 2.0
   Previous versions of CKAN used a different authorization system.

CKAN's authorization system controls which users are allowed to carry out


Use Sphinx’s deprecated directive to mark things as deprecated in the docs:

.. deprecated:: 3.1
   Use :func:`spam` instead.


Often one page of the docs is related to other pages of the docs or to external pages. A seealso block is a nice way to include a list of related links:

.. seealso::

   :doc:`The DataStore extension <datastore>`
     A CKAN extension for storing data.

   CKAN's `demo site <>`_
     A demo site running the latest CKAN beta version.