Thursday, October 2, 2014

Documenting Django

Sphinx has an extension called sphinx.ext.intersphinx that automatically links to Sphinx documentation elsewhere on the Web. Django poses a few challenges, but reveals some interesting underlying structure of Django's documentation and intersphinx. The SO Q&A: How to link with intersphinx to django-specific constructs (like settings)? has some useful info on this issue.

intersphinx_mapping

As addressed in issue #10315, Django mapping is not stored in an objects.inv file since the Django documentation is itself a django app evidently, so the content of objects.inv is only returned from the URL conf http://docs.djangoproject.com/en/1.6/_objects/. The following intersphinx_mapping conf works:

extensions = ["sphinx.ext.intersphinx"]
intersphinx_mapping = {
    'python': ('http://docs.python.org/2.7', None),
    'django': ('http://docs.djangoproject.com/en/dev/',
               'http://docs.djangoproject.com/en/dev/_objects/'),
}

But what's in Django's objects.inv file? Navigating to http://docs.djangoproject.com/en/dev/_objects/ shows four header lines:

# Sphinx inventory version 2
# Project: Django
# Version: 1.6
# The remainder of this file is compressed using zlib.
followed by a bunch of binary garbage. Save the file as django.inv and after removing the header lines, use Python to decompress the zlib file and write it out as plain text:
>>> import zlib
>>> # django_zlib.inv is django.inv with 1st four header lines removed
>>> with open('django_zlib.inv', 'rb') as f:
>>>     src = zlib.decompress(f.read())
>>> with open('django_txt.inv','w') as f:
>>>     f.write(src)
Opening the plain text file shows the structure given in the data table below. The first column is how you should call the cross reference in your documentation. For example, search for collectstatic and you'll see that you can reference it as :std:djadmin:`collectstatic`. The second column is the directive for the reference, and in some cases a domain as well. Django uses many custom directives and adds them all to the standard domain, std. Therefore you will have to add Django's custom extensions to your document tree. The custom directives are in the docs folder of the Django GitHub repository, in a folder called _ext in a file called djangodocs.py. Choose the tag corresponding to your Django release, e.g.: 1.6.5. Make a folder in your docs tree called _ext and copy djangodocs.py there. Then insert the path to _ext in your conf.py and add djangodocs.py to the list of extensions.

# insert path to _ext
sys.path.append(abspath(join(dirname(__file__), "_ext")))
# add djangodocs extension
extensions = ["djangodocs", "sphinx.ext.intersphinx"]

Inside djangodocs.py you will find the corresponding role to use for each directive. For example, the reference to collectstatic uses the custom django-admin directive, which has a corresponding role of djadmin. Finally the fourth column in the object inventory is the endpoint of the link to the reference in the Django documentation on the Web. Now you can reference collectstatic in your docs using :std:djadmin:`collectstatic`, and it will link to Django. Voila!

You can also link to cross references in external documents that are listed in the object inventory as std:label and have a flag of -1 by using :ref:`prefix:label` or with alternate text as :ref:`alternate text <prefix:label>`. The prefix is the name of the remote documentation. For example, search for django-settings-module and it can be linked using either :ref:`django:django-settings-module` which displays Designating the Settings or :ref:`Django Settings Module <django:django-settings-module>`.

Django-1.6.5 Sphinx Object Inventory

No comments:

Post a Comment

Fork me on GitHub