Commits

Benoît Bryon  committed b9c2539

Initialized Sphinx documentation

  • Participants
  • Parent commits f568593

Comments (0)

Files changed (6)

 syntax: glob
 *.pyc
 *.pyo
+docs/_build
 :Copyright: This document is part of the django-menus package. Read LICENSE
             for details.
 
-************
-Introduction
-************
 
-Django-Menus provides tools that help integrate menus in Django-based websites.
-
-When you add a configurable menu system to a website, you usually perform two 
-tasks:
-
-* create tools for the site administrator to manage menu items. Since menus 
-  can be flat or nested, internationalized or in one language only, related to
-  categories, flatpages or other models... this part is often specific to the 
-  project;
-* render menus through templates. Here you may use the same HTML structure and
-  styles for each website.
-
-This application provides:
- 
-* an API that allow developers to connect project specific structure to a 
-  catalog of menu items;
-* template tags and template snippets that help template designers to display 
-  menus.
-
-************
-Installation
-************
-
-Requirements
-============
-
-This application requires:
-
-* `Django-1.1.1`_: the application targets the most recent release of 
-  1.x branch;
-* `Django-TemplateAddOns`_: a set of utilities to create template tags and 
-                            a library of template tags. 
-
-.. _`Django-1.1.1`: http://www.djangoproject.com/
-.. _`Django-TemplateAddOns`: http://bitbucket.org/benoitbryon/django-templateaddons/
-
-Please install and configure these applications *before* this one.
-
-Get the code
-============
-
-The code is published under the BSD license. See LICENSE for details.
-
-The code is available at http://bitbucket.org/benoitbryon/django-menus/
-
-You can get it by running the following commands::
-
-	$ hg clone http://bitbucket.org/benoitbryon/django-menus menus
-
-Put the "menus" folder somewhere in your PYTHON_PATH. 
-
-Django settings
-================
-
-* add 'menus' to your INSTALLED_APPS
-* add 'django.core.context_processors.request' to your 
-  TEMPLATE_CONTEXT_PROCESSORS. This is required to detect which menu is active.
-* add 'menus.context_processors.menus' to your TEMPLATE_CONTEXT_PROCESSORS.
-* Add a MENUS_PROCESSORS setting::
-	
-	MENUS_PROCESSORS = ()
-  
-  Default value is empty tuple. Menus processors are loaded in order. 
-  Notice that a menu processor can override or delete items set by other menu 
-  processors.
-
-*****
-Usage
-*****
-
-Synopsis
-========
-
-In order to work with Django-Menus, you will need to:
-
-* install and configure the Django-Menus application
-* as a developer, set up at least one menu processor
-* as a template designer, use the menus template tag library to display menus
-
-The menus processors will fill a dictionary of menu items, which will be
-made available in templates in a variable named "menus".
-
-Menu processors
-===============
-
-Menu processors are callbacks that build or update the menu registry. They
-are Python callables. They must be declared in the settings.MENUS_PROCESSORS
-list to be active. 
-
-Example: a simple menu processor
---------------------------------
-
-In the following example, we will set up a menu processor which will put 3
-values in the menu catalog and associate them to the "test" key.
-
-First create a file named 'menus_processors.py' at your project root (besides
-settings.py and manage.py), with the following code::
-
-  from menus.models import MenuItem
-
-  def test(request, menus):
-      """
-      This menu processor adds 3 items to the 'test' menu:
-      
-        'test'
-         |__ 'Home'
-         |__ 'Test section'
-              |__ 'Test page'
-      
-      Input "menus" is a menus.loading.MenuRegistry instance.
-      """
-      # get or create root menu item
-      root_menu_item = menus['test']
-      # create items and append it to root
-      menu_item = MenuItem(
-          title='Home',
-          url='/',
-          subtitle='website home page',
-          accesskey='',
-      )
-      root_menu_item.append(menu_item)
-      menu_item = MenuItem(
-          title='Test section',
-          url='/test/',
-          subtitle='Some test section',
-          accesskey='',
-      )
-      sub_menu_item = MenuItem(
-          title='Test page',
-          url='/test/page/',
-          subtitle='Some test page',
-          accesskey='',
-      )
-      menu_item.append(sub_menu_item)
-      root_menu_item.append(menu_item)
-      # update menus
-      menus['test'] = root_menu_item
-      # return updated menus
-      return menus
-
-Add the menu processor to your MENUS_PROCESSORS setting::
-
-  MENUS_PROCESSORS = (
-      'menus_processors.test',
-      # ... other menu processors
-      )
-
-Display the menu in your templates with the following code::
-
-  {% load menus %}
-  {% render_menu_items menu=menus.test name="test" %}
-
-Example: a menu built from some Category model
-----------------------------------------------
-
-Suppose you have a 'category' application that manage categories. You want to 
-build a menu with all categories. The corresponding model is named Category.
-
-First create a file named 'menus_processors.py' in the category app directory
-(assume "categories/menus_processors.py").
-
-Then, in menus_processors.py, write a callback to convert a Category instance 
-into a MenuItem::
-
-  from menus.models import MenuItem
-  from categories.models import Category
-  
-  def category_to_menu_item(category):
-      """
-      Converts a Category instance into a MenuItem instance.
-      Here, assume that categories are not nested, so a menu item has no
-      children.
-      """
-      return MenuItem(
-          title=category.title,
-          url=category.get_absolute_url(),
-          subtitle=category.subtitle,
-      )
-
-In menus_processors.py, write a menu processor::
-
-  def categories(request, menus):
-      """
-      This menu processor adds items to the 'categories' menu.
-      """
-      # get or create root menu item
-      root_menu_item = menus['categories']
-      # create items and append it to root
-      for category in Category.objects.all():
-          root_menu_item.append(category_to_menu_item(category, menu_name, counter))
-      # update menus
-      menus['categories'] = root_menu_item
-      # return updated menus
-      return menus
-
-Add the menu processor to your MENUS_PROCESSORS setting::
-
-  MENUS_PROCESSORS = (
-      'categories.menus_processors.categories',
-      # ... other menu processors
-      )
-
-Display the menu in your templates with the following code::
-
-  {% load menus %}
-  <div class="categories">
-  	{% render_menu_items menu=menus.category name="category" %}
-  </div>
-
-Do not forget to create some Category instances in the database...
-
-Updating the menu items catalog
--------------------------------
-
-As you can see in the previous examples, a menu processor takes the menu items
-catalog as input and returns it after update. It means that a menu processor
-could change menu items that were already defined by other processors.
-
-This is useful to force the insertion of static items in the catalog, or 
-to build a menu with several menu processors.
-
-Using custom 'MenuItem' classes
-===============================
-
-This application provides a default MenuItem class, which can be used to 
-populate the menu catalog. This class uses a basic request matching algorithm.
-The 'match' is effective if the menu item instance's URL equals path_info 
-property of the request.
-
-For specific cases, you may want to change this behavior. As an example, the
-authentication of the request's user could change the match. To do so, create
-another MenuItem class. Have a look at the inline documentation of the 
-menus.models.MenuItem class. You may be able to completely cover your needs
-by overriding the self_matches_request() method, which is the one used by
-template tags.
-
-Templates
-=========
-
-The 'menus.context_processors.menus' context processor calls menu processors
-defined by developers and add a "menus" template variable to the template
-context.
-
-In the examples used below, we assume that developers pushed "main" and
-"accessibility" keys to the menu catalog.
-
-The "menus" template tag library
---------------------------------
-
-The "menus" template tag library provides the following template tags:
-
-* render_menu_items: use it to render the list of children of a menu item
-* render_menu_item: use it to render a menu item itself
-
-The following template code demonstrate the use of the "render_menu_items" 
-template tag::
-
-  {% load menus %}
-  The following line will use YOUR_TEMPLATE_DIR/menus/default.html to render
-  the menus.main menu.
-  {% render_menu_items menu=menus.main %}
-  The following line will use YOUR_TEMPLATE_DIR/menus/accessibility.html or 
-  YOUR_TEMPLATE_DIR/menus/default.html to render the menus.accessibility menu.
-  The first one which exists will be used.
-  {% render_menu_items menu=menus.accessibility name='accessibility' %}
-
-Both render_menu_items and render_menu_item template tags accept the following
-arguments:
-
-* menu: (mandatory, MenuItem) the menu to render.
-* name: (optional, string, defaults to 'default') the name to determine 
-        specific template names.
-* max_depth: (optional, positive integer or None, defaults to None) a value
-             to limit recursion. A zero will display only the first level, a 
-             1 value will display first level and one level of children.
-
-Default template
-----------------
-
-If you want to affect all menus, set up two templates in your own template 
-folder: 
-
-* menus/default_items.html: the template for lists of items
-* menus/default_item.html: the template for an item itself
-
-Django-Menus provides a default one that you may use as a start. Notice that
-the provided default templates use render_menu_items and render_menu_item 
-template tags recursively. 
-
-Specific template
------------------
-
-If you want to change only a specific menu, use template names that
-correspond to the value of the "name" parameter passed to the 
-"render_menu_items" template tag:
-
-* menus/%s_items.html: the template for lists of items, where %s is the name
-* menus/%s_item.html: the template for an item itself, where %s is the name
-
-When using the following code, the templates "menus/accessibility_items.html"
-and "menus/accessibility_item.html" will be used. If these templates do not 
-exist, then the default templates will be used::
-
-  {% load menus %}
-  <div class="accessibilityMenu">
-    {% render_menu_items menu=menus.accessibility name='accessibility' %}
-  </div>
-
-Default CSS classes
-===================
-
-You should call every {% render_menu_items %} within a container, as
-shown in following template code::
-
-  {% load menus %}
-  <div class="accessibilityMenu">
-    {% render_menu_items menu=menus.accessibility name='accessibility' %}
-  </div>
-
-This practice makes CSS customization easier. In the following examples, 
-you may prefix every CSS style definition with the class name or id of your
-specific container.  
-
-The following CSS classes are used by the default templates::
-
-  UL {
-  	/* The container for menu items */
-  	
-  }
-  UL LI {
-  	/* The container for the menu item itself (a link) plus the list of 
-  	   descendants (recursive UL + LI) */
-  UL LI.active {
-  	/* The container for menu items that match the current request */
-  	
-  }
-  UL LI.opened {
-  	/* The container for menu item which does not match the current request 
-  	   but one of its descendants does */
-  	
-  }
-  UL LI A {
-  	/* The menu item itself (a link) */
-  	
-  }
-  UL LI.active A {
-  	/* An active menu item */
-  	
-  }
-  UL LI.opened A {
-  	/* An opened menu item */
-  	
-  }
-  UL UL {
-  	/* The container for the second level of menu items */
-  	
-  }
-  /* ... and so on, depending on the maximum recursion depth... */
-  
-  UL.depth0 {
-  	/* ... an alternative for accessing UL element at depth 0 */
-  	
-  }
-  
-  LI.depth0 {
-  	/* ... an alternative for accessing LI element at depth 0 */
-  	
-  }
-  
-  UL.depth1 {
-  	/* ... an alternative for accessing UL element at depth 1 */
-  	
-  }
-  
-  LI.depth1 {
-  	/* ... an alternative for accessing LI element at depth 1 */
-  	
-  }
-  
-  /* ... and so on, depending on the maximum recursion depth... */
-  
-
-****
-TODO
-****
-
-* Write tests (this should have been done BEFORE)
-* Use either request.path or breadcrumb to detect which menu item is active.
-  And write a recipe for using breadcrumb.
-* Enhance the tree structure: performance, browsing capabilities and utilities
-  like "walk".
-* Experiment and write documentation about the creation of custom MenuItem 
-  instances, which could implement specific self_matches_request() method.
+Read docs/index for more information.

File docs/Makefile

+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html      to make standalone HTML files"
+	@echo "  dirhtml   to make HTML files named index.html in directories"
+	@echo "  pickle    to make pickle files"
+	@echo "  json      to make JSON files"
+	@echo "  htmlhelp  to make HTML files and a HTML help project"
+	@echo "  qthelp    to make HTML files and a qthelp project"
+	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  changes   to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck to check all external links for integrity"
+	@echo "  doctest   to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf _build/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
+	@echo
+	@echo "Build finished. The HTML pages are in _build/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) _build/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in _build/dirhtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in _build/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) _build/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in _build/qthelp, like this:"
+	@echo "# qcollectiongenerator _build/qthelp/Django-Menus.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile _build/qthelp/Django-Menus.qhc"
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in _build/latex."
+	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+	      "run these through (pdf)latex."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
+	@echo
+	@echo "The overview file is in _build/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in _build/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) _build/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in _build/doctest/output.txt."

File docs/conf.py

+# -*- coding: utf-8 -*-
+#
+# Django-Menus documentation build configuration file, created by
+# sphinx-quickstart on Sat Apr 24 20:20:43 2010.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.txt'
+
+# The encoding of source files.
+#source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Django-Menus'
+copyright = u'2010, Benoit Bryon'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.1'
+# The full version, including alpha/beta/rc tags.
+release = '0.1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Django-Menusdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'Django-Menus.tex', u'Django-Menus Documentation',
+   u'Benoit Bryon', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True

File docs/index.txt

+############
+Django-Menus
+############
+
+:Authors: See AUTHORS
+:Copyright: This document is part of the django-menus package. Read LICENSE
+            for details.
+
+************
+Introduction
+************
+
+Django-Menus provides tools that help integrate menus in Django-based websites.
+
+When you add a configurable menu system to a website, you usually perform two 
+tasks:
+
+* create tools for the site administrator to manage menu items. Since menus 
+  can be flat or nested, internationalized or in one language only, related to
+  categories, flatpages or other models... this part is often specific to the 
+  project;
+* render menus through templates. Here you may use the same HTML structure and
+  styles for each website.
+
+This application provides:
+ 
+* an API that allow developers to connect project specific structure to a 
+  catalog of menu items;
+* template tags and template snippets that help template designers to display 
+  menus.
+
+************
+Installation
+************
+
+Requirements
+============
+
+This application requires:
+
+* `Django-1.1.1`_: the application targets the most recent release of 
+  1.x branch;
+* `Django-TemplateAddOns`_: a set of utilities to create template tags and 
+                            a library of template tags. 
+
+.. _`Django-1.1.1`: http://www.djangoproject.com/
+.. _`Django-TemplateAddOns`: http://bitbucket.org/benoitbryon/django-templateaddons/
+
+Please install and configure these applications *before* this one.
+
+Get the code
+============
+
+The code is published under the BSD license. See LICENSE for details.
+
+The code is available at http://bitbucket.org/benoitbryon/django-menus/
+
+You can get it by running the following commands::
+
+	$ hg clone http://bitbucket.org/benoitbryon/django-menus menus
+
+Put the "menus" folder somewhere in your PYTHON_PATH. 
+
+Django settings
+================
+
+* add 'menus' to your INSTALLED_APPS
+* add 'django.core.context_processors.request' to your 
+  TEMPLATE_CONTEXT_PROCESSORS. This is required to detect which menu is active.
+* add 'menus.context_processors.menus' to your TEMPLATE_CONTEXT_PROCESSORS.
+* Add a MENUS_PROCESSORS setting::
+	
+	MENUS_PROCESSORS = ()
+  
+  Default value is empty tuple. Menus processors are loaded in order. 
+  Notice that a menu processor can override or delete items set by other menu 
+  processors.
+
+*****
+Usage
+*****
+
+Synopsis
+========
+
+In order to work with Django-Menus, you will need to:
+
+* install and configure the Django-Menus application
+* as a developer, set up at least one menu processor
+* as a template designer, use the menus template tag library to display menus
+
+The menus processors will fill a dictionary of menu items, which will be
+made available in templates in a variable named "menus".
+
+Menu processors
+===============
+
+Menu processors are callbacks that build or update the menu registry. They
+are Python callables. They must be declared in the settings.MENUS_PROCESSORS
+list to be active. 
+
+Example: a simple menu processor
+--------------------------------
+
+In the following example, we will set up a menu processor which will put 3
+values in the menu catalog and associate them to the "test" key.
+
+First create a file named 'menus_processors.py' at your project root (besides
+settings.py and manage.py), with the following code::
+
+  from menus.models import MenuItem
+
+  def test(request, menus):
+      """
+      This menu processor adds 3 items to the 'test' menu:
+      
+        'test'
+         |__ 'Home'
+         |__ 'Test section'
+              |__ 'Test page'
+      
+      Input "menus" is a menus.loading.MenuRegistry instance.
+      """
+      # get or create root menu item
+      root_menu_item = menus['test']
+      # create items and append it to root
+      menu_item = MenuItem(
+          title='Home',
+          url='/',
+          subtitle='website home page',
+          accesskey='',
+      )
+      root_menu_item.append(menu_item)
+      menu_item = MenuItem(
+          title='Test section',
+          url='/test/',
+          subtitle='Some test section',
+          accesskey='',
+      )
+      sub_menu_item = MenuItem(
+          title='Test page',
+          url='/test/page/',
+          subtitle='Some test page',
+          accesskey='',
+      )
+      menu_item.append(sub_menu_item)
+      root_menu_item.append(menu_item)
+      # update menus
+      menus['test'] = root_menu_item
+      # return updated menus
+      return menus
+
+Add the menu processor to your MENUS_PROCESSORS setting::
+
+  MENUS_PROCESSORS = (
+      'menus_processors.test',
+      # ... other menu processors
+      )
+
+Display the menu in your templates with the following code::
+
+  {% load menus %}
+  {% render_menu_items menu=menus.test name="test" %}
+
+Example: a menu built from some Category model
+----------------------------------------------
+
+Suppose you have a 'category' application that manage categories. You want to 
+build a menu with all categories. The corresponding model is named Category.
+
+First create a file named 'menus_processors.py' in the category app directory
+(assume "categories/menus_processors.py").
+
+Then, in menus_processors.py, write a callback to convert a Category instance 
+into a MenuItem::
+
+  from menus.models import MenuItem
+  from categories.models import Category
+  
+  def category_to_menu_item(category):
+      """
+      Converts a Category instance into a MenuItem instance.
+      Here, assume that categories are not nested, so a menu item has no
+      children.
+      """
+      return MenuItem(
+          title=category.title,
+          url=category.get_absolute_url(),
+          subtitle=category.subtitle,
+      )
+
+In menus_processors.py, write a menu processor::
+
+  def categories(request, menus):
+      """
+      This menu processor adds items to the 'categories' menu.
+      """
+      # get or create root menu item
+      root_menu_item = menus['categories']
+      # create items and append it to root
+      for category in Category.objects.all():
+          root_menu_item.append(category_to_menu_item(category, menu_name, counter))
+      # update menus
+      menus['categories'] = root_menu_item
+      # return updated menus
+      return menus
+
+Add the menu processor to your MENUS_PROCESSORS setting::
+
+  MENUS_PROCESSORS = (
+      'categories.menus_processors.categories',
+      # ... other menu processors
+      )
+
+Display the menu in your templates with the following code::
+
+  {% load menus %}
+  <div class="categories">
+  	{% render_menu_items menu=menus.category name="category" %}
+  </div>
+
+Do not forget to create some Category instances in the database...
+
+Updating the menu items catalog
+-------------------------------
+
+As you can see in the previous examples, a menu processor takes the menu items
+catalog as input and returns it after update. It means that a menu processor
+could change menu items that were already defined by other processors.
+
+This is useful to force the insertion of static items in the catalog, or 
+to build a menu with several menu processors.
+
+Using custom 'MenuItem' classes
+===============================
+
+This application provides a default MenuItem class, which can be used to 
+populate the menu catalog. This class uses a basic request matching algorithm.
+The 'match' is effective if the menu item instance's URL equals path_info 
+property of the request.
+
+For specific cases, you may want to change this behavior. As an example, the
+authentication of the request's user could change the match. To do so, create
+another MenuItem class. Have a look at the inline documentation of the 
+menus.models.MenuItem class. You may be able to completely cover your needs
+by overriding the self_matches_request() method, which is the one used by
+template tags.
+
+Templates
+=========
+
+The 'menus.context_processors.menus' context processor calls menu processors
+defined by developers and add a "menus" template variable to the template
+context.
+
+In the examples used below, we assume that developers pushed "main" and
+"accessibility" keys to the menu catalog.
+
+The "menus" template tag library
+--------------------------------
+
+The "menus" template tag library provides the following template tags:
+
+* render_menu_items: use it to render the list of children of a menu item
+* render_menu_item: use it to render a menu item itself
+
+The following template code demonstrate the use of the "render_menu_items" 
+template tag::
+
+  {% load menus %}
+  The following line will use YOUR_TEMPLATE_DIR/menus/default.html to render
+  the menus.main menu.
+  {% render_menu_items menu=menus.main %}
+  The following line will use YOUR_TEMPLATE_DIR/menus/accessibility.html or 
+  YOUR_TEMPLATE_DIR/menus/default.html to render the menus.accessibility menu.
+  The first one which exists will be used.
+  {% render_menu_items menu=menus.accessibility name='accessibility' %}
+
+Both render_menu_items and render_menu_item template tags accept the following
+arguments:
+
+* menu: (mandatory, MenuItem) the menu to render.
+* name: (optional, string, defaults to 'default') the name to determine 
+        specific template names.
+* max_depth: (optional, positive integer or None, defaults to None) a value
+             to limit recursion. A zero will display only the first level, a 
+             1 value will display first level and one level of children.
+
+Default template
+----------------
+
+If you want to affect all menus, set up two templates in your own template 
+folder: 
+
+* menus/default_items.html: the template for lists of items
+* menus/default_item.html: the template for an item itself
+
+Django-Menus provides a default one that you may use as a start. Notice that
+the provided default templates use render_menu_items and render_menu_item 
+template tags recursively. 
+
+Specific template
+-----------------
+
+If you want to change only a specific menu, use template names that
+correspond to the value of the "name" parameter passed to the 
+"render_menu_items" template tag:
+
+* menus/%s_items.html: the template for lists of items, where %s is the name
+* menus/%s_item.html: the template for an item itself, where %s is the name
+
+When using the following code, the templates "menus/accessibility_items.html"
+and "menus/accessibility_item.html" will be used. If these templates do not 
+exist, then the default templates will be used::
+
+  {% load menus %}
+  <div class="accessibilityMenu">
+    {% render_menu_items menu=menus.accessibility name='accessibility' %}
+  </div>
+
+Default CSS classes
+===================
+
+You should call every {% render_menu_items %} within a container, as
+shown in following template code::
+
+  {% load menus %}
+  <div class="accessibilityMenu">
+    {% render_menu_items menu=menus.accessibility name='accessibility' %}
+  </div>
+
+This practice makes CSS customization easier. In the following examples, 
+you may prefix every CSS style definition with the class name or id of your
+specific container.  
+
+The following CSS classes are used by the default templates::
+
+  UL {
+  	/* The container for menu items */
+  	
+  }
+  UL LI {
+  	/* The container for the menu item itself (a link) plus the list of 
+  	   descendants (recursive UL + LI) */
+  UL LI.active {
+  	/* The container for menu items that match the current request */
+  	
+  }
+  UL LI.opened {
+  	/* The container for menu item which does not match the current request 
+  	   but one of its descendants does */
+  	
+  }
+  UL LI A {
+  	/* The menu item itself (a link) */
+  	
+  }
+  UL LI.active A {
+  	/* An active menu item */
+  	
+  }
+  UL LI.opened A {
+  	/* An opened menu item */
+  	
+  }
+  UL UL {
+  	/* The container for the second level of menu items */
+  	
+  }
+  /* ... and so on, depending on the maximum recursion depth... */
+  
+  UL.depth0 {
+  	/* ... an alternative for accessing UL element at depth 0 */
+  	
+  }
+  
+  LI.depth0 {
+  	/* ... an alternative for accessing LI element at depth 0 */
+  	
+  }
+  
+  UL.depth1 {
+  	/* ... an alternative for accessing UL element at depth 1 */
+  	
+  }
+  
+  LI.depth1 {
+  	/* ... an alternative for accessing LI element at depth 1 */
+  	
+  }
+  
+  /* ... and so on, depending on the maximum recursion depth... */
+  
+
+****
+TODO
+****
+
+* Write tests (this should have been done BEFORE)
+* Use either request.path or breadcrumb to detect which menu item is active.
+  And write a recipe for using breadcrumb.
+* Enhance the tree structure: performance, browsing capabilities and utilities
+  like "walk".
+* Experiment and write documentation about the creation of custom MenuItem 
+  instances, which could implement specific self_matches_request() method.

File docs/make.bat

+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+set SPHINXBUILD=sphinx-build
+set ALLSPHINXOPTS=-d _build/doctrees %SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html      to make standalone HTML files
+	echo.  dirhtml   to make HTML files named index.html in directories
+	echo.  pickle    to make pickle files
+	echo.  json      to make JSON files
+	echo.  htmlhelp  to make HTML files and a HTML help project
+	echo.  qthelp    to make HTML files and a qthelp project
+	echo.  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  changes   to make an overview over all changed/added/deprecated items
+	echo.  linkcheck to check all external links for integrity
+	echo.  doctest   to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (_build\*) do rmdir /q /s %%i
+	del /q /s _build\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% _build/html
+	echo.
+	echo.Build finished. The HTML pages are in _build/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% _build/dirhtml
+	echo.
+	echo.Build finished. The HTML pages are in _build/dirhtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% _build/pickle
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% _build/json
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% _build/htmlhelp
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in _build/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% _build/qthelp
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in _build/qthelp, like this:
+	echo.^> qcollectiongenerator _build\qthelp\Django-Menus.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile _build\qthelp\Django-Menus.ghc
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% _build/latex
+	echo.
+	echo.Build finished; the LaTeX files are in _build/latex.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% _build/changes
+	echo.
+	echo.The overview file is in _build/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% _build/linkcheck
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in _build/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% _build/doctest
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in _build/doctest/output.txt.
+	goto end
+)
+
+:end