开发者

Sphinx documentation on Django templatetags

I am using Sphinx with autodoc for documenting my Django project.

Design guys want to have documentation page(s) about all the template tags that are defined in the project. Of course, I can make such a page by enumerating all the template processing functions by hand, but I think it is not DRY, 开发者_如何学Goisn't it? In fact, template tag processing functions are all marked with @register.inclusion_tag decorator. So it seems to be possible and natural for some routine to collect them all and put into documentation.

The same about filter functions.

I've googled it, searched Django documentation but in vein. I can hardly believe that such a natural functionality hasn't been implemented by someone.


I didn't stop at this point and implemented a Sphinx autodoc extension.

Snippet 2. Sphinx autodoc extension

"""
    Extension of Sphinx autodoc for Django template tag libraries.

    Usage:
       .. autotaglib:: some.module.templatetags.mod
           (options)

    Most of the `module` autodoc directive flags are supported by `autotaglib`.     

    Andrew "Hatter" Ponomarev, 2010
"""

from sphinx.ext.autodoc import ModuleDocumenter, members_option, members_set_option, bool_option, identity
from sphinx.util.inspect import safe_getattr

from django.template import get_library, InvalidTemplateLibrary

class TaglibDocumenter(ModuleDocumenter):           
    """
    Specialized Documenter subclass for Django taglibs.
    """
    objtype = 'taglib'
    directivetype = 'module'
    content_indent = u''

    option_spec = {
        'members': members_option, 'undoc-members': bool_option,
        'noindex': bool_option,
        'synopsis': identity,
        'platform': identity, 'deprecated': bool_option,
        'member-order': identity, 'exclude-members': members_set_option,
    }

    @classmethod
    def can_document_member(cls, member, membername, isattr, parent):
        # don't document submodules automatically
        return False

    def import_object(self):
        """
        Import the taglibrary.

        Returns True if successful, False if an error occurred.
        """
        # do an ordinary module import      
        if not super(ModuleDocumenter, self).import_object():
            return False        

        try:    
            # ask Django if specified module is a template tags library
            # and - if it is so - get and save Library instance         
            self.taglib = get_library(self.object.__name__)
            return True
        except InvalidTemplateLibrary, e:
            self.taglib = None
            self.directive.warn(unicode(e))

        return False    

    def get_object_members(self, want_all):
        """
        Decide what members of current object must be autodocumented.

        Return `(members_check_module, members)` where `members` is a
        list of `(membername, member)` pairs of the members of *self.object*.

        If *want_all* is True, return all members.  Else, only return those
        members given by *self.options.members* (which may also be none).
        """
        if want_all:
            return True, self.taglib.tags.items()
        else:
            memberlist = self.options.members or []
        ret = []
        for mname in memberlist:
            if mname in taglib.tags:
                ret.append((mname, self.taglib.tags[mname]))
            else:
                self.directive.warn(
                    'missing templatetag mentioned in :members: '
                    'module %s, templatetag %s' % (
                    safe_getattr(self.object, '__name__', '???'), mname))
        return False, ret

def setup(app):
    app.add_autodocumenter(TaglibDocumenter)

This extension defines Sphinx directive autotaglib which behaves much like automodule, but enumerates only tag implementing functions.

Example:

.. autotaglib:: lib.templatetags.bfmarkup
   :members:
   :undoc-members:
   :noindex:


For the record, Django has an automatic documentation system (add django.contrib.admindocs to your INSTALLED_APPS).

This will give you extra views in the admin (usually at /admin/docs/) that represent your models, views (based on the URL), template tags and template filters.

More documentation for this can be found in the admindocs section.

You can take a look at that code to include it in your documentation or at the extensions for the Django documentation.


I solved the problem and would like to share my snippets - in case they will be useful to someone.

Snippet 1. Simple documenter

import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings'

from django.template import get_library

def show_help(libname):
    lib = get_library(libname)
    print lib, ':'
    for tag in lib.tags:
        print tag
        print lib.tags[tag].__doc__


if __name__ == '__main__':
    show_help('lib.templatetags.bfmarkup')

Before running this script you should setup PYTHONPATH environment variable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜