[Checkins] SVN: grok/trunk/ svn merge -r 119493:119617 svn+ssh://svn.zope.org/repos/main/grok/branches/jw-documentation-rearangement .

Jan-Wijbrand Kolman janwijbrand at gmail.com
Mon Jan 17 06:06:32 EST 2011


Log message for revision 119618:
  svn merge -r 119493:119617 svn+ssh://svn.zope.org/repos/main/grok/branches/jw-documentation-rearangement .

Changed:
  U   grok/trunk/INSTALL.txt
  D   grok/trunk/doc/.static/
  D   grok/trunk/doc/ACKS.txt
  A   grok/trunk/doc/Makefile
  D   grok/trunk/doc/README.rst
  A   grok/trunk/doc/_build/
  A   grok/trunk/doc/_static/
  A   grok/trunk/doc/_templates/
  A   grok/trunk/doc/api.rst
  D   grok/trunk/doc/bugs.rst
  U   grok/trunk/doc/conf.py
  D   grok/trunk/doc/contents.rst
  D   grok/trunk/doc/design/
  D   grok/trunk/doc/developing_grok.rst
  A   grok/trunk/doc/development.rst
  D   grok/trunk/doc/docindex.template
  D   grok/trunk/doc/glossary.rst
  D   grok/trunk/doc/grok_overview.rst
  D   grok/trunk/doc/groktut/
  U   grok/trunk/doc/index.rst
  A   grok/trunk/doc/introduction.rst
  D   grok/trunk/doc/layout.html
  A   grok/trunk/doc/make.bat
  D   grok/trunk/doc/naming_conventions.rst
  D   grok/trunk/doc/reference/
  D   grok/trunk/doc/resources/
  D   grok/trunk/doc/style.tex
  D   grok/trunk/doc/template.pt
  D   grok/trunk/doc/tutorial.rst
  D   grok/trunk/doc/tutorial_outline.txt
  D   grok/trunk/doc/upgrade.rst
  D   grok/trunk/doc/upgrade.txt
  U   grok/trunk/documentation.cfg
  D   grok/trunk/documentation_deployment.cfg

-=-
Modified: grok/trunk/INSTALL.txt
===================================================================
--- grok/trunk/INSTALL.txt	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/INSTALL.txt	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,3 +1,6 @@
+Developing grok
+===============
+
 Preparing for grok development
 ------------------------------
 

Deleted: grok/trunk/doc/ACKS.txt
===================================================================
--- grok/trunk/doc/ACKS.txt	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/ACKS.txt	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,23 +0,0 @@
-Contributors to the Grok Documentation
-======================================
-
-This section lists people who have contributed in some way to the Grok
-documentation. It is probably not complete -- if you feel that you or
-anyone else should be on this list, please let us know (send email to
-grok-dev at zope.org), and we'll be glad to correct the problem.
-
-.. acks::
-
-   * Darryl Cousins
-   * Kushal Das
-   * Martijn Faassen
-   * Uli Fouquet
-   * Jim Fulton
-   * Jan-Wijbrand Kolman
-   * Luis de la Parra
-   * Luciano Ramalho
-   * Lennart Regebro
-   * Brandon Craig Rhodes
-   * Kevin Teague
-   * Sebastian Ware
-   * Philipp von Weitershausen

Copied: grok/trunk/doc/Makefile (from rev 119617, grok/branches/jw-documentation-rearangement/doc/Makefile)
===================================================================
--- grok/trunk/doc/Makefile	                        (rev 0)
+++ grok/trunk/doc/Makefile	2011-01-17 11:06:31 UTC (rev 119618)
@@ -0,0 +1,130 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man 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 "  singlehtml to make a single large HTML file"
+	@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 "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@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 $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/grok.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/grok.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/grok"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/grok"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	make -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."

Deleted: grok/trunk/doc/README.rst
===================================================================
--- grok/trunk/doc/README.rst	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/README.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,95 +0,0 @@
-*********************
-About these documents
-*********************
-
-These documents are generated from `reStructuredText
-<http://docutils.sf.net/rst.html>`_ sources by `Sphinx
-<http://sphinx.pocoo.org>`_, an excellent document processor
-specifically written for the Python documentation by Georg Brandl and
-contributors.
-
-Development of this documentation and its toolchain takes place on the
-grok-dev at zope.org mailing list.  We're always looking for volunteers
-wanting to help with the docs, so feel free to send a mail there!
-
-Many thanks go to:
-
-* the `docutils <http://docutils.sf.net/>`_ project for creating
-  reStructuredText and the docutils suite;
-* Georg Brandl for his `Sphinx` package.
-
-See :ref:`reporting-bugs` for information how to report bugs in Grok
-itself.
-
-.. including the ACKS file here so that it can be maintained separately
-.. include:: ACKS.txt
-
-It is only with the input and contributions of the Grok community
-that Grok has so much documentation -- Thank You!
-
-
-The Grok documentation toolchain
-================================
-
-Grok now makes use of the ``Sphinx`` package, which was written by
-Georg Brandl and volunteers, to generate the official Python
-documentation. Sphinx is able to generate HTML as well as LaTeX and
-other formats.
-
-
-How can I generate nice HTML/LaTeX/PDF documentation for Grok?
---------------------------------------------------------------
-
-If you have run ``bin/buildout``, than you're nearly finished. This
-will generate some scripts in the ``bin/`` directory. Just run::
-
-  $ bin/grokdocs2html
-
-to generate the HTML documentation. The docs will be placed in
-
-  docs/build/html/
-
-For LaTeX/PDF docs you must have LaTeX and ``pdflatex`` installed. Then, to generate PDF docs, run::
-
-  $ bin/grokdocs2pdf
-
-which will first generate .tex files and appropriate Makefiles in
-``docs/build/latex`` and afterwards run ``pdflatex`` to generate PDFs.
-
-If everything works smoothly three documents will be generated:
-
-1) The Tutorial (``tutorial.pdf``)
-
-2) The Reference (``reference.pdf``)
-
-3) The whole documentation (``grokdocs.pdf``)
-
-which can be found in ``docs/build/latex``.
-
-Any warnings during the document processing can be ignored for the
-time being.
-
-The ``grokdocs2...`` scripts generated in ``bin/`` unfortunately yet
-do not accept much options. In fact they accept no options at all. But
-you can use the also generated script ``bin/sphinx-build`` to finetune
-parameters or, after running ``grokdocs2...`` change to the ``build/``
-directory and run for instance::
-
-    $ make html SPHINXOPTS="-E -a"
-
-to regenerate all docs in HTML format.
-
-
-How to tweak the layout/settings of the documentation toolchain
----------------------------------------------------------------
-
-Beside passing options to Spinx (see above), the general settings of
-documentation generated by ``sphinx`` are settable in a file
-``conf.py`` which must be in the source root directory of your
-docs. Have a look at ``docs/conf.py`` for deeper insights.
-
-The structure of the HTML entry page is defined in
-``build/docindex.template``, which is a template for the Jinja
-templating engine used by Sphinx.
-
-The layout details are defined in ``docs/.static/grok.css``.


Property changes on: grok/trunk/doc/_build
___________________________________________________________________
Added: svn:ignore
   + doctrees
html


Copied: grok/trunk/doc/api.rst (from rev 119617, grok/branches/jw-documentation-rearangement/doc/api.rst)
===================================================================
--- grok/trunk/doc/api.rst	                        (rev 0)
+++ grok/trunk/doc/api.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -0,0 +1,144 @@
+API reference
+=============
+
+.. py:module:: grok
+
+Content model and container components
+--------------------------------------
+
+.. autoclass:: grok.Application
+.. autoclass:: grok.Container
+.. autoclass:: grok.Model
+.. autoclass:: grok.OrderedContainer
+.. autoclass:: grok.Site
+.. autofunction:: grok.getApplication
+.. autofunction:: grok.getSite
+
+View components
+---------------
+
+.. autoclass:: grok.DirectoryResource
+.. autoclass:: grok.IBrowserRequest
+.. autoclass:: grok.IDefaultBrowserLayer
+.. autoclass:: grok.IRESTLayer
+.. autoclass:: grok.IRESTSkinType
+.. autoclass:: grok.JSON
+.. autoclass:: grok.layer
+.. autoclass:: grok.PageTemplate
+.. autoclass:: grok.PageTemplateFile
+.. autoclass:: grok.path
+.. autoclass:: grok.REST
+.. autoclass:: grok.restskin
+.. autoclass:: grok.skin
+.. autoclass:: grok.template
+.. autoclass:: grok.view
+.. autoclass:: grok.View
+.. autoclass:: grok.Viewlet
+.. autoclass:: grok.viewletmanager
+.. autoclass:: grok.ViewletManager
+.. autoclass:: grok.XMLRPC
+.. autofunction:: grok.url
+
+Forms
+-----
+
+.. autoclass:: grok.action
+.. autoclass:: grok.AddForm
+.. autoclass:: grok.DisplayForm
+.. autoclass:: grok.EditForm
+.. autoclass:: grok.Form
+.. autofunction:: grok.AutoFields
+.. autofunction:: grok.Fields
+
+Utilities and Adapters
+----------------------
+
+.. autoclass:: grok.adapter
+.. autoclass:: grok.Adapter
+.. autoclass:: grok.Annotation
+.. autoclass:: grok.global_utility
+.. autoclass:: grok.GlobalUtility
+.. autoclass:: grok.implementer
+.. autoclass:: grok.local_utility
+.. autoclass:: grok.LocalUtility
+.. autoclass:: grok.MultiAdapter
+.. autofunction:: grok.adapts
+.. autofunction:: grok.implements
+
+Security
+--------
+
+.. autoclass:: grok.Permission
+.. autoclass:: grok.permissions
+.. autoclass:: grok.Public
+.. autoclass:: grok.require
+.. autoclass:: grok.Role
+
+Traversal
+---------
+
+.. autoclass:: grok.Traverser
+.. autoclass:: grok.traversable
+
+Indexes
+-------
+
+.. autoclass:: grok.Indexes
+.. autoclass:: grok.index.Field
+.. autoclass:: grok.index.Set
+.. autoclass:: grok.index.Text
+
+Events
+------
+
+.. autoclass:: grok.ApplicationInitializedEvent
+.. autoclass:: grok.ContainerModifiedEvent
+.. autoclass:: grok.IBeforeTraverseEvent
+.. autoclass:: grok.IContainerModifiedEvent
+.. autoclass:: grok.IObjectAddedEvent
+.. autoclass:: grok.IObjectCopiedEvent
+.. autoclass:: grok.IObjectCreatedEvent
+.. autoclass:: grok.IObjectModifiedEvent
+.. autoclass:: grok.IObjectMovedEvent
+.. autoclass:: grok.IObjectRemovedEvent
+.. autoclass:: grok.ObjectAddedEvent
+.. autoclass:: grok.ObjectCopiedEvent
+.. autoclass:: grok.ObjectCreatedEvent
+.. autoclass:: grok.ObjectModifiedEvent
+.. autoclass:: grok.ObjectMovedEvent
+.. autoclass:: grok.ObjectRemovedEvent
+.. autoclass:: grok.viewletmanager
+.. autofunction:: grok.notify
+
+Directives
+----------
+
+.. autoclass:: grok.baseclass
+.. autoclass:: grok.context
+.. autoclass:: grok.description
+.. autoclass:: grok.direct
+.. autoclass:: grok.global_utility
+.. autoclass:: grok.layer
+.. autoclass:: grok.name
+.. autoclass:: grok.permissions
+.. autoclass:: grok.provides
+.. autoclass:: grok.require
+.. autoclass:: grok.restskin
+.. autoclass:: grok.site
+.. autoclass:: grok.skin
+.. autoclass:: grok.template
+.. autoclass:: grok.title
+.. autoclass:: grok.view
+.. autoclass:: grok.viewletmanager
+
+Grokkers
+--------
+
+.. autoclass:: grok.ClassGrokker
+.. autoclass:: grok.GlobalGrokker
+.. autoclass:: grok.GrokError
+.. autoclass:: grok.GrokImportError
+.. autoclass:: grok.InstanceGrokker
+.. autofunction:: grok.testing.grok
+.. autofunction:: grok.testing.grok_component
+.. autofunction:: grok.testing.warn

Deleted: grok/trunk/doc/bugs.rst
===================================================================
--- grok/trunk/doc/bugs.rst	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/bugs.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,64 +0,0 @@
-.. _reporting-bugs:
-
-**********************
-Reporting Bugs in Grok
-**********************
-
-Grok aims to become a mature framework and tries to earn reputation
-for stability.  In order to maintain this reputation, the developers
-would like to know of any deficiencies you find in Grok.
-
-If you find errors in the documentation, you can correct it yourself
-on the Grok website http://grok.zope.org/ . You only need to register
-with the website for that, which is necessary to block spammers. On
-some pages you then can use the "Add a comment" feature of the
-relevant page.
-
-All other bug reports should be submitted via the Grok Bug Tracker
-(https://bugs.launchpad.net/grok/).  The bug tracker offers a Web form
-which allows pertinent information to be entered and submitted to the
-developers.
-
-The first step in filing a report is to determine whether the problem
-has already been reported.  The advantage in doing so, aside from
-saving the developers time, is that you learn what has been done to
-fix it; it may be that the problem has already been fixed for the next
-release, or additional information is needed (in which case you are
-welcome to provide it if you can!).  To do this, search the bug
-database using the search box on the top of the page or by clicking on
-"List all open bugs".
-
-If the problem you're reporting is not already in the bug tracker, go
-back to the Grok Bug Tracker and click the red "Report a bug" box on
-the right. If you don't already have a launchpad account, you will be
-asked to complete the registration by giving an e-mail address and
-following the steps mailed to you. Complete the registration process.
-Otherwise, if you're not logged in, enter your credentials and select
-"Log In".  It is not possible to submit a bug report anonymously.
-
-Being now logged in, you can submit a bug.  You will be asked a number
-of questions. 
-
-For the "Summary" field, enter a *very* short description of the
-problem; less than ten words is good.  In the "Further Information"
-field, describe your problem as accurate as possible. A good
-description will enables the developers to reproduce your
-problem. Name also the version of grok/grokproject you used.
-
-Each bug report will be assigned to a developer who will determine
-what needs to be done to correct the problem. You will receive an
-update each time action is taken on the bug.
-
-.. seealso::
-
-   `How to Report Bugs Effectively
-   <http://www.chiark.greenend.org.uk/~sgtatham/bugs.html>`_ Article
-   which goes into some detail about how to create a useful bug
-   report. This describes what kind of information is useful and why
-   it is useful.
-
-   `Bug Writing Guidelines
-   <http://www.mozilla.org/quality/bug-writing-guidelines.html>`_
-   Information about writing a good bug report.  Some of this is
-   specific to the Mozilla project, but describes general good
-   practices.

Modified: grok/trunk/doc/conf.py
===================================================================
--- grok/trunk/doc/conf.py	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/conf.py	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,70 +1,86 @@
 # -*- coding: utf-8 -*-
 #
-# Grok Reference documentation build configuration file, created by
-# sphinx-quickstart.py on Wed Feb 20 02:11:17 2008.
+# grok documentation build configuration file, created by
+# sphinx-quickstart on Thu Jan 13 10:38:13 2011.
 #
 # This file is execfile()d with the current directory set to its containing dir.
 #
-# The contents of this file are pickled, so don't put values in the namespace
-# that aren't pickleable (module imports are okay, they're removed automatically).
+# Note that not all possible configuration values are present in this
+# autogenerated file.
 #
-# All configuration values have a default value; values that are commented out
-# show the default value as assigned to them.
+# All configuration values have a default; values that are commented out
+# serve to show the default.
 
-import sys
-import pkg_resources
+import sys, os
 
-from os import path, curdir
+# 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.insert(0, os.path.abspath('.'))
 
-# If your extensions are in another directory, add it here.
-#sys.path.append('some/directory')
+# -- General configuration -----------------------------------------------------
 
-# General configuration
-# ---------------------
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc',
-              'sphinx.ext.doctest',
-              'sphinx.ext.intersphinx',
-              # 'sphinx.ext.viewcode', # This is currently broken?
-              ]
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.coverage',
+    'sphinx.ext.doctest',
+    'sphinx.ext.intersphinx',
+    'sphinx.ext.todo',
+    'sphinx.ext.viewcode',
+    ]
 
 # Order autodoc generated docs in source code order.
-autodoc_member_order = 'bysource'
+autodoc_member_order = 'alphabetical'
 
 # Add any paths that contain templates here, relative to this directory.
-templates_path = ['.']
+templates_path = ['_templates']
 
 # The suffix of source filenames.
 source_suffix = '.rst'
 
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
 # The master toctree document.
 master_doc = 'index'
 
-# General substitutions.
-project = 'Official Grok'
-copyright = '2006-2010, The Zope Foundation'
+# General information about the project.
+project = u'grok'
+copyright = u'2006-2011, The Zope Foundation and Grok developers and community'
 
-# The default replacements for |version| and |release|, also used in various
-# other places throughout the built documents.
+# 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 = pkg_resources.get_distribution('grok').version
+version = '1.4'
 # The full version, including alpha/beta/rc tags.
-release = version
+release = '1.4'
 if release.endswith('dev'):
     release = '%s (unreleased)' % release
 
+# 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'
+#today_fmt = '%B %d, %Y'
 
-# List of documents that shouldn't be included in the build.
-unused_docs = ['build']
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_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
 
@@ -72,73 +88,145 @@
 # 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
 
-# Options for HTML output
-# -----------------------
+# 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.  See the documentation for
+# a list of builtin themes.
+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'
+#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
+#html_use_smartypants = True
 
-# Custom sidebar templates, maps page names to filenames relative to this file.
+# Custom sidebar templates, maps document names to template names.
 #html_sidebars = {}
 
 # Additional templates that should be rendered to pages, maps page names to
-# filenames relative to this file.
-html_additional_pages = {'index':'docindex.template'}
+# template names.
+#html_additional_pages = {}
 
-# If true, the reST sources are included in the HTML build as _sources/<name>.
-#html_copy_source = True
+# If false, no module index is generated.
+#html_domain_indices = True
 
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'Grokdoc'
+# If false, no index is generated.
+#html_use_index = True
 
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
 
-# The style sheet to use for HTML and HTML Help pages. A file of that name
-# must exist either in Sphinx' static/ path, or in one of the custom paths
-# given in html_static_path.
-html_style = 'grok.css'
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
 
-# 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 = [path.join(path.abspath(curdir), '.static')]
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
 
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
 
-# Options for LaTeX output
-# ------------------------
+# 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 = ''
 
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+# htmlhelp_basename = 'grokdoc'
+
+
+# -- 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'
-latex_font_size = '11pt'
 
 # Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, document class [howto/manual]).
-#latex_documents = []
+# (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
-    ('contents', 'grokdocs.tex', 'Grok Documentation', 'The Grok Team',
-     'manual'),
-    ('tutorial', 'tutorial.tex', 'Grok Tutorial', 'The Grok Team',
-     'manual'),
-    (path.join('reference', 'index'), 'reference.tex', 'Grok Reference',
-     'The Grok Team', 'manual'),
-    ]
+  ('index', 'grok.tex', u'grok Documentation',
+   u'The Grok developers and community', '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
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
 # Additional stuff for the LaTeX preamble.
-#latex_preamble = '
-latex_preamble = '''
-\usepackage{epsfig}
+#latex_preamble = ''
 
-'''
-
 # Documents to append as an appendix to all manuals.
 #latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'grok', u'grok Documentation',
+     [u'The Grok developers and community'], 1)
+]
+
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {'http://docs.python.org/': None}

Deleted: grok/trunk/doc/contents.rst
===================================================================
--- grok/trunk/doc/contents.rst	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/contents.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,20 +0,0 @@
-===========================
-Grok Documentation Contents
-===========================
-
-.. toctree::
-   :maxdepth: 2
-
-   changes.rst
-   upgrade.rst
-   tutorial.rst
-   grok_overview.rst
-   reference/index.rst
-   naming_conventions.rst
-   developing_grok.rst
-
-   bugs.rst
-   license.rst
-   README.rst
-   copyright.rst
-   glossary.rst

Deleted: grok/trunk/doc/developing_grok.rst
===================================================================
--- grok/trunk/doc/developing_grok.rst	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/developing_grok.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,123 +0,0 @@
-===============
-Developing Grok
-===============
-
-.. contents::
-
-Making Grok (Toolkit) releases
-------------------------------
-
-Manual steps
-~~~~~~~~~~~~
-
-Grok Toolkit's release procedure (and that of the comprising package like grok
-and the ``grokcore.*`` family of libraries) follows ZTK's `official release
-guidelines`_.
-
-.. _`official release guidelines`: http://docs.zope.org/zopetoolkit/process/releasing-software.html
-
-Automated steps
-~~~~~~~~~~~~~~~
-
-Even if it can be useful to follow these release steps by hand, most of it is
-automated in the `zest.releaser`_ package that is included in Grok Toolkit's
-``buildout.cfg``. Using this tool will prevent making mistakes caused by the
-rather repetitive nature of the release process.
-
-.. _`zest.releaser`: http://pypi.python.org/pypi/zest.releaser
-
-Part of the `official release guidelines`_ is reviewing the changelog recorded
-in ``CHANGES.txt``. This is an important step that cannot be automated.
-
-In other words, before starting a release make sure that:
-
-  1) All tests pass
-  2) All local changes are committed
-  3) The changelogs in the Grok packages are up to date.
-
-The `zest.releaser` package provides a command line utility to help reviewing
-the changelog. It will display a diff between the most recently created
-release tag and the current maintenance branch of trunk::
-
-  $ ./bin/lasttagdiff
-
-After having reviewed the changelog (and making sure any changes are commited!)
-the actual release can be made::
-
-  $ ./bin/fullrelease
-
-Grok Tookit contains a post-release step triggered by zest.releaser that will
-upload a ``versions.cfg`` file to::
-
-   grok.zope.org:/var/www/html/grok/releaseinfo/[VERSION]/versions.cfg
-
-Manual post release steps
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-After having released Grok, the following steps should be taken:
-
-1. Grokproject generates a ``buildout.cfg`` with an ``extends`` directive
-   pointing to the most recent release versions file. It determines the URL
-   to this versions file by reading http://grok.zope.org/releaseinfo/current.
-   This file needs to be updated to point to the uploaded ``*.cfg`` file for
-   the official "final" releases.
-
-2. Add a document with the release announcement in the `releases folder`_
-   Name it after the release version number. Summarize what is in
-   ``CHANGES.txt``. Make sure you move it to become the first item of the
-   releases folder. You can move it up by using the contents view of the
-   folder. The last column in that table presents a handle by which you can
-   drag up the document in the folder.
-
-   .. _`releases folder`: http://grok.zope.org/project/releases/
-
-3. Official Documentation: Create a build of the docs from the tagged
-   release and copy it to the server. Detailed steps are documented in the
-   `Updating the Official Grok Documentation (OGD)`_ page.
-
-4. Create a news item in the `blog folder`_ announcing the news. The text
-   can be based on the release notes written at point 7.
-
-   .. _`blog folder`: http://grok.zope.org/blog/
-
-5. Make both the new release notes, the new news item, as well as the
-   updated upgrade notes public.
-
-6. Update the sidebar in the site. You can edit it here::
-
-     http://grok.zope.org/portal_skins/custom/portlet_download/manage_main
-
-7. Community Documentation: Update the Plone Help Center used for Grok
-   Community Documentation so that the new Version is available. Important: you
-   can select multiple "current" versions for community documentation, any
-   documentation for a release which is not "current" gets a big nasty
-   "outdated" header at the top of it. We only want to do this for
-   documentation which is truly outdated and no longer best practice. Do this
-   here: http://grok.zope.org/documentation/edit
-
-8. Send out an email to at least zope-announce at zope.org as well as grok-
-   dev at zope.org announcing the new release. The text can be based on the
-   release notes written at step 2.
-
-9. Update the Grok Wikipedia article with the information about the latest
-   release: http://en.wikipedia.org/wiki/Grok_(web_framework)
-
-.. _`Updating the Official Grok Documentation (OGD)`: http://grok.zope.org/project/meta/updating-the-official-grok-documentation-ogd
-
-Binary eggs on Windows
-----------------------
-
-Grok aims to work on Windows as well. This is not a problem for the most part,
-but takes special attention when updating the list of dependencies. The follow
-eggs need a compiler on Unixy platforms, and a binary egg on Windows::
-
-  zope.i18nmessageid
-  zope.interface
-  zope.security
-  zope.container
-  ZODB3
-  zope.hookable
-  zope.proxy
-
-Please make sure a Windows version of the egg is available when you update a
-dependency!

Copied: grok/trunk/doc/development.rst (from rev 119617, grok/branches/jw-documentation-rearangement/doc/development.rst)
===================================================================
--- grok/trunk/doc/development.rst	                        (rev 0)
+++ grok/trunk/doc/development.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -0,0 +1 @@
+.. include:: ../INSTALL.txt

Deleted: grok/trunk/doc/docindex.template
===================================================================
--- grok/trunk/doc/docindex.template	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/docindex.template	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,87 +0,0 @@
-{% extends "layout.html" %}
-{% set title = 'Overview' %}
-{% block body %}
-
-  <h1>{{ docstitle }}</h1>
-  <p>
-  This is official documentation for Grok {{ release }}.
-  {% if last_updated %}Last modifed on {{ last_updated }}.{% endif %}
-  </p>
-
-  <p><strong>Sections</strong></p>
-  <table class="contentstable" align="center"><tr>
-    <td width="50%">
-      <p class="biglink"><a class="biglink" href="{{ pathto("tutorial") }}"
-      >Grok Tutorial</a><br>
-      <span class="linkdescr">Get started with Grok.</span></p>
-
-      <p class="biglink"><a class="biglink" href="{{ pathto("reference/index") }}">The Grok Reference</a><br>
-         <span class="linkdescr">Describes syntax and package elements.</span></p>
-
-      <p class="biglink"><a class="biglink" href="{{ pathto("grok_overview") }}"
-      >Grok Developer Notes</a><br>
-      <span class="linkdescr">Overview of what's in Grok and how to use it.</span></p>
-
-      <p class="biglink"><a class="biglink" href="{{ pathto("naming_conventions") }}">Naming Conventions</a><br>
-         <span class="linkdescr">How to name your stuff correctly.</span></p>
-
-    </td><td width="50%">
-	    <p class="biglink"><a class="biglink" href="{{ pathto("changes") }}"
-	    >What's new in Grok?</a><br>
-	    <span class="linkdescr">Changes made in each Grok release.</span></p>
-
-	    <p class="biglink"><a class="biglink" href="{{ pathto("upgrade") }}"
-	    >Upgrading notes</a><br>
-	    <span class="linkdescr">How to upgrade your project to a new version of the Grok Toolkit.</span></p>
-
-      <p class="biglink"><a class="biglink" href="{{ pathto("developing_grok") }}">Developing Grok</a><br>
-         <span class="linkdescr">Notes for developers <strong>of</strong> Grok.</span></p>
-
-    </td></tr>
-  </table>
-
-  <p><strong>Indices and tables</strong></p>
-  <table class="contentstable" align="center"><tr>
-    <td width="50%">
-      <p class="biglink"><a class="biglink" href="{{ pathto("contents") }}">Table of Contents</a><br>
-         <span class="linkdescr">Lists all sections and subsections.</span></p>
-<!--
-      <p class="biglink"><a class="biglink" href="{{ pathto("search") }}">Search page</a><br>
-         <span class="linkdescr">search this documentation</span></p>
--->
-    </td><td width="50%">
-      <p class="biglink"><a class="biglink" href="{{ pathto("genindex") }}">Index</a><br>
-         <span class="linkdescr">All functions, classes, terms.</span></p>
-    </td></tr>
-  </table>
-
-  <p><strong>Further information</strong></p>
-  <table class="contentstable" align="center"><tr>
-    <td width="50%">
-
-      <p class="biglink"><a class="biglink" href="{{ pathto("bugs") }}"
-      >Reporting bugs</a><br>
-
-      <p class="biglink"><a class="biglink" href="{{ pathto("README") }}"
-      >About the documentation</a><br>
-
-    </td><td width="50%">
-
-      <p class="biglink"><a class="biglink" href="{{ pathto("license") }}"
-      >License</a><br>
-
-      <p class="biglink"><a class="biglink" href="{{ pathto("copyright") }}"
-      >Copyright</a><br>
-
-    </td></tr>
-  </table>
-
-  <p>
-	The <b>Official Grok Documentation</b> documents the core features of the
-	Grok framework. For further reading, the
-	<a href="http://grok.zope.org/documentation/">Community Grok Documentation</a>
-	contains deeper information on working with Grok, as well as using
-	additional packages with Grok that are not part of the core framework.
-  </p>
-
-{% endblock %}
\ No newline at end of file

Deleted: grok/trunk/doc/glossary.rst
===================================================================
--- grok/trunk/doc/glossary.rst	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/glossary.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,99 +0,0 @@
-=================
-Grok Glossary
-=================
-
-* **adapter** - 
-  An Adapter takes an object providing an existing interface and extends it to 
-  provide a new interface.
-
-* **(Grok) application** - 
-  Applications are top-level objects. They are typically used to hold global 
-  configuration and behaviour for an application instance, as well as holding 
-  data objects such as grok.Container and grok.Model object instances.
-  
-* **buildout** -
-  ...
-
-* **buildout egg** -
-  ...
-
-* **(Grok) container** - 
-  Objects in a container are manipulated using the same syntax as you would with
-  a standard Python Dictionary object. The container implements the 
-  zope.app.container.interfaces.IContainer interface using a BTree, providing 
-  reasonable performance for large collections of objects.
-
-* **(Grok) directive** - 
-  The grok module defines a set of directives that allow you to configure and 
-  register your components.
-
-* **directory resource** - 
-  ...
-
-* **egg** - 
-  ...
-
-* **global utility** - 
-  A global utility is an object which provides an interface, and can be 
-  looked-up by that interface and optionally the component name. The attributes 
-  provided by a global utility are not persistent.
-
-* **grokproject** - 
-  A command line tool for creating a Grok project using buildout.
-
-* **layer** -
-  A layer for the view.
-
-* **local utility** -
-  A local utility is an object which provides an interface, and can be looked-up
-  by that interface and optionally the component name. The attributes provided 
-  by a local utility are transparently stored in the database (ZODB). This means
-  that configuration changes to a local utility lasts between server restarts.
-
-* **martian** - 
-  ...
-
-* **megrok** - 
-  ...
-
-* **(Grok) model** - 
-  Model objects provide persistence and containment. Model in Grok refers to an 
-  applications data model - that is data which is persistently saved to disk, by
-  default in the Zope Object Dataabse (ZODB).
-
-* **Python Cheeseshop** -
-  ...
-
-* **(Grok) site** - 
-  Contains a Site Manager. Site Managers act as containers for registerable 
-  components.
-
-* **skin** - 
-  A named layer.
-
-* **(Grok) view** - 
-  Views handle interactions between the user and the model. 
-
-* **viewlet** - 
-  Viewlets are a flexible way to compound HTML snippets.
-
-* **viewlet manager** - 
-  A ViewletManager is a component that provides access to a set of content 
-  providers (Viewlets). 
-
-* **zc.buildout** - 
-  see buildout
-
-* **zc.resourcelibrary** - 
-  ...
-
-* **ZCML** - 
-  Zope Configuration Markup Language
-
-* **ZODB** - 
-  Zope Object Database
-
-* **ZPT** -
-  Zope Page Template
-
-

Deleted: grok/trunk/doc/grok_overview.rst
===================================================================
--- grok/trunk/doc/grok_overview.rst	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/grok_overview.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,1374 +0,0 @@
-Grok Developer's Notes
-======================
-
-This document is a developer's overview of Grok. It is not intended to
-be a beginner's tutorial. It's also not a reference. It gives a
-succinct an overview of *what's there* in Grok, with a brief idea on
-how to use it, so you can try it out and learn more about it. This
-includes rules, common APIs and patterns.
-
-Models
-------
-
-A Grok-based application is composed out of one or more *models*. We
-also call these *content objects*, or just *objects*. The objects are
-just Python objects, instantiated from a class. Models can be stored
-in the object database (ZODB), created by an object relational mapper,
-or created on the fly by your code.
-
-Grok comes with two kinds of models: ``grok.Model`` and
-``grok.Container``. ``grok.Model`` is the most basic one and doesn't
-really do much for you. You can subclass from ``grok.Model``, like
-this::
-
-  class Document(grok.Model):
-      pass
-
-The main thing subclassing from ``grok.Model`` does is make it
-possible (but not required) to store instances in the ZODB.
-
-You can also subclass from ``grok.Container``, like this::
-
-  class Folder(grok.Container):
-      pass
-
-A container is like a model, but also acts much like a Python
-dictionary. The main difference with Python dictionaries is that its
-methods, like ``keys`` and ``items``, are iterator-like. They also do
-more, like send events, but we can forget about that for now.
-
-In order to be able to install an application, you need to mix in
-``grok.Application`` into a class::
-
-  class Application(grok.Application, grok.Container):
-      pass
-
-Instances of this class can now be installable in the Grok web UI.
-
-Let's make a structure with some folders and documents::
-
-  app = Application()
-  app['a'] = a = Container()
-  a['b'] = Document()
-  a['c'] = Container()
-  a['c']['d'] = Document()
-
-Grok publishes these objects to the web: this is called object
-publishing. What this means in essence is that objects can be
-addressed with URLs. When you access a URL of a Grok application with
-your web browser, Grok uses this URL to find an object.
-
-An example: if ``app`` were installed under
-``http://localhost:8080/app``, the following URLs will exist in your
-application::
-
-  http://localhost:8080/app
-  http://localhost:8080/app/a
-  http://localhost:8080/app/a/b
-  http://localhost:8080/app/a/c
-  http://localhost:8080/app/a/c/d
-
-``__parent__`` and ``__name__``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Models in Grok are automatically supplied with a ``__parent__`` and a
-``__name__`` attribute.
-
-* ``__parent__`` points to object this object is in. If the object is in
-  a container, this is the container.
-
-* ``__name__`` is the name this object has in a URL (and in its
-  container, if it is in a container).
-
-These attributes are used for navigation through content space, and
-Grok also uses them to construct URLs automatically (see below). The
-``__parent__`` and ``__name__`` attributes are automatically added to
-an object when it is placed in a container, or when it is being
-traversed through using ``traverse``.
-
-Custom traversing
-~~~~~~~~~~~~~~~~~
-
-Grok resolves URLs to objects by *traversing* through the containers
-and models in question. What if you want to customize the way this
-traversal works? Perhaps you want to traverse through objects you
-create yourself, or objects created by an object relational
-mapper. Grok offers a handy way to do so: the ``traverse`` method on
-models.
-
-A math example: imagine you want to create an application that
-represents integer numbers, and you want to traverse to each
-individual number, like this::
-
-  http://localhost:8080/integers/0
-  http://localhost:8080/integers/1
-  http://localhost:8080/integers/2
-  http://localhost:8080/integers/3
-  ...
-
-and so on. How would we implement this? We cannot create a container
-and fill it with all integers possible, as there are an infinite
-number of them. Okay, so we are in a math example, so let's be exact:
-this is true if we ignore memory limitations and URL length
-limitations. Storing all possible integers in a container is just not
-*practical*.
-
-We use the ``traverse`` method::
-
-  class ParticularInteger(grok.Model):
-      def __init__(self, number):
-          self.number = number
-
-  class Integers(grok.Application, grok.Model):
-      def traverse(self, name):
-          try:
-               value = int(name)
-          except ValueError:
-               return None # not an integer
-          return ParticularInteger(value)
-
-Now all URLs for numbers are available. What's more, other URLs like
-this are not::
-
-  http://localhost:8080/integers/foo
-
-The ``traverse`` method works by trying to convert the path element
-that comes in as ``name`` to an integer. If it fails, we return
-``None``, telling Grok that the ``traverse()`` method didn't find the
-object asked for. Grok then falls back on default behavior, which in
-this case would mean a ``404 Not Found`` error.
-
-Traversable attributes
-~~~~~~~~~~~~~~~~~~~~~~
-
-In some cases, you want to traverse to attributes or methods of your
-``grok.Model``. This can be done easily using the ``grok.traversable``
-directive::
-
-  class Mammoth(grok.Model):
-      grok.traversable('trunk')
-
-      trunk = Trunk()
-
-  class MammothView(grok.View):
-      grok.context(Mammoth)
-
-      def render(self):
-          return "I'm a mammoth!"
-
-Now, if traversing to http://localhost/mammoth/trunk , a Trunk()
-object will be exposed at that URL.
-
-Views
------
-
-Now that we have models and can build structures of them, we will need
-to look at ways to actually present them to the user: views. So what
-is a view? A view is a class that represents a model in some way. It
-creates a user interface of some sort (typically HTML) for a model. A
-single model can have more than one view. It looks like this::
-
-  class Index(grok.View):
-      grok.context(Application)
-
-      def render(self):
-          return "This is the application"
-
-The ``grok.context`` bit in the class is an example of using a *Grok
-directive*. If you use ``grok.context`` on a view class, it connects
-the view to the class we give it. So in this case, ``Index`` is a view
-for ``Application``. Note that if there is only a single model in the
-module and you want your view to be associated with it, you can leave
-out ``grok.context`` and the view will be associated with that model
-by default. Many directives have such default behavior, allowing you
-to leave them out of your code if you organize your code in a certain
-way.
-
-The default view for a model is called ``index``. You can specify
-``index`` at the end of the URL, like this::
-
-  http://localhost:8080/app/index
-
-What happens when you go to this URL is that Grok instantiates the
-``Index`` class, creating a ``Index`` instance. View instances have
-a number of attributes by default:
-
-  * ``context``, the model instance that the view is presenting.
-
-  * ``request``, the current web request.
-
-  * ``response``, an object representing the response sent to the
-                  user.  Used less often.
-
-``index`` views are special, as it's also fine not to add ``index`` at
-the end, because the name ``index`` is the default::
-
-  http://localhost:8080/app
-
-You can also create views with different names::
-
-  class Edit(grok.View):
-      grok.context(Application)
-
-      def render(self):
-          return "This is the edit screen for the application"
-
-Now you can go to this URL::
-
-   http://localhost:8080/app/edit
-
-The name of the view is the name of the view class, lowercased. This
-is the default behavior: you can override this using the ``grok.name``
-directive::
-
-  class SomeImpossiblyLongClassName(grok.View):
-      grok.context(Application)
-      grok.name('edit')
-
-      def render(self):
-          return "This is the edit screen for the application"
-
-Templates
-~~~~~~~~~
-
-In the previous examples, we used the ``render`` method to determine
-what you actually see on a web page. For most views we don't want to
-do that: we want to use a template to prepare presentation. Using a
-template with a view is easy.  First create a directory
-``<name>_templates``, where ``<name>`` is the the module that contains
-the views. So, if you are developing in a module ``app.py``, you need
-to create a subdirectory ``app_templates`` for templates in the same
-directory as the ``app.py`` module.
-
-You can then add templates to that directory with the same name as the
-view class name (lowercase), with the ``.pt`` extension
-appended. These templates follow the Zope Page Template (ZPT) rules,
-though Grok can also be extended to support other template languages.
-
-You could for instance have this view::
-
-  class Index(grok.View):
-      grok.context(Application)
-
-and a file ``index.pt`` in the module's templates directory containing
-template code.
-
-These are the defaults. If for some reason you want the name of the
-template directory not to be based on the name of module, you can
-manually set the name of the template directory used by a module by
-using the ``grok.templatedir`` directive in the module. If you want
-the name of the template not to be based on the name of the class, you
-use the ``grok.template`` directive in the view class.
-
-The template can access attributes and methods on the view through the
-special ``view`` name available in the template. The template can
-access attributes and methods on the model through the special
-``context`` name available in the template. The template has the
-following special names available::
-
-* ``view`` - the view that this template is associated with
-
-* ``context`` - the model that is being viewed
-
-* ``request`` - the current request object
-
-* ``static`` - to make URLs to static content made available by this module
-
-and any names you also make available using the ``namespace`` method.
-
-static content
-~~~~~~~~~~~~~~
-
-A typical web page references one or more CSS files, javascript files
-and images: static content that is part of the layout.
-
-To make available static content to your template create a directory
-in your package called ``static``. Put ``.css`` files, ``.js`` files,
-image and whatever else is needed in there.
-
-You can now refer to these static files in your template using the
-special name ``static``, like this (ZPT example)::
-
-  <img tal:attributes="src static/my_image.png" />
-
-This will automatically create a URL to the place where Grok published
-that image.
-
-You can create subdirectories in ``static`` and refer to them as you'd
-expect::
-
-  <image tal:attributes="src static/images/some_image.gif" />
-
-``update``
-~~~~~~~~~~
-
-You can define an ``update`` method in a view to prepare a view just
-before it is accessed. You can use this to process information in the
-request (URL parameters or form variables) or in the context, and set
-attributes on the view that can be used in the template::
-
-  def update(self):
-      self.total = int(self.request.form['a']) + int(self.request.form['b'])
-
-The template now has access to ``view.total``.
-
-You can define parameters in the update view. These will be
-automatically bound to parameters (or form values) in the request::
-
-  def update(self, a, b):
-      self.total = int(a) + int(b)
-
-``namespace``
-~~~~~~~~~~~~~
-
-If you just want a variable to become available in the top-level of
-your template (much like ``view`` and ``model``), you can also define
-the ``namespace`` method on the view::
-
-  def namespace(self):
-      return {'foo': "Some value"}
-
-You can now refer to ``foo`` in your template and have available to
-this value.
-
-the ``url`` method
-~~~~~~~~~~~~~~~~~~
-
-Views have a special method called ``url()`` that can be used to
-create URLs to objects. The ``url`` method takes zero, one or two
-arguments and an additional optional keyword argument 'data' that
-is converted into a CGI query string appended to the URL::
-
-* self.url() - URL to this view.
-
-* self.url(object) - URL to the provided object.
-
-* self.url(u"name") - URL to the context object, with ``/name`` appended,
-                   to point to a view or subobject of the context.
-
-* self.url(object, u"name") - URL to the provided object, with
-  		   ``/name`` appended, to point to a view or subobject
-  		   of the provided object.
-
-* self.url(object, u"name", data={'name':'Peter', 'age':28})
-            - URL to the provided object, with ``/name`` appended
-              with '?name=Peter&age=28' at the end.
-
-* self.url(data={'name':u'Andr\xe9', 'age:int':28}) - URL to the provided
-                   object with '?name=Andre%C3%A9'&age%3Aint=28'.
-
-From the view, this is accessed through ``self.url()``. From the
-template, this method can be accessed using ``view.url()``.
-
-the ``application_url`` method
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When using views it is sometimes desirable to be able to construct a
-URL to the application object. ``application_url`` is a quick way to
-do it.  It takes a single optional argument, name, which is the name
-of a view of the application.
-
-the ``redirect`` method
-~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``redirect`` method on views can be used to redirect the browser
-to another URL. Example::
-
-   def render(self):
-       self.redirect(self.url(self.context.__parent__))
-       # return empty body as we are going to redirect anyway
-       return ''
-
-``__parent__`` and ``__name__`` on views
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Like models, views also get supplied with a ``__parent__`` and
-``__name__`` object when they are instantiated for a particular model.
-
-``__parent__`` points to the model being viewed (and is the same as
-``context``, which should normally be used).
-
-``__name__`` is the name of the view in the URL.
-
-The ``@@`` thing
-~~~~~~~~~~~~~~~~
-
-Supposing you have a view called ``edit``, whenever you write this::
-
-  http://localhost:8080/app/edit
-
-you can also write this::
-
-  http://localhost:8080/app/@@edit
-
-Why the ugly ``@@`` syntax? Imagine that ``app`` is a container, and
-that your user interface lets the user add objects to it with a name
-of their own choosing. The user could decide to add an object called
-``index``. In that case Grok wouldn't know whether the
-``http://localhost:8080/app/index`` index is to get to a view or a
-subobject. ``@@`` tells the system to look up a view definitely. If
-``@@`` is not provided, subobjects take precedence over views in case
-of name collision.
-
-Request
--------
-
-Some useful things to know about the request object (accessible as an
-attribute on the view):
-
-Information on the ``request`` object can be accessed using mapping
-access (``request[`foo`]``). You can access request form variables and
-cookies and headers (including `environment variables`_).
-
-.. _`environment variables`: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
-
-To access form variables in particular use: ``request.form['foo']``.
-
-To access cookies in particular use: ``request.cookies['foo']``.
-
-To access headers (and environment variables) in particular use:
-``request.headers['foo']``. You can also use ``request.getHeader()``,
-with the header name as the argument, and an optional second default
-argument.
-
-Instead of the mapping access, the ``get`` methods work as well, as on
-normal Python dictionaries.
-
-More can be found in the ``IHTTPRequest`` interface documentation
-in ``zope.publisher.interfaces.http``.
-
-Response
---------
-
-Some useful things to know about the response object (accessible as
-an attribute on the view):
-
-``setStatus(name, reason)`` sets the HTTP status code. The argument
-may either be an integer representing the status code (such as ``200``
-or ``400``), or a string (``OK``, ``NotFound``). The optional second
-argument can be be used to pass the human-readable representation
-(``Not Found``).
-
-``setHeader(name, value)`` can be used to set HTTP response headers. The first
-argument is the header name, the second the value.
-
-``addHeader(name, value)`` can be used to add a HTTP header, while
-retaining any previously set headers with the same name.
-
-``setCookie(name, value, **kw)`` can be used to set a cookie. The first
-argument is the cookie name, the second the value. Optional keyword
-arguments can be used to set up further cookie properties (such as
-``max_age`` and ``expires``).
-
-``expireCookie(name, **kw)`` can be used to immediately expire a
-cookie.
-
-More can be found in the ``IHTTPResponse`` interface documentation
-in ``zope.publisher.interfaces.http``.
-
-Adapters
---------
-
-An adapter is much like a view, but is aimed towards developers, not
-end users. It presents an interface to an object, but an interface for
-developers, not an user interface for end-users.
-
-The section on adapters will of necessity be rather abstract. Feel
-free to skip it until you want to know what is going on up with
-interfaces and adapters - it is an important foundation to Grok, but one
-you do not know much about when you get started.
-
-An adapter can be used to add new methods to an object without
-changing the object. To demonstrate the principle, we will construct
-adapters entirely by hand first. At the end we will show how Groks
-helps in constructing adapters and using them.
-
-Imagine we are developing a content management system and we want to
-get information about the size (in, say, bytes, approximately) of
-content objects stored in our CMS, for instance in order to display it
-in our UI or to calculate the total size of all objects in a
-container. The simplest approach would be to add a ``size()`` method
-to all our content objects::
-
-  class Document(grok.Model):
-       def __init__(self, text):
-           self.text = text
-
-       def size(self):
-           return len(self.text.encode('UTF-8'))
-
-  class Image(grok.Model):
-       def __init__(self, data):
-            self.data = data
-
-       def size(self):
-            return len(self.data)
-
-  class Container(grok.Container):
-        def size(self):
-            total = 0
-            for obj in self.values():
-                total += obj.size()
-            return total
-
-For simple cases this is fine, but for larger applications this can
-become a problem. Our ``Document`` model needs a ``size`` method, and
-does our ``Image`` model, and our ``Container``, and our ``News Item``
-model, and so on. Given the requirements of a typical CMS, content
-objects would soon end up with a very large number of methods, for all
-sorts of functionality, from getting the size of objects to offering a
-commenting facility. It would be nicer to separate things out and keep
-the underlying models clean.
-
-To do this, we can use the adaptation pattern. As said, we will do it
-by hand at first. An adapter is an object that adds an API to another
-object (typically stored as the ``context`` attribute of the
-adapter)::
-
-  class DocumentSized(object):
-      def __init__(self, context):
-          self.context = context
-
-      def size(self):
-          return len(self.context.text.encode('UTF-8'))
-
-We would use it like this::
-
-   DocumentSized(document).size()
-
-We could extend this same adapter to work for different kinds of
-content objects, but that isn't very extensible when new adapters need
-to be made::
-
-  class Sized(object):
-      def __init__(self, context):
-          self.context = context
-
-      def size(self):
-          if isinstance(self.context, Document):
-               return len(self.context.text.encode('UTF-8'))
-          elif isinstance(self.context, Image):
-               return len(self.context.data)
-          elif isintance(self.context, Container):
-               total = 0
-               for obj in self.context.values():
-                   total += Sized(obj).size()
-               return total
-
-Instead, we can create a smart ``sized`` factory that does this
-switch-on-type behavior instead, keeping our adapters clean::
-
-  class DocumentSized(object):
-      def __init__(self, context):
-          self.context = context
-
-      def size(self):
-          return len(self.context.text.encode('UTF-8'))
-
-  class ImageSized(object):
-      def __init__(self, context):
-          self.context = context
-
-      def size(self):
-          return len(self.context.data)
-
-  class ContainerSized(object):
-      def __init__(self, context):
-          self.context = context
-
-      def size(self):
-          total = 0
-          for obj in self.context.values():
-              total += sized(obj).size()
-          return total
-
-  def sized(context):
-      if isinstance(context, Document):
-          return DocumentedSized(context)
-      elif isinstance(context, Image):
-          return ImageSized(context)
-      elif isinstance(context, Container):
-          return ContainerSized(context)
-
-We can now call ``sized`` for a content object and get an object back
-that implements the "sized API"::
-
-   s = sized(my_content_object)
-   print s.size()
-
-It's good to spell out the APIs of your application explicitly, as
-documentation so that other developers can work with them and also
-implement them for their own content objects. Grok lets you do this
-using an *interface* specification, using the ``zope.interface``
-package::
-
-  from zope.interface import Interface
-
-  class ISized(Interface):
-      def size():
-           "Return the size of the object"
-
-We can now make this ``ISized`` interface into the adapter factory
-(like ``sized`` above), without actually having to implement it
-directly. Let's do that now by subclassing from ``grok.Adapter`` and
-using a few grok directives::
-
-  class DocumentSized(grok.Adapter):
-      grok.context(Document)
-      grok.provides(ISized)
-
-      def size(self):
-          return len(self.context.text.encode('UTF-8'))
-
-  class ImageSized(grok.Adapter):
-      grok.context(Image)
-      grok.provides(ISized)
-
-      def size(self):
-          return len(self.context.data)
-
-  class ContainerSized(grok.Adapter):
-      grok.context(Container)
-      grok.provides(ISized)
-
-      def size(self):
-          total = 0
-          for obj in self.context.values():
-              total += ISized(obj).size()
-          return total
-
-We can now use ``ISized`` like we used ``sized`` above::
-
-   s = ISized(my_content_object)
-   print s.size()
-
-When new content objects were to be created for this CMS, ``ISized``
-adapters can be registered for them anywhere. Using this pattern,
-existing objects implemented by someone else can be made to conform
-with the ``ISized`` API without having to modify them.
-
-``grok.context`` works as for views. It is useful to point it to any
-class however, not just that of models. ``grok.provides`` has to be
-pointed to an interface (the interface that the adapter *adapts to*).
-
-Interfaces
-~~~~~~~~~~
-
-Classes can also be made to *implement* an interface. This means that
-instances of that class *provide* that interface::
-
-  from zope.interface import Interface, Attribute
-
-  class IAnimal(Interface):
-      name = Attribute("The name of the animal")
-
-      def makeSound():
-          "The sound the animal makes."
-
-  class Cow(object):
-      grok.implements(IAnimal)
-
-      def __init__(self, name):
-          self.name = name
-
-      def makeSound(self):
-          return "Mooo"
-
-We can ask the interface machinery whether an object provides an interface::
-
-  >>> cow = Cow()
-  >>> IAnimal.providedBy(cow)
-  True
-
-If you use an interface to adapt an object, and this object already
-provides the interface, you get back the object itself::
-
-  >>> IAnimal(cow) is cow
-  True
-
-``grok.context`` can always point to an interface instead of a class
-directly. This indirection can be useful to make a view or adapter
-work for a whole set of classes that all implement the same interface.
-
-``ComponentLookupError``
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-What if an adapter cannot be found for a particular object? Perhaps no
-adapter has been registered for a particular object or a particular
-interface. The system will raise a ``ComponentLookupError``::
-
-  >>> ISized(cow)
-  Traceback (most recent call last):
-    ...
-  ComponentLookupError
-
-If you want to catch this exception, you can import it from
-``zope.component.interfaces``::
-
-  from zope.component.interfaces import ComponentLookupError
-
-Named adapters
-~~~~~~~~~~~~~~
-
-It is possible to give an adapter a name, making it a *named
-adapter*. This way it is possible to have more than one adapter
-registered for a single object that all provide the same interface,
-each with a different name. This feature is rarely used directly,
-but internally it is used for views, as we will see later. The
-``grok.name()`` directive can be used to give an adapter a name::
-
-  class Adapter(object):
-      grok.name('somename')
-      grok.context(SomeClass)
-      grok.provides(ISomeInterface)
-
-Actually all adapters are named: by default the name of an adapter is
-the empty string.
-
-You cannot call the interface directly to get a named adapter for an
-object.  Instead, you need to use the APIs provided by the
-``zope.component`` package, in particular ``getAdapter``::
-
-  from zope import component
-
-  my_adapter = component.getAdapter(some_object, ISomeInterface,
-                                   name='somename')
-
-``getAdapter`` can also be used to look up unnamed adapters, as an
-alternative to using the interface directly::
-
-  myadapter = component.getAdapter(some_object, ISomeInterface)
-
-Functions as adapters
-~~~~~~~~~~~~~~~~~~~~~
-
-Sometimes an adapter doesn't need to be a full-fledged class;
-registering the factory function itself is enough. We can do this with
-the ``@grok.adapter`` and ``@grok.implementer`` decorators. This way
-we can write simple adapters that don't need to return a full-fledged
-custom class instance but for instance some built-in Python object
-like a string::
-
-  @grok.adapter(SomeClass)
-  @grok.implementer(ISomeInterface)
-  def some_interface_for_some_class(some_instance):
-      return str(some_instance)
-
-You can now do the following::
-
-  some_instance = SomeClass()
-  s = ISomeInterface(some_instance)
-  print s
-
-``ISomeInterface`` now behaves much like ``str`` for ``SomeClass``.
-
-Multi adapters
-~~~~~~~~~~~~~~
-
-Another feature of adapters is that you can adapt multiple objects at
-once using a *multi adapter*. Again this feature is rarely used in
-practice, except internally to implement views and events.
-
-You can construct a multi adapter by subclassing from
-``grok.MultiAdapter``::
-
-  class MyMultiAdapter(grok.MultiAdapter):
-      grok.adapts(SomeClass, AnotherClass)
-      grok.provides(ISomeInterface)
-
-      def __init__(some_instance, another_instance):
-          self.some_interface = some_instance
-          self.another_instance = another_instance
-
-The multi-adapter receives as many arguments as what it was registered
-for using ``grok.adapts``.
-
-A multi adapter also cannot be looked up directly by calling the
-interface. Instead, we need to use the ``zope.component`` package
-again::
-
-  from zope import component
-
-  my_multi_adapter = component.getMultiAdapter((some_object, another_object),
-                                               ISomeInterface)
-
-``getMultiAdapter`` receives as the first argument a tuple with the
-combination of objects to adapt.
-
-It can also optionally be named using ``grok.name`` and then looked up
-using a name argument::
-
-  my_named_multi_adapter = component.getMultiAdapter(
-      (some_object, another_object), ISomeInterface, name="foo")
-
-Views as adapters
-~~~~~~~~~~~~~~~~~
-
-A view in Grok is in fact a named multi adapter, providing the base
-interface (``Interface``). This means that a view in Grok can be
-looked up in code by the following call::
-
-  from zope.interface import Interface
-
-  view = component.getMultiAdapter((object, request), Interface, name="index")
-
-Since the default for the second argument is in fact ``Interface``, this
-call can be shorted to this::
-
-  view = component.getMultiAdapter((object, request), name="index")
-
-Being able to do this in code is sometimes useful. It is also what
-Grok does internally when it looks up a view.
-
-Events
-------
-
-Grok lets you write handlers for *events*. Using event handlers you
-can hook into code that you do not control. Events allow decoupling: a
-framework can send events without worrying who is interested in it,
-and similarly you can send events to work with existing bits of
-framework that expects them. You can also define new types of events
-if you are designing a framework yourself.
-
-You write an event handler by writing a function that *subscribes* to
-the event, and marking it with a python decorator::
-
-  @grok.subscribe(Document, grok.IObjectAddedEvent)
-  def handle(obj, event):
-      print "Object %s was added." % obj
-
-Whenever an instance of a model of class ``Document`` (or subclasses)
-is added to a container, this code will be run. You can then take some
-action. Any ``grok.Container`` subclass will take care of sending
-these events automatically.  You can have as many subscribers for a
-particular event as you like.  The order in which they are run is not
-guaranteed by the system, so cannot be relied on.
-
-The event handler takes two arguments: the object for which the event
-was fired, and the event instance. The event instance has attributes,
-depending on the type of event.
-
-Events defined by Grok
-~~~~~~~~~~~~~~~~~~~~~~
-
-Here we describe the standard events defined by Grok. Described are
-the interfaces which you would use in a subscriber, and how you can
-send this event yourself. Other events may be defined by libraries or
-by you.
-
-``IObjectMovedEvent``
-+++++++++++++++++++++
-
-Will be fired whenever an object is moved from container to container,
-renamed, added or removed.
-
-The event object has these attributes:
-
-* ``object`` - the object being moved
-
-* ``oldParent`` - the parent (container) from which the object was moved
-                  or removed, or ``None`` if this object is newly added.
-
-* ``oldName`` - the previous name of the object in its container,
-                before renaming if renaming took place, or ``None`` if
-                this object is newly added.
-
-* ``newParent`` - the parent (container) to this object was moved or
-                added. ``None`` if this object was removed.
-
-* ``newName`` - the name the object has in the new container, or ``None``
-                if this object was removed.
-
-Containers take care of sending this event, but should you want to
-send it yourself, use::
-
-  grok.notify(grok.ObjectMovedEvent(obj, oldParent, oldName, newParent, newName))
-
-``IObjectAddedEvent``
-+++++++++++++++++++++
-
-Fired when an object is added to a container. Specialization of
-``IObjectMovedEvent``, and shares the attributes as described.
-
-Containers take care of sending this event, but should you want to send it
-yourself, use::
-
-  grok.notify(grok.ObjectAddedEvent(obj))
-
-or::
-
-  grok.notify(grok.ObjectAddedEvent(obj, newParent, newName))
-
-``IObjectRemovedEvent``
-+++++++++++++++++++++++
-
-Fired when an object is removed from a container (and not re-added
-elsewhere). Specialization of ``IObjectMovedEvent``, and shares the
-attributes as described.
-
-Containers take care of sending this event, but should you want to send it
-yourself, use::
-
-  grok.notify(grok.ObjectRemovedEvent(obj)
-
-or::
-
-  grok.notify(grok.ObjectRemovedEvent(obj, oldparent, oldName))
-
-``IObjectModifiedEvent``
-++++++++++++++++++++++++
-
-Fired when an object is modified by the system, such as when a form is
-saved. If you modify the object in code, the system won't know about
-this, and you will have to remember to send it yourself.
-
-This event has a single attribute, ``object``, which is the object
-that was modified.
-
-To send this event yourself, use::
-
-  grok.notify(grok.ObjectModifiedEvent(obj))
-
-``IContainerModifiedEvent``
-+++++++++++++++++++++++++++
-
-A specialization of ``IObjectModifiedEvent`` that fires when the
-container was modified by adding something to it or removing from it.
-
-Containers take care of sending this event, but if you want to send it
-yourself, use::
-
-  grok.notify(grok.ContainerModifiedEvent(obj))
-
-``IObjectCreatedEvent``
-+++++++++++++++++++++++
-
-Fired when an object is created. When you create your own objects the
-system won't know about this, and you will have to remember to send it
-yourself if you care about listing to ``IObjectCreatedEvent``. This is
-fairly rare - usually you're better of looking at
-``IObjectAddedEvent`` if you can.
-
-This event has a single attribute, ``object``, which is the object
-that was created.
-
-To send this event yourself::
-
-  grok.notify(grok.ObjectCreatedEvent(obj))
-
-``IObjectCopiedEvent``
-++++++++++++++++++++++
-
-Fired when an object was copied. It is a specialization of
-``IObjectCreatedEvent`` that is fired by the system if you use the
-``zope.copypastemove`` functionality.
-
-Besides the ``object`` attribute it shares with
-``IObjectCreattedEvent``, it has also has the ``original`` attribute,
-which was the object that iwas copied from.
-
-To send this event yourself::
-
-  grok.notify(grok.ObjectCopiedEvent(copy, original))
-
-``IBeforeTraverseEvent``
-+++++++++++++++++++++++++
-
-Fired when the publisher is about to traverse into your object. This
-is useful to specify on your application object if you for instance
-want to set the default skin for your application.
-
-Creating and sending your own events
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you are going to send an object that pertains to a particular object,
-subclass ``zope.component.interfaces.ObjectEvent``::
-
-  from zope.component.interfaces import ObjectEvent
-
-  class MyEvent(ObjectEvent):
-      pass
-
-You can then send it like this::
-
-  grok.notify(MyEvent(some_obj))
-
-And listen for it like this::
-
-  @grok.subscribe(SomeClass, MyEvent)
-  def handle_my_event(obj, event):
-      pass
-
-This subclassing from ``ObjectEvent`` is not required; if your event
-isn't about an object, you can choose to design your event class
-entirely yourself. See ``zope.sendmail`` for the construction of mail sending
-events for an example.
-
-Interfaces for events
-~~~~~~~~~~~~~~~~~~~~~
-
-For documentation purposes it can be a good idea to to define an
-interface for your event. You can then also allow for multiple
-implementations of the same event interface. When you have an
-interface for your event, you can then listen for the interface in the
-subscribers as well::
-
-  from zope.interface import Interface
-
-  class IMyEvent(zope.component.interfaces.IObjectEvent):
-      "My special event"
-
-  class MyEvent(zope.component.interfaces.ObjectEvent):
-      grok.implements(IMyEvent)
-
-  @grok.subscribe(SomeClass, IMyEvent):
-  def handle_my_event(obj, event):
-      pass
-
-More about interfaces
----------------------
-
-We have seen small examples of interfaces before, but here we will go
-a bit more into them, and why they are useful.
-
-An *interface* is a description of the API of a class (or more rarely,
-module or object). Interfaces are useful because:
-
-* They are API documentation.
-
-* They can describe how a framework expects you to implement classes
-  that fit into it.
-
-* The system can inspect the interfaces a particular object provides,
-  and treat them as an abstract form of classes for registration
-  purposes.
-
-Interfaces make it possible to use a generic framework's pluggability
-points with confidence: you can clearly see what you are supposed to
-implement to plug into it. You can define very generic frameworks
-yourself by defining them in terms of interfaces.
-
-Some interface features
-~~~~~~~~~~~~~~~~~~~~~~~
-
-A summary of interface features we've seen:
-
-* To create an interface, subclass from ``zope.interface.Interface``.
-
-* To state that implementors of the interface must have a method, supply
-  the method with arguments. Don't use ``self`` as the first
-  arguments, as this is an implementation detail not important to the
-  interface. Instead, describe the methods as they look to the caller.
-
-* To state that implementors of the interface must have an attribute, use::
-
-    some_attribute = zope.interface.Attribute("Description of attribute")
-
-* To state a class *implements* an interface, use ``grok.implements``.
-
-* Instances of a class are said to *provide* the interface that the
-  class *implements*.
-
-* You can check whether an instance provides a certain interface by using
-  ``some_interface.providedBy``::
-
-     IObjectEvent.providedBy(NonSubclassEvent(some_obj))
-
-Interfaces and events
-~~~~~~~~~~~~~~~~~~~~~
-
-Let's study interfaces some more in connection with
-``IObjectModifiedEvent``. The ``IObjectModifiedEvent`` interface looks
-like this::
-
-  class IObjectModifiedEvent(zope.component.interfaces.IObjectEvent):
-      """An object has been modified"""
-
-This refers us to the ``IObjectEvent`` interface, which looks like
-this::
-
-  from zope import interface
-
-  class IObjectEvent(interface.Interface):
-      """An event related to an object.
-      """
-
-      object = interface.Attribute("The subject of the event.")
-
-We therefore know that if we implement ``IObjectModifiedEvent``, we
-must supply a single attribute, ``object``.
-
-The following event handler for instances of ``SomeClass`` subscribes
-to *any* event that provides ``IModifiedObjectEvent``::
-
-   @grok.subscribe(SomeClass, IObjectModifiedEvent):
-   def handle_event(obj, event):
-       "Called when there is an IObjectModifiedEvent for SomeClass instances."
-
-This handler will be called not only for subclasses of the
-``grok.ObjectModifiedEvent`` class, but also for other, otherwise
-unrelated classes that implement ``IObjectEvent``, such as this one::
-
-  class NonSubclassObjectEvent(object):
-      grok.implements(IObjectEvent)
-
-      def __init__(self, object):
-           self.object = object
-
-So far we have only used interfaces for the second argument of the
-event handler registration, but the principle also works for the first
-argument. For example, to handle ``IObjectModifiedEvent`` events for
-all kinds of containers, you can subscribe to
-``zope.container.interfaces.IContainer`` objects::
-
-  @grok.subscribe(IContainer, IObjectModifiedEvent):
-  def handle_event(obj, event):
-      "Called whenever any container is modified"
-
-``zope.container.interfaces.IContainer`` defines the abstract
-container API that all containers must provide, no matter how they are
-implemented internally.
-
-Interfaces and adapters
-~~~~~~~~~~~~~~~~~~~~~~~
-
-The same principle also works for adapters and ``grok.context``. You
-can use ``grok.context`` with interfaces as well as with concrete
-classes. To write an adapter that works for any kind of container, you
-can write::
-
-  from zope.container.interfaces import IContainer
-
-  class SortedKeysAdapter(grok.Adapter):
-      grok.context(IContainer)
-      grok.provides(ISortedKeys)
-
-      def sortedKeys(self):
-          return sorted(self.context.keys())
-
-Interfaces and views
-~~~~~~~~~~~~~~~~~~~~
-
-The same principle can also be used with ``grok.context`` in other
-places, such as in views. This view is registered for all containers::
-
-  from zope.container.interfaces import IContainer
-
-  class Keys(grok.View):
-     grok.context(IContainer)
-
-     def render(self):
-         return ', '.join(ISortedKeysAdapter(self.context).sortedKeys())
-
-The view ``keys`` exists for all containers, no matter how they are
-implement, where they are implemented or who implemented them, as long
-as they provide ``IContainer``.
-
-Using the fact ``Interface`` is the base of all interfaces, you can
-even register a view for *all* objects. This can be useful to register
-ZPT macros, which will then be available on all contexts::
-
-  class Layout(grok.View):
-      grok.context(Interface)
-
-with a template ``layout.pt`` associated to it.
-
-You can then use these macros in any page template anywhere by
-referring to them like this::
-
-  <html metal:use-macro="context/@@layout/macros/page">
-
-Forms
------
-
-Grok can autogenerate web forms from descriptions called *schema*. A
-schema is a special kind of interface. We already saw ``Attribute``,
-which can be used to specify that something that provides that
-interface should have that attribute. The ``zope.schema`` package adds
-a lot more specific field descriptions. Here is an example of a
-schema::
-
-  from zope.interface import Interface
-  from zope import schema
-
-  class ISpecies(Interface):
-      name = schema.TextLine(u"Animal species name")
-      scientific_name = schema.TextLine(u"Scientific name")
-      legs = schema.Int(u"Number of legs")
-
-Let's also look at a simple implementation of this interface::
-
-  class Species(grok.Model):
-      grok.implements(ISpecies)
-
-Note how we aren't even creating an ``__init__`` to set the
-attributes; we could, but we'll see below that Grok's ``applyData``
-can take care of this automatically.
-
-The ``ISpecies`` schema can be turned into a form. Grok does this by
-looking up a *widget* for each schema field to display it. A widget is
-very much like a view. Let's look at a form for this schema::
-
-  class Species(grok.Form):
-      form_fields = grok.Fields(ISpecies)
-
-      @grok.action(u"Save form")
-      def handle_save(self, **data):
-          print data['name']
-          print data['scientific_name']
-          print data['legs']
-
-What is going on here? Firstly we use a special base class called
-``grok.Form``. A form is a special kind of ``grok.View``, and
-associates the same way (using ``grok.context``). A form expects two
-things:
-
-* a ``form_fields`` attribute. Above we see the most common way to construct
-  this attribute, using ``grok.Fields`` on the interface.
-
-* one or more actions. Actions are specified by using the
-  ``@grok.action`` decorator. An action gets the fields filled in the
-  form as keyword parameters, so ``**data`` in this case. We could
-  also have specified the arguments we expected specifically.
-
-Form widgets translate the raw HTML form input to Python objects, such
-as (unicode) strings, integers and datetime objects, as specified by
-schema fields. The schema fields can then be used to validate this
-input further. Forms are self-submitting, and in case of a validation
-error the form can render them in-line next to the fields.
-
-We'll look at a lot of form features next.
-
-``grok.AddForm``
-~~~~~~~~~~~~~~~~
-
-An add form is used to create a new object. Most forms are views of
-the object that they are representing, but an add form is typically
-associated a view of the container in which new objects are to be
-added. Let's look at an example::
-
-  class SpeciesContainer(grok.Container):
-      pass
-
-  class Add(grok.AddForm):
-      grok.context(SpeciesContainer)
-
-      form_fields = grok.Fields(ISpecies)
-
-      @grok.action(u"Add species")
-      def add_species(self, **data):
-          # create a species instance
-          species = Species()
-          # assign the right attributes to fulfill ISpecies schema with
-          # the form data
-          self.applyData(species, **data)
-          # stores the instance into the SpeciesContainer
-          name = data['name']
-          self.context[name] = species
-          # redirect to the newly created object
-          self.redirect(self.url(species))
-          # we don't want to display anything, as we redirect
-          return ''
-
-The user can now go to ``myspeciescontainer/add`` to add a species,
-where ``myspeciescontainer`` is any instance of ``SpeciesContainer``.
-
-``grok.EditForm``
-~~~~~~~~~~~~~~~~~
-
-Now that we can create species objects, let's create a form so you can
-easily edit them. This *is* a view of the ``Species`` model::
-
-  class Edit(grok.EditForm):
-     grok.context(Species)
-
-     form_fields = grok.Fields(ISpecies)
-
-     @grok.action(u"Edit species")
-     def edit_species(self, **data):
-          self.applyData(self.context, **data)
-
-Forms are self-submitting, so this will show the edit form again. If
-you want to display another page, you can redirect the browser as we
-showed for the add form previously.
-
-The user can now go to ``myspecies/edit`` to edit the species.
-
-``grok.DisplayForm``
-~~~~~~~~~~~~~~~~~~~~
-
-Sometimes you just want to display an object, and not actually edit
-it. If the object is schema-based, an easy way to do this is to use
-display forms. Let's look at an example::
-
-  class Display(grok.DisplayForm):
-     grok.context(Species)
-
-     form_fields = grok.Fields(ISpecies)
-
-The user can now go to ``myspecies/display`` to look at the species.
-
-Associating a template for a form
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-By default, Grok supplies some templates for forms. They work, but
-they are not very pretty and don't fit into your application's
-layout. You can instead use your own form rendering logic in a
-template you associate with the form just like you associate templates
-with views. You can also abstract form rendering logic you keep
-reusing into a ZPT macro. Below is an example of form rendering logic
-to help you get started. The example doesn't have any consideration
-for layouting to make the logic clear. As a result, the form will be
-very ugly if you use this - you will want to use CSS or table HTML to
-layout things::
-
-  <!-- render the form tag -->
-  <form action="." tal:attributes="action request/URL" method="post"
-        class="edit-form" enctype="multipart/form-data">
-    <!-- render any validation errors on top -->
-    <ul class="errors" tal:condition="view/errors">
-      <li tal:repeat="error view/error_views">
-         <span tal:replace="structure error">Error Type</span>
-      </li>
-    </ul>
-
-    <!-- render the widgets -->
-    <tal:block repeat="widget view/widgets">
-      <label tal:attributes="for widget/name">
-        <!-- a * when the widget is required -->
-        <span class="required" tal:condition="widget/required">*</span>
-        <!-- the title of the field -->
-        <span i18n:translate="" tal:content="widget/label">label</span>
-      </label>
-
-      <!-- render the HTML widget -->
-      <div class="widget" tal:content="structure widget">
-        <input type="text" />
-      </div>
-
-      <!-- render any field specific validation error from a previous
-           form submit next to the field -->
-      <div class="error" tal:condition="widget/error">
-        <span tal:replace="structure widget/error">error</span>
-      </div>
-    </tal:block>
-
-    <!-- render all the action submit buttons -->
-    <span class="actionButtons" tal:condition="view/availableActions">
-      <input tal:repeat="action view/actions"
-             tal:replace="structure action/render" />
-    </span>
-  </form>
-
-The template for a display form a lot simpler::
-
-  <tal:block repeat="widget view/widgets">
-    <tal:block content="widget/label" />
-    <input tal:replace="structure widget" />
-  </tal:block>
-
-  <!-- render all the action submit buttons -->
-  <span class="actionButtons" tal:condition="view/availableActions">
-    <input tal:repeat="action view/actions"
-           tal:replace="structure action/render" />
-  </span>

Modified: grok/trunk/doc/index.rst
===================================================================
--- grok/trunk/doc/index.rst	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/index.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,7 +1,22 @@
-Official Grok Documentation Overview
-************************************
+Grok, a smashing framework!
+===========================
 
+Contents:
+
 .. toctree::
-   :hidden:
+   :maxdepth: 2
 
-   contents.rst
+   introduction
+   api
+   development
+   changes
+
+   license
+   copyright
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`

Copied: grok/trunk/doc/introduction.rst (from rev 119617, grok/branches/jw-documentation-rearangement/doc/introduction.rst)
===================================================================
--- grok/trunk/doc/introduction.rst	                        (rev 0)
+++ grok/trunk/doc/introduction.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -0,0 +1 @@
+.. include:: ../README.txt

Deleted: grok/trunk/doc/layout.html
===================================================================
--- grok/trunk/doc/layout.html	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/layout.html	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,35 +0,0 @@
-{% extends "!layout.html" %}
-
-{%- set reldelim1 = reldelim1 is not defined and ' &raquo;' or reldelim1 %}
-{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
-
-{%- macro relbar_grok() %}
-    <div class="header">
-        {%- block rootrellink %}
-        <a href="{{ pathto('index') }}">Official Grok Documentation</a> version {{ release }}
-        {%- endblock %}
-    <div class="globalnav">
-      <h3>Navigation</h3>
-      <div id="globalnavwrapper">
-      <ul>
-            <li><a href="{{ pathto("tutorial") }}">Tutorial</a></li>
-            <li><a href="{{ pathto("grok_overview") }}">Developer's Notes</a></li>
-            <li><a href="{{ pathto("reference/index")}}">Reference</a></li>
-            <li><a rel="index" title="Global index" href="{{pathto('genindex') }}">Index</a></li>
-            <li><a href="http://grok.zope.org/documentation/">Grok Community Documentation</a></li>
-            {%- block relbaritems %}{% endblock %}
-      </ul>
-      </div>
-    </div>
-    </div>
-{%- endmacro %}
-
-{%- block sidebarlogo %}
-    <a href="{{ pathto('index') }}">
-      <img src="{{ pathto('_static/logo.png', 1) }}" 
-	   alt="Grok Logo"
-	   class="logo"
-	   /></a>
-{% endblock %}
-{%- block relbar1 %}{{ relbar_grok() }}{% endblock %}
-{%- block relbar2 %}<!-- no footer relbar -->{% endblock %}

Copied: grok/trunk/doc/make.bat (from rev 119617, grok/branches/jw-documentation-rearangement/doc/make.bat)
===================================================================
--- grok/trunk/doc/make.bat	                        (rev 0)
+++ grok/trunk/doc/make.bat	2011-01-17 11:06:31 UTC (rev 119618)
@@ -0,0 +1,170 @@
+ at ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/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.  singlehtml to make a single large HTML file
+	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.  devhelp    to make HTML files and a Devhelp project
+	echo.  epub       to make an epub
+	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  text       to make text files
+	echo.  man        to make manual pages
+	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 (%BUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %BUILDDIR%\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+	goto end
+)
+
+if "%1" == "singlehtml" (
+	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\grok.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\grok.ghc
+	goto end
+)
+
+if "%1" == "devhelp" (
+	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished.
+	goto end
+)
+
+if "%1" == "epub" (
+	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The epub file is in %BUILDDIR%/epub.
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "text" (
+	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The text files are in %BUILDDIR%/text.
+	goto end
+)
+
+if "%1" == "man" (
+	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The manual pages are in %BUILDDIR%/man.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.The overview file is in %BUILDDIR%/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+	goto end
+)
+
+:end

Deleted: grok/trunk/doc/naming_conventions.rst
===================================================================
--- grok/trunk/doc/naming_conventions.rst	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/naming_conventions.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,33 +0,0 @@
-Grok naming conventions
------------------------
-
-Zope 3 used to follow PEP 8, but then PEP 8 changed so that
-methodNames() is deprecated in favor of method_names().
-
-Grok aims to be mostly consistent with Zope 3, but does make some
-changes in the direction of PEP 8.
-
-modulenames - module and package names are all lower case, no
-underscores
-              
-ClassNames - CamelCase (Zope 3 + PEP 8)
-
-methodNames - camelCase: follow Zope 3 conventions. We work a lot with Zope 3
-              classes and sometimes subclass.
-
-attribute_names - Zope 3 + PEP 8
-
-class_annotations - we break with Zope 3 tradition
-                    (grok.local_utility() versus implementsOnly()). 
-                    This makes class annotations stand out a bit
-                    more and is more consistent with the use of
-                    class-level attribute names for customization
-                    as well (as in formlib).
-
-top_level_functions - Zope 3 uses camel case (getUtility()).  Grok
-                      uses underscores for top-level functions that
-                      define class annotations. Grok internally has also
-                      been using underscores for functions defined
-                      internally. So far we have avoided exposing them
-                      to the outside world. If you need to expose
-                      one of these, bring it up on the grok-dev mailing list.

Deleted: grok/trunk/doc/style.tex
===================================================================
--- grok/trunk/doc/style.tex	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/style.tex	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,74 +0,0 @@
-% latex include file for docutils latex writer
-% --------------------------------------------
-%
-% CVS: $Id: style.tex,v 1.1 2004/01/23 21:17:32 faassen Exp $
-%
-% This is included at the end of the latex header in the generated file,
-% to allow overwriting defaults, although this could get hairy.
-% Generated files should process well standalone too, LaTeX might give a
-% message about a missing file.
-
-% donot indent first line of paragraph.
-\setlength{\parindent}{0pt}
-\setlength{\parskip}{5pt plus 2pt minus 1pt}
-
-% sloppy
-% ------
-% Less strict (opposite to default fussy) space size between words. Therefore
-% less hyphenation.
-\sloppy
-
-% fonts
-% -----
-% times for pdf generation, gives smaller pdf files.
-%
-% But in standard postscript fonts: courier and times/helvetica do not fit.
-% Maybe use pslatex.
-\usepackage{times}
-
-% pagestyle
-% ---------
-% headings might put section titles in the page heading, but not if
-% the table of contents is done by docutils.
-% If pagestyle{headings} is used, \geometry{headheight=10pt,headsep=1pt}
-% should be set too.
-%\pagestyle{plain}
-%
-% or use fancyhdr (untested !)
-\usepackage{fancyhdr}
-\pagestyle{fancy}
-\addtolength{\headheight}{\baselineskip}
-\renewcommand{\sectionmark}[1]{\markboth{#1}{}}
-\renewcommand{\subsectionmark}[1]{\markright{#1}}
-\fancyhf{}
-\fancyhead[LE,RO]{\bfseries\textsf{\thepage}}
-\fancyhead[LO]{\textsf{\footnotesize\rightmark}}
-\fancyhead[RE]{\textsc{\textsf{\footnotesize\leftmark}}}
-%\fancyfoot[LE,RO]{\bfseries\textsf{\scriptsize Docutils}}
-%\fancyfoot[RE,LO]{\textsf{\scriptsize\today}}
-
-% geometry 
-% --------
-% = papersizes and margins
-%\geometry{a4paper,twoside,tmargin=1.5cm,
-%          headheight=1cm,headsep=0.75cm}
-
-% Do section number display
-% -------------------------
-%\makeatletter
-%\def\@seccntformat#1{}
-%\makeatother
-% no numbers in toc
-%\renewcommand{\numberline}[1]{}
-
-
-% change maketitle
-% ----------------
-%\renewcommand{\maketitle}{
-%  \begin{titlepage}
-%    \begin{center}
-%    \textsf{TITLE \@title} \\
-%	Date: \today
-%    \end{center}
-%  \end{titlepage}
-%}

Deleted: grok/trunk/doc/template.pt
===================================================================
--- grok/trunk/doc/template.pt	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/template.pt	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,68 +0,0 @@
-<metal:block define-macro="pagelayout">
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-  <title tal:content="context/title" />
-  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
-  <meta name="description" content="Grok - now even cavemen can use Zope3" />
-  <meta name="keywords" content="Grok, internet, zope, zope3, software, web apps, web applications, python" />
-	<style type="text/css"><!-- @import url(/resources/grok.css); --></style>
-</head>
-
-<body>
-<div class="header">
-	
-	<a href="http://grok.zope.org">
-	<img src="/resources/grok-header.jpg" alt="GROK"/></a>
-	<ul id="navigation">
-        <li tal:repeat="item context/menu">
-            <a tal:content="item/title"
-               tal:attributes="title item/description;
-                               class item/klass;
-                               href item/href">link</a></li>
-  </ul>
-</div>
-
-
-<div class="roundcont">
-	
-  <div class="roundtop">
-    <img src="/resources/corner-topleft.jpg" alt="" 
-           width="45" height="45" class="corner" 
-           style="display: none" />
-  </div>
-
-  <div class="content">
-
-          <tal:block replace="structure context/content" />
-
-  </div>
-
-  <div class="roundbottom">
-     <img src="/resources/corner-bottomleft.jpg" alt="" 
-     width="45" height="45" class="corner" 
-     style="display: none" />
-  </div>
-
-</div>
-
-<div class="footer">
-	
-	<table><tr><td>
-	Grok cooks around the campfire of <br />
-	<a href="http://wiki.zope.org/zope3/FrontPage"><img src="/resources/zopelogo.gif" alt="Zope" style="padding: 0.5em;" /></a>
-	</td><td>
-	 and roams free on the savannah of<br />
-	<a href="http://www.python.org"><img src="/resources/python-logo.gif" style="padding: 0.5em;" alt="Python" /></a>
-	</td></tr>
-	</table>
-
-	<p>Hosting provided by <a href="http://quintagroup.com/"><b>Quintagroup</b></a></p>
-</div>
-
-</body>
-</html>
-</metal:block>
-

Deleted: grok/trunk/doc/tutorial.rst
===================================================================
--- grok/trunk/doc/tutorial.rst	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/tutorial.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,1343 +0,0 @@
-=============
-Grok tutorial
-=============
-
-.. raw:: html
-
-   Also available as <a href="./tutorial.pdf">PDF</a>.
-
-.. contents::
-
-Welcome to the Grok tutorial!
-=============================
-
-.. sidebar:: Getting started with Zope Page Templates
-
-  You can find introductions and more information about Zope Page Templates
-  (ZPT, sometimes also called TAL) in various places:
-
-    http://plone.org/documentation/tutorial/zpt
-
-    http://wiki.zope.org/ZPT/FrontPage
-
-  Note that some of the information in these introductions may refer to
-  concepts not available in Grok or the Zope Toolkit, in particular variables
-  like ``here`` or ``template``. The basic principles will work with Grok
-  however; try reading ``context`` or ``view`` instead.
-
-Grok is a powerful and flexible web application framework for Python
-developers. In this tutorial we will show you the various things you can do
-with Grok, and how Grok can help you build your web application. We'll start
-out simple, and will slowly go to more complex usage patterns.
-
-All you're expected to know is the Python programming language and an
-understanding of basic web programming (HTML, forms, URLs). It also helps if
-you are familiar with Zope Page Templates, though most of the examples should
-be fairly obvious if you are already familiar with another templating language.
-
-We recommend that beginners follow the tutorial from top to bottom. The
-tutorial is designed to explain important concepts in order and slowly builds
-up from there.
-
-If you are more experienced, or just curious, you may want to skip around
-instead and read the pieces which interest you most. If something is unclear,
-you can always backtrack to previous sections.
-
-Grok is based on the `Zope Toolkit`_. You do not need to know about the Zope
-Toolkit at all to follow this tutorial. Grok builds on existing Zope Toolkit
-technology but exposes it in a special way to the developer. We believe Grok
-makes developing with Zope Toolkit technology easier and more fun for beginners
-and experienced developers alike.
-
-.. _`Zope Toolkit`: http://docs.zope.org/zopetoolkit/
-
-
-Getting started with Grok
-=========================
-
-This chapter will help you get up and running with Grok, using the
-``grokproject`` tool. We create a new project with ``grokproject`` and tell you
-how to get that project running so you can access it with a web browser.
-
-Setting up grokproject
-----------------------
-
-.. sidebar:: Installing ``easy_install``
-
-  If you don't already have ``easy_install`` available, you can find the script
-  to set it up on the `PEAK EasyInstall page`_.
-
-  .. _`PEAK EasyInstall page`: http://peak.telecommunity.com/DevCenter/EasyInstall#installing-easy-install
-
-  You need to download `ez_setup.py`_. Then, you run it like this to install
-  ``easy_install`` into your system Python::
-
-    $ sudo python2.6 ez_setup.py
-
-  .. _`ez_setup.py`: http://peak.telecommunity.com/dist/ez_setup.py
-
-  This will make ``easy_install`` available to you.
-
-  **Note**: Sometimes you have ``easy_install`` installed but you need a newer
-  version of the underlying setuptools infrastructure to make Grok work. You
-  can upgrade setuptools with::
-
-    $ sudo easy_install -U setuptools
-
-Setting up grok on a Unix-like (Linux, Mac OS X) environment is easy. Most of
-these instructions should work in a Windows environment as well.
-
-Let's go through the prerequisites first. You need a computer connected to the
-internet, as Grok installs itself over the network. You also need Python 2.6
-(or Python 2.5) installed.
-
-Because Grok uses a source distribution of the Zope Toolkit libraries, you may
-need to install your operating system's Python "dev" package (``python-dev`` on
-Debian and Ubuntu, ``python2.6-dev`` for Python 2.6). You also need a working C
-compiler (typically ``gcc``) installed, as we compile bits of the Zope Toolkit
-during setup (``build-essential`` on Debian and Ubuntu).
-
-On Windows such a build environment is not necessary, as grokproject will
-download and automatically install precompiled libraries for Windows. Finally,
-you also need ``easy_install`` installed so it becomes easy to install Python
-packages.
-
-Once you are done with the prerequisites, you can install grokproject itself::
-
-  $ easy_install grokproject
-
-If you are on a Unixy environment and you are not working from a `virtualenv`_
-virtualenv or custom compiled python installation, you will need to request
-admin rights using ``sudo``, as this will install new libraries into your
-system Python.
-
-  .. _`virtualenv`: http://foo
-
-We're ready to create our first grok project now!
-
-Creating a new Grok project
----------------------------
-
-.. sidebar:: Using paster
-
-  For those who know paster_: ``grokproject`` is just a wrapper around a paster
-  template. So instead of running the ``grokproject`` command, you can also
-  run::
-
-  $ paster create -t grok Sample
-
-  .. _paster: http://pythonpaste.org/script/
-
-Let's create a first Grok project. A Grok project is a working environment for
-a developer of an web application based using Grok. In essence, a directory
-with a lot of files and subdirectories in it. Let's create a Grok project
-called Sample::
-
-  $ grokproject Sample
-
-This tells grokproject to create a new subdirectory called ``Sample`` and set
-up the project in there. grokproject will automatically download and install
-the Zope Toolkit libraries as well as the Grok Toolkit into the project area.
-
-Grok asks you for an initial username and password for the server. We'll use
-``grok`` for both in this example::
-
-  Enter user (Name of an initial administrator user): grok
-  Enter passwd (Password for the initial administrator user): grok
-
-Now you have to wait while grokproject downloads and installs the various tools
-and libraries that are needed in a Grok project. The second time you create a
-Grok project it will be faster as it can reuse the previously installed
-libraries. After all that your Grok project is ready to go.
-
-.. sidebar:: Common problems installing Grok
-
-  *No Python development environment*
-
-  Grok includes dependencies that need to be compiled against Python.
-  This happens automatically in the installation process, but a Python
-  development environment does need to be installed, unless you are on
-  Windows, where we supply binary versions of the required libraries.
-
-  On Debian and Ubuntu this is the ``python-dev`` package
-  (``python2.6-dev for Python 2.6). You also need ``build-essential``.
-
-Starting up the web server
---------------------------
-
-You can go into the ``Sample`` project directory now and start up the web
-server for our project::
-
-  $ cd Sample
-  $ bin/paster serve parts/etc/deploy.ini
-
-This will make Grok available on port 8080. You can log in with username
-``grok`` and password ``grok``. Assuming you've started up the web server on
-your development computer, you can go to it here:
-
-  http://localhost:8080
-
-This first pops up a login dialog (username: ``grok`` and password: ``grok``).
-It will then show a simple Grok admin interface. This user interface allows you
-to install new Grok applications.
-
-Our sample application (``sample.app.Sample``) will be available for adding.
-Let's try this out. Go to the Grok admin page:
-
-  http://localhost:8080
-
-and add a Sample application. Give it the name ``test``.
-
-You can now go to the installed application if you click on its link. This will
-bring you to the following URL:
-
-  http://localhost:8080/test
-
-You should see a simple web page with the following text on it::
-
-  Congratulations!
-
-  Your Grok application is up and running. Edit
-  sample/app_templates/index.pt to change this page.
-
-You can shut down the server at any time by hitting ``CTRL-c``. Shut it down
-now. We will be shutting down and starting up the server often in this tutorial.
-
-Practice restarting the server now, as you'll end up doing it a lot during this
-tutorial. It's just stopping and starting it again: ``CTRL-c`` and then
-``bin/paster serve parts/etc/deploy.ini`` from your Sample project directory.
-
-Alternatively, you can use the --reload flag to start up paster with a monitor
-that scans your code base (python files only) for changes and automatically
-restarts the server every time you make a change::
-
-  $ bin/paster serve --reload parts/etc/deploy.ini
-
-An empty Grok project
----------------------
-
-.. sidebar:: What about the other directories and files in our project?
-
-  What about the other files and subdirectories in our ``Sample`` project
-  directory? Grokproject sets up the project using a system called
-  `zc.buildout`_. The ``eggs``, ``develop-eggs``, ``bin`` and ``parts``
-  directories are all set up and maintained by zc.buildout. See its
-  documentation for more information about how to use it. The configuration of
-  the project and its dependency is in ``buildout.cfg``. For the moment
-  however, you can ignore these details however.
-
-  .. _`zc.buildout`: http://buildout.org
-
-Let's take a closer look at what's been created in the Sample project directory.
-
-One of the things grokproject created was a ``setup.py`` file. This file
-contains information about your project. This information is used by buildout
-to download your project's dependencies and to install it. You can also use the
-``setup.py`` file to upload your project to the Python Package Index (PyPI).
-
-We have already seen the ``bin`` directory. It contains the startup script for
-the web server (``bin/paster``) as well as the executable for the buildout
-system (``bin/buildout``) which can be used to re-build your project (to update
-it or to install a new dependency).
-
-The ``parts` directory contain configuration and data created and managed by
-``buildout``, such as the Zope object database (ZODB) storage, and the ``.ini``
-files to be used with ``paster``.
-
-The actual code of the project will all be inside the ``src`` directory. In it
-is a Python package directory called ``sample`` with the ``app.py`` file that
-grokproject said it would create. Let's look at this file:
-
-.. include:: groktut/an_empty_grok_project/src/sample/app.py
-   :literal:
-
-Not very much yet, but enough to make an installable Grok application and
-display its welcome page. We'll go into the details of what this means later.
-
-Besides this, there is an empty ``__init__.py`` file to make this directory a
-Python package.
-
-There is also a directory called ``app_templates``. It contains a single
-template called ``index.pt``:
-
-.. include:: groktut/an_empty_grok_project/src/sample/app_templates/index.pt
-  :literal:
-
-This is the template for your project's welcome page.
-
-There is also a ``configure.zcml`` file. This file will normally only contain a
-few lines that load dependencies and then register this application with Grok.
-This means we can typically completely ignore it, but we'll show it here once
-for good measure:
-
-.. include:: groktut/an_empty_grok_project/src/sample/configure.zcml
-   :literal:
-
-.. sidebar:: ``configure.zcml`` in non-Grok applications
-
-  In non-Grok applications that use the Zope Toolkit (such as something created
-  with Zope 2 or Zope 3), the ZCML file usually plays a much bigger role. It
-  contains directives which registers particular Python objects (typically
-  classes, such as views) with the component architecture that is central to
-  the Zope Toolkit. Grok however automates this registration by putting more
-  information into the Python code directly, so that the ZCML file can remain
-  small.
-
-There is also a ``static`` directory. This contains static files that can be
-used in the web application, such as images, css files and javascript files.
-
-Besides these files, there is an ``app.txt``, ``ftesting.zcml`` and
-``tests.py``. These all have to do with the automatic testing environment and
-can be ignored for now.
-
-Showing pages
-=============
-
-Showing web pages is what puts the *web* in "web applications". Typically HTML
-templates are used for this, but Grok doesn't stop at templates. Most web pages
-in a real-world web application will contain complex presentation logic that is
-better handled by separate Python code in conjunction with templates. This
-becomes especially important in more complex interactions with the user, such
-as form handling. After reading this chapter, you should already be able to
-write simple web applications with Grok.
-
-Publishing a simple web page
-----------------------------
-
-Let's publish a simple static web page. Grok is geared towards web applications
-and therefore is not really meant for publishing a large number of static
-(pregenerated) web pages. For that you're better off to use a specialized
-system such as Apache. Nonetheless, in order to develop any web application we
-need to know how to put some simple HTML on the web.
-
-As you saw previously, our ``Sample`` application has a stock front page,
-generated by grokproject. Let's change that.
-
-To do this, go to the ``app_templates`` directory in ``src/sample/``. This
-directory contains the templates used for anything defined in the ``app``
-module. Grok knows to associate the directory to the module by its name
-(``<module_name>_templates``).
-
-In this directory we will edit the ``index`` template for our ``Sample``
-application object. To do this, open the ``index.pt`` file in a text editor.
-The ``.pt`` extension indicates that this file is a Zope Page Template (ZPT).
-We're just going to put HTML in it now, but this allows us to make page dynamic
-later on.
-
-Change the ``index.pt`` file to contain the following (very simplistic) HTML:
-
-.. include:: groktut/publishing_a_simple_web_page/src/sample/app_templates/index.pt
-  :literal:
-
-Then reload the page:
-
-  http://localhost:8080/test
-
-You should now see the following text::
-
-  Hello world!
-
-Note that you can change templates and see the effects instantly: there is no
-need to restart the web server to see the effect. This is not true for changes
-on the Python level, for instance when you add a template. We show an example
-of this next.
-
-A second view
--------------
-
-Our view is named ``index``. This in fact means something slightly special:
-it's the default view of our application object. We can also access it
-explicitly by naming the view:
-
-  http://localhost:8080/test/index
-
-If you view that URL in your browser, you should see the same result as before.
-This is the way all other, non-index views are accessed.
-
-Often, your application needs more than one view. A document for instance may
-have an ``index`` view that displays it, but another ``edit`` view to change
-its contents. To create a second view, create another template called
-``bye.pt`` in ``app_templates``. Make it have the following content:
-
-.. include:: groktut/a_second_view/src/sample/app_templates/bye.pt
-  :literal:
-
-Now we need to tell Grok to actually use this template. To do this,
-modify ``src/sample/app.py`` so that it reads like this:
-
-.. include:: groktut/a_second_view/src/sample/app.py
-  :literal:
-
-As you can see, all we did was add a class called ``Bye`` that subclasses from
-``grok.View``. This indicates to Grok that we want a view named ``bye`` for the
-application, just like the ``Index`` class that was already created for us
-indicates that we want a view named ``index``. A *view* is a way to view some
-model, in this case installations of our ``Sample`` application. Note that the
-view name in the URL is always going to be lowercase, while the class name
-normally starts with an uppercase letter.
-
-The empty class definition above is enough for Grok to go look in the
-``app_templates`` directory for ``bye.pt``. The rule is that a the template
-should have the same name as the class, but lowercased and with the ``.pt``
-postfix.
-
-.. sidebar:: Other templating languages
-
-  You can also install extensions to allow the use of other templating
-  languages in Grok, see for instance `megrok.genshi`_.
-
-  .. _`megrok.genshi`: http://pypi.python.org/pypi/megrok.genshi/
-
-Restart the web server (``Ctrl + C``, then ``bin/paster serve
-parts/etc/deploy.ini``). You can now go to a new web page called ``bye``:
-
-  http://localhost:8080/test/bye
-
-When you load this web page in a browser, you should see the following text::
-
-  Bye world!
-
-Making our page dynamic
------------------------
-
-Static web pages are not very helpful if we want to make a dynamic web
-application. Let's make a page that shows the result of a very simple
-calculation: ``1 + 1``.
-
-We will use a Zope Page Templates (ZPT) directive to do this calculation inside
-``index.pt`` template. Change the ``index.pt`` to read like this:
-
-.. include:: groktut/making_our_page_dynamic/src/sample/app_templates/index.pt
-  :literal:
-
-We've used the ``tal:content`` page template directive to replace the content
-between the ``<p>`` and ``</p>`` tags with something else, in this case the
-result of the Python expression ``1 + 1``.
-
-Since restarting the server is not necessary for changes that are limited to
-the page templates, you can just reload the web page:
-
-  http://localhost:8080/test
-
-You should see the following result::
-
-  2
-
-Looking at the source of the web page shows us this::
-
-  <html>
-  <body>
-  <p>2</p>
-  </body>
-  </html>
-
-As you can see, the content of the ``<p>`` tag was indeed replaced with the
-result of the expression ``1 + 1``.
-
-Static resources for our web page
----------------------------------
-
-In real-world web pages, we almost never publish a web page that just contains
-bare-bones HTML. We also want to refer to other resources, such as images, CSS
-files or Javascript files. As an example, let's add some style to our web page.
-
-To do this, create a new directory called ``static`` in the ``sample`` package
-(so, ``src/sample/static``). In it, place a file called ``style.css`` and put
-in the following content:
-
-.. include:: groktut/static_resources_for_our_web_page/src/sample/static/style.css
-  :literal:
-
-In order to use it, we also need to refer to it from our ``index.pt``. Change
-the content of ``index.pt`` to read like this:
-
-.. include:: groktut/static_resources_for_our_web_page/src/sample/app_templates/index.pt
-  :literal:
-
-Now restart the server and reload the page:
-
-  http://localhost:8080/test
-
-The web page should now show up with a red background.
-
-You will have noticed we used the ``tal:attributes`` directive in our
-``index.pt`` now. This uses Zope Page Templates to dynamically generate the
-link to our file ``style.css``.
-
-Let's take a look at the source code of the generated web page::
-
-  <html>
-  <link rel="stylesheet" type="text/css"
-        href="http://localhost:8080/test/@@/sample/style.css" />
-  <body>
-  <p>Hello world!</p>
-  </body>
-  </html>
-
-As you can see, the ``tal:attributes`` directive is gone and has been replaced
-with the following URL to the actual stylesheet:
-
-  http://localhost:8080/test/@@/sample/style.css
-
-We will not go into the details of the structure of the URL here, but we will
-note that because it's generated this way, the link to ``style.css`` will
-continue to work no matter where you install your application (i.e. in a
-virtual hosting setup).
-
-Pulling in images or javascript is very similar. Just place your image files
-and `.js` files in the ``static`` directory, and create the URL to them using
-``static/<filename>`` in your page template.
-
-Using view methods
-------------------
-
-.. sidebar:: Unassociated templates
-
-  If you have followed the tutorial so far, you will have an extra template
-  called ``bye.pt`` in your ``app_templates`` directory. Since in the given
-  ``app.py`` we we have no more class using it, the ``bye.pt`` template will
-  have become *unassociated*. When you try to restart the server, Grok will
-  give you a warning like this::
-
-    UserWarning: Found the following unassociated template(s) when grokking
-    'sample.app': bye. Define view classes inheriting from grok.View to enable
-    the template(s).
-
-  To get rid of this warning, simply remove ``bye.pt`` from your
-  ``app_templates`` directory.
-
-ZPT is deliberately limited in what it allows you to do with Python. It is good
-application design practice to use ZPT for fairly simple templating purposes
-only, and to do anything a bit more complicated in Python code. Using ZPT with
-arbitrary Python code is easy: you just add methods to your view class and use
-them from your template.
-
-Let's see how this is done by making a web page that displays the current date
-and time. We will use our Python interpreter to find out what works::
-
-  $ python
-  Python 2.6.2
-  Type "help", "copyright", "credits" or "license" for more information.
-  >>>
-
-We will need Python's ``datetime`` class, so let's import it::
-
-  >>> from datetime import datetime
-
-Note that this statement brings us beyond the capabilities of simple ZPT use;
-it is not allowed to import arbitrary Python modules from within a ZPT
-template; only Python *expressions* (with a result) are allowed, not
-*statements* such as ``from .. import ..``.
-
-Let's get the current date and time::
-
-  >>> now = datetime.now()
-
-This gives us a date time object; something like this::
-
-  >>> now
-  datetime.datetime(2007, 2, 27, 17, 14, 40, 958809)
-
-Not very nice to display on a web page, so let's turn it into a prettier string
-using the formatting capabilities of the ``datetime`` object::
-
-  >>> now.strftime('%Y-%m-%d %H:%M')
-  '2007-02-27 17:14'
-
-That looks better.
-
-So far nothing new; just Python. We will integrate this code into our Grok
-project now. Go to ``app.py`` and change it to read like this:
-
-.. include:: groktut/using_view_methods/src/sample/app.py
-  :literal:
-
-We've simply added a method to our view that returns a string representing the
-current date and time. Now to get this string in our page template. Change
-``index.pt`` to read like this:
-
-.. include:: groktut/using_view_methods/src/sample/app_templates/index.pt
-  :literal:
-
-Restart the server. This is needed as we changed the content of a Python file
-(``app.py``). Now reload our index page to see whether it worked:
-
-  http://localhost:8080/test
-
-You should see a web page with a date and time like this on your screen now::
-
-  2007-02-27 17:21
-
-What happened here? When viewing a page, the view class (in this case ``Index``
-is instantiated by the framework. The name ``view`` in the template is always
-made available and is associated with this instance. We then simply call the
-method on it in our template.
-
-There is another way to write the template that is slightly shorter and may be
-easier to read in some cases, using a ZPT path expression::
-
-  <html>
-  <body>
-  <p tal:content="view/current_datetime"></p>
-  </body>
-  </html>
-
-Running this has the same result as before.
-
-Generating HTML from Python
----------------------------
-
-While usually you will be using templates to generate HTML, sometimes you want
-to generate complicated HTML in Python and then include it in an existing web
-page. For reasons of security against cross-site scripting attacks, TAL will
-automatically escape any HTML into `&gt;` and `&lt;`. With the ``structure``
-directive, you can tell TAL explicitly to not escape HTML this way, so it is
-passed literally into the template. Let's see how this is done. Change
-``app.pt`` to read like this:
-
-.. include:: groktut/generating_html_from_python/src/sample/app.py
-  :literal:
-
-and then change ``index.pt`` to read like the following:
-
-.. include:: groktut/generating_html_from_python/src/sample/app_templates/index.pt
-  :literal:
-
-Let's take another look at our web page:
-
-  http://localhost:8080/test
-
-You should see the following text (in bold):
-
-  **ME GROK BOLD**
-
-This means the HTML we generated from the ``some_html`` method was indeed
-successfully integrated in our web page. Without the the ``structure``
-directive, you would've seen the following instead::
-
-  <b>ME GROK BOLD</b>
-
-Completely Python-driven views
-------------------------------
-
-.. sidebar:: Setting the content-type
-
-  When generating the complete content of a page yourself, it's often useful to
-  change the content-type of the page to something else than ``text/plain``.
-  Let's change our code to return simple XML and set the content type to
-  ``text/xml``:
-
-  .. include:: groktut/setting_the_content_type/src/sample/app.py
-    :literal:
-
-  All views in Grok have a ``response`` property that you can use to manipulate
-  response headers.
-
-Sometimes it is inconvenient to have to use a template at all. Perhaps we are
-not returning a HTML page at all, for instance. In this case, we can use the
-special ``render`` method on a view.
-
-Modify ``app.py`` so it reads like this:
-
-.. include:: groktut/completely_python_driven_views/src/sample/app.py
-  :literal:
-
-If you were to start up the server with an ``index.pt`` template still inside
-``app_templates`` you would get a an error::
-
-    GrokError: Multiple possible ways to render view <class
-    'sample.app.Index'>. It has both a 'render' method as well as an
-    associated template.
-
-In the face of ambiguity Grok, like Python, refuses to guess. To resolve this
-error, remove ``index.pt`` from the ``app_templates`` directory.
-
-Now take another look at our test application:
-
-  http://localhost:8080/test
-
-You should see the following::
-
-  ME GROK NO TEMPLATE
-
-You should see this even when you view the source of the page. When looking at
-the content type of this page, you will see that it is ``text/plain``.
-
-Doing some calculation before viewing a page
---------------------------------------------
-
-Instead of calculating some values in a method call from the template, it is
-often more useful to calculate just before the web page's template is
-calculated. This way you are sure that a value is only calculated once per
-view, even if you use it multiple times.
-
-You can do this by defining an ``update`` method on the view class. Modify
-``app.py`` to read like this:
-
-.. include:: groktut/doing_some_calculation_before_viewing_a_page/src/sample/app.py
-  :literal:
-
-This sets a name ``alpha`` on the view just before the template is being
-displayed, so we can use it from the template. You can set as many names on
-``self`` as you like.
-
-Now we need a template ``index.pt`` that uses ``alpha``:
-
-.. include:: groktut/doing_some_calculation_before_viewing_a_page/src/sample/app_templates/index.pt
-  :literal:
-
-Restart the server and then let's take another look at our application:
-
-  http://localhost:8080/test
-
-You should see 256, which is indeed 2 raised to the power 8.
-
-Reading URL parameters
-----------------------
-
-When developing a web application, you don't just want to output data, but also
-want to use input. One of the simplest ways for a web application to receive
-input is by retrieving information as a URL parameter. Let's devise a web
-application that can do sums for us. In this application, if you enter the
-following URL into that application:
-
-  http://localhost:8080/test?value1=3&value2=5
-
-you should see the sum (8) as the result on the page.
-
-Modify ``app.py`` to read like this:
-
-.. include:: groktut/reading_url_parameters/src/sample/app.py
-  :literal:
-
-We need an ``index.pt`` that uses ``sum``:
-
-.. include:: groktut/reading_url_parameters/src/sample/app_templates/index.pt
-  :literal:
-
-Restart the server. Now going to the following URL should display 8:
-
-  http://localhost:8080/test?value1=3&value2=5
-
-Other sums work too, of course:
-
-  http://localhost:8080/test?value1=50&value2=50
-
-What if we don't supply the needed parameters (``value1`` and
-``value2``) to the request? We get an error:
-
-  http://localhost:8080/test
-
-You can look at the window where you started up the server to see the error
-traceback. This is the relevant complaint::
-
-  TypeError: Missing argument to update(): value1
-
-We can modify our code so it works even without input for either parameter:
-
-.. include:: groktut/reading_url_parameters2/src/sample/app.py
-  :literal:
-
-Restart the server, and see it can now deal with missing parameters (they
-default to ``0``).
-
-Simple forms
-------------
-
-.. sidebar:: Automatic forms
-
-  Creating forms and converting and validating user input by hand, as shown in
-  this section, can be rather cumbersome. With Grok, you can use the Zope
-  Toolkit's *schema* and *formlib* systems to automate this and more. This will
-  be discussed in a later section. TDB
-
-Entering the parameters through URLs is not very pretty. Let's use a form for
-this instead. Change ``index.pt`` to contain a form, like this:
-
-.. include:: groktut/simple_forms/src/sample/app_templates/index.pt
-  :literal:
-
-One thing to note here is that we dynamically generate the form's ``action``.
-We make the form submit to itself, basically. Grok views have a special method
-called ``url`` that you can use to retrieve the URL of the view itself (and
-other URLs which we'll go into later).
-
-Leave the ``app.py`` as in the previous section, for now. You can now go to the
-web page::
-
-  http://localhost:8080/test
-
-You can submit the form with some values, and see the result displayed below.
-
-We still have a few bugs to deal with however. For one, if we don't fill in any
-parameters and submit the form, we get an error like this::
-
-  File "../app.py", line 8, in update
-    self.sum = int(value1) + int(value2)
-  ValueError: invalid literal for int():
-
-This is because the parameters were empty strings, which cannot be converted to
-integers. Another thing that is not really pretty is that it displays a sum (0)
-even if we did not enter any data. Let's change ``app.py`` to take both cases
-into account:
-
-.. include:: groktut/simple_forms2/src/sample/app.py
-  :literal:
-
-We catch any TypeError and ValueError here so that wrong or missing data does
-not result in a failure. Instead we display the text "No sum". If we don't get
-any error, the conversion to integer was fine, and we can display the sum.
-
-Restart the server and go to the form again to try it out:
-
-  http://localhost:8080/test
-
-Models
-======
-
-Now we know how to show web pages, we need to go into what we are actually
-showing: the models. The models contain the display-independent logic of your
-application. In this chapter we will discuss a number of issues surrounding
-models: how your views connect to models, and how you can make sure the data in
-your models is stored safely. As the complexity of our sample applications
-grows, we will also go into a few more issues surrounding form handling.
-
-A view for a model
-------------------
-
-So far, we have only seen views that do the work all by themselves. In typical
-applications this is not the case however - views display information that is
-stored elsewhere. In Grok applications, views work for models: subclasses of
-``grok.Model`` or ``grok.Container``. For the purposes of this discussion, we
-can treat a ``grok.Container`` as another kind of ``grok.Model`` (more about
-what makes ``grok.Container`` special later XXX).
-
-Our ``Sample`` class is a ``grok.Container``, so let's use ``Sample`` to
-demonstrate the basic principle. Let's modify ``app.py`` so that ``Sample``
-actually makes some data available:
-
-.. include:: groktut/a_view_for_a_model/src/sample/app.py
-  :literal:
-
-In this case, the information (``"This is important information!"``) is just
-hardcoded, but you can imagine information is retrieved from somewhere else,
-such as a relational database or the filesystem.
-
-We now want to display this information in our template ``index.pt``:
-
-.. include:: groktut/a_view_for_a_model/src/sample/app_templates/index.pt
-  :literal:
-
-Restart the server. When you view the page:
-
-  http://localhost:8080/test
-
-You should now see the following::
-
-  This is important information!
-
-Previously we have seen that you can access methods and attributes on the view
-using the special ``view`` name in a template. Similarly, the name ``context``
-is also available in each template. ``context`` allows us to access information
-on the context object the view is displaying. In this case this is an instance
-of ``Sample``, our application object.
-
-Separating the model from the view that displays it is an important concept in
-structuring applications. The view, along with the template, is responsible for
-displaying the information and its user interface. The model represents the
-actual information (or content) the application is about, such as documents,
-blog entries or wiki pages. The model should not know anything about the way it
-is displayed.
-
-This way of structuring your applications allows you to change the way your
-model is displayed without modifying the model itself, just the way it is
-viewed.
-
-Let's do that by making the view do something to the information. Change
-``app.py`` again:
-
-.. include:: groktut/a_view_for_a_model2/src/sample/app.py
-  :literal:
-
-You can see that it is possible to access the context object (an instance of
-``Sample``) from within the view class, by accessing the ``context`` attribute.
-This gets the same object as when we used the ``context`` name in our template
-before.
-
-What we do here is reverse the string returned from the ``information()``
-method. You can try it on the Python prompt::
-
-  >>> ''.join(reversed('foo'))
-  'oof'
-
-Now let's modify the ``index.pt`` template so that it uses the
-``reversed_information`` method:
-
-.. include:: groktut/a_view_for_a_model2/src/sample/app_templates/index.pt
-  :literal:
-
-Restart the server. When you view the page:
-
-  http://localhost:8080/test
-
-You should now see the following:
-
-  The information: This is important information!
-
-  The information, reversed: !noitamrofni tnatropmi si sihT
-
-Storing data
-------------
-
-So far we have only displayed either hardcoded data, or calculations based on
-end-user input. What if we actually want to *store* some information, such as
-something the user entered? The easiest way to do this with Grok is to use the
-Zope Object Database (ZODB).
-
-The ZODB is a database of Python objects. You can store any Python object in
-it, though you do need to follow a few simple rules (the "rules of
-persistence", which we will go into later). Our ``Sample`` application object
-is stored in the object database, so we can store some information on it.
-
-Let's create an application that stores a bit of text for us. We will use one
-view to view the text (``index``) and another to edit it (``edit``).
-
-Modify ``app.py`` to read like this:
-
-.. include:: groktut/storing_data/src/sample/app.py
-  :literal:
-
-The ``Sample`` class gained a class attribute with some default text. In the
-``update`` method of the ``Edit`` view you can see we actually set the ``text``
-attribute on the context, if at least a ``text`` value was supplied by a form.
-This will set the ``text`` attribute on the instance of the ``Sample`` object
-in the object database, and thus will override the default ``text`` class
-attribute.
-
-Change the ``index.pt`` template to read like this:
-
-.. include:: groktut/storing_data/src/sample/app_templates/index.pt
-  :literal:
-
-This is a very simple template that just displays the ``text`` attribute of the
-``context`` object (our ``Sample`` instance).
-
-Create an ``edit.pt`` template with the following content:
-
-.. include:: groktut/storing_data/src/sample/app_templates/edit.pt
-  :literal:
-
-This template display a form asking for a bit of text. It submits to itself.
-
-Restart the server. Let's first view the index page:
-
-  http://localhost:8080/test
-
-You should see ``default text``.
-
-Now let's modify the text by doing to the edit page of the application:
-
-  http://localhost:8080/test/edit
-
-Type in some text and press the "Store" button. Since it submits to itself, we
-will see the form again, so go to the index page manually:
-
-  http://localhost:8080/test
-
-You should now see the text you just entered on the page. This means that your
-text was successfully stored in the object database!
-
-You can even restart the server and go back to the index page, and your text
-should still be there.
-
-Redirection
------------
-
-Let's make our application a bit easier to use. First, let's change
-``index.pt`` so it includes a link to the edit page. To do this, we will use
-the ``url`` method on the view:
-
-.. include:: groktut/redirection/src/sample/app_templates/index.pt
-  :literal:
-
-Giving ``url`` a single string argument will generate a URL to the view named
-that way on the same object (``test``), so in this case ``test/edit``.
-
-Now let's change the edit form so that it redirects back to the ``index`` page
-after you press the submit button:
-
-.. include:: groktut/redirection/src/sample/app.py
-  :literal:
-
-The last line is the new one. We use the ``url`` method on the view to
-construct a URL to the ``index`` page. Since we're in the template, we can
-simply call ``url`` on ``self``. Then, we pass this to another special method
-available on all ``grok.View`` subclasses, ``redirect``. We tell the system to
-redirect to the ``index`` page.
-
-Showing the value in the form
------------------------------
-
-Let's change our application so it displays what we stored the edit form as
-well, not just on the index page.
-
-To make this work, change edit.pt so it reads like this:
-
-.. include:: groktut/showing_the_value_in_the_form/src/sample/app_templates/edit.pt
-  :literal:
-
-The only change is that we have used ``tal:attributes`` to include the value of
-the ``text`` attribute of the context object in the form.
-
-The rules of persistence
-------------------------
-
-These are the "rules of persistence":
-
-* You should subclass classes that want to store data from
-  ``persistent.Persistent`` so that it's easy to store them in the ZODB. The
-  simplest way to do this with Grok is to subclass from ``grok.Model`` or
-  ``grok.Container``.
-
-* Instances that you want to store should be connected to other persistent
-  classes that are already stored. The simplest way to do this with Grok is to
-  attach them somehow to the ``grok.Application`` object, directly or
-  indirectly. This can be done by setting them as an attribute, or by putting
-  them in a container (if you made your application subclass
-  ``grok.Container``).
-
-* To make sure that the ZODB knows you changed a mutable attribute (such as a
-  simple Python list or dictionary) in your instance, set the special
-  ``_p_changed`` attribute on that instance to ``True``. This is only necessary
-  if that attribute is not ``Persistent`` itself. It is also not necessary when
-  you create or overwrite an attribute directly using ``=``.
-
-If you construct your application's content out of ``grok.Model`` and
-``grok.Container`` subclasses you mostly follow the rules already. Just
-remember to set ``_p_changed`` in your methods if you find yourself modifying a
-Python list (with ``append``, for instance) or dictionary (by storing a value
-in it).
-
-The code in the section `Storing data`_ is a simple example. We in fact have to
-do nothing special at all to obey the rules of persistence in that case.
-
-If we use a mutable object such as a list or dictionary to store data instead,
-we do need to take special action. Let's change our example code (based on the
-last section) to use a mutable object (a list):
-
-.. include:: groktut/the_rules_of_persistence/src/sample/app.py
-  :literal:
-
-We have now changed the ``Sample`` class to do something new: it has an
-``__init__`` method. Whenever you create the ``Sample`` application object now,
-it will be created with an attribute called ``list``, which will contain an
-empty Python list.
-
-We also make sure that the ``__init__`` method of the superclass still gets
-executed, by using the regular Python ``super`` idiom. If we didn't do that,
-our container would not be fully initialized.
-
-You will also notice a small change to the ``update`` method of the ``Edit``
-class. Instead of just storing the text as an attribute of our ``Sample``
-model, we add each text we enter to the new ``list`` attribute on.
-
-Note that this code has a subtle bug in it, which is why we've added the
-comment. We will see what bug this is in a little bit. First, though, let's
-change our templates.
-
-We change ``index.pt`` so that it displays the list:
-
-.. include:: groktut/the_rules_of_persistence/src/sample/app_templates/index.pt
-  :literal:
-
-We've also changed the text of the link to the ``edit`` page to reflect the new
-adding behavior of our application.
-
-We need to undo the change to the ``edit.pt`` template that we made in the last
-section, as each time we edit a text we now *add* a new text, instead of
-changing the original. There is therefore no text to show in as the input value
-anymore:
-
-.. include:: groktut/the_rules_of_persistence/src/sample/app_templates/edit.pt
-  :literal:
-
-.. sidebar:: evolution
-
-  What to do when you change an object's storage structure while your
-  application is already in production? In a later section, we will introduce
-  Zope Toolkit's object evolution mechanism that allows you to update objects
-  in an existing object database. TDB
-
-Let's restart the server. If you have followed the tutorial from the last
-section, you will now see an error when you look at the front page of the
-application::
-
-  A system error occurred.
-
-Look at the output we got when we tried to load our page::
-
-  AttributeError: 'Sample' object has no attribute 'list'
-
-But we just changed our object to have an attribute ``list``, right? Yes we
-did, but only for *new* instances of the Sample object. What we are looking at
-is the sample object from before, still stored in the object database. It has
-no such attribute. This isn't a bug by the way (for our actual bug, see later
-in this section): it is just a database problem.
-
-What to do now? The simplest action to take during development is to simply
-remove our previously installed application, and create a new one that *does*
-have this attribute. Go to the Grok admin screen:
-
-  http://localhost:8080
-
-Select the application object (``test``) and delete it. Now install it again,
-as ``test``. Now go to its edit screen and add a text:
-
-  http://localhost:8080/test/edit
-
-Click on ``add a text`` and add another text. You will see the new texts appear
-on the ``index`` page.
-
-Everything is just fine now, right? In fact, not so! Now we will get to our
-bug. Restart the server and look at the index page again:
-
-  http://localhost:8080/test
-
-None of the texts we added were saved! What happened? We broke the third rule
-of persistence as described above: we modified a mutable attribute and did not
-notify the database that we made this change. This means that the object
-database was not aware of our change to the object in memory, and thus never
-saved it to disk.
-
-.. sidebar: The ZODB only stores instance data
-
-  Note that the ZODB only stores ("persists") instance data. This means that
-  any data you have directly associated with a class, as opposed to the
-  instance, won't be persisted. Normally you only associate immutable data with
-  the class, so this is not a problem::
-
-    class Foo(object):
-        mydata = 'some text'
-
-  That data will be there when the module is imported, and since it will never
-  be changed, there isn't a problem. Now let's check what happens with mutable
-  data::
-
-    class Foo(object):
-        mydata = []
-
-  Appending an item to mydata (through ``self.mydata.append('bar')``, for
-  instance) have an effect, but only until you restart the server. Then your
-  changes will be lost.
-
-  It is good Python design practice not to use mutable class-data, so this
-  property of the ZODB shouldn't cramp your style.
-
-We can easily amend this by adding one line to the code:
-
-.. include:: groktut/the_rules_of_persistence2/src/sample/app.py
-  :literal:
-
-We've now told the server that the context object has changed (because we
-modified a mutable sub-object), by adding the line::
-
-  self.context._p_changed = True
-
-If you now add some texts and then restart the server, you will notice the data
-is still there: it has successfully been stored in the object database.
-
-The code shown so far is a bit ugly in the sense that typically we would want
-to manage our state in the model code (the ``Sample`` object in this case), and
-not in the view. Let's make one final change to show what that would look like:
-
-.. include:: groktut/the_rules_of_persistence3/src/sample/app.py
-  :literal:
-
-As you can see, we have created a method ``addText`` to the model that takes
-care of amending the list and informing the ZODB about it. This way, any view
-code can safely use the API of ``Sample`` without having to worry about the
-rules of persistence itself, as that is the model's responsibility.
-
-Explicitly associating a view with a model
-------------------------------------------
-
-How does Grok know that a view belongs to a model? In the previous examples,
-Grok has made this association automatically. Grok could do this because there
-was only a single model defined in the module (``Sample``). In this case, Grok
-is clever enough to automatically associate all views defined elsewhere in the
-same module to the only model. Behind the scenes Grok made the model the
-*context* of the views.
-
-Everything that Grok does implicitly you can also tell Grok to do explicitly.
-This will come in handy later, as you may sometimes need (or want) to tell Grok
-what to do, overriding its default behavior. To associate a view with a model
-automatically, you use the ``grok.context`` class annotation.
-
-What is a class annotation? A class annotation is a declarative way to tell
-grok something about a Python class. Let's look at an example. We will change
-``app.py`` in the example from `A second view` to demonstrate the use of
-``grok.context``:
-
-.. include:: groktut/explicitly_associating_a_view_with_a_model/src/sample/app.py
-  :literal:
-
-This code behaves in exactly the same way as the previous example in `A second
-view`, but has the relationship between the model and the view made explicit,
-using the ``grok.context`` class annotation.
-
-``grok.context`` is just one class annotation out of many. We will see another
-one (``grok.name``) in the next section.
-
-A second model
---------------
-
-.. sidebar:: How to combine models into a single application?
-
-  Curious now about how to combine models into a single application? Can't
-  wait? Look at the section `Containers` coming up next, or `Traversal` later
-  on. TDB
-
-We will now extend our application with a second model. Since we haven't
-explained yet how to combine models together into a single application, we will
-just create a second application next to our first one. Normally we probably
-wouldn't want to define two applications in the same module, but we are trying
-to illustrate a few points, so please bear with us. Change ``app.py`` so it
-looks like this:
-
-.. include:: groktut/a_second_model/src/sample/app.py
-  :literal:
-
-You can see we now defined a second application class, ``Another``. It
-subclasses from ``grok.Application`` to make it an installable application.
-
-It also subclasses from ``grok.Model``. There is a difference between
-``grok.Model`` and ``grok.Container``, but for the purpose of the discussion we
-can ignore it for now. We just figured we should use ``grok.Model`` for some
-variety, though we could have indeed subclassed from ``grok.Container`` instead.
-
-We also define two templates, one called ``sampleindex.pt``:
-
-.. include:: groktut/a_second_model/src/sample/app_templates/sampleindex.pt
-  :literal:
-
-And one called ``anotherindex.pt``:
-
-.. include:: groktut/a_second_model/src/sample/app_templates/anotherindex.pt
-  :literal:
-
-We have named the templates the name as the lowercased class names as the
-views, so that they get associated with them.
-
-You will have noticed we have used ``grok.context`` to associate the views with
-models. We actually *have* to do this here, as Grok refuses to guess in the
-face of ambiguity. Without the use of ``grok.context``, we would have seen an
-error like this when we start up::
-
-  GrokError: Multiple possible contexts for <class
-  'sample.app.AnotherIndex'>, please use grok.context.
-
-So, we use ``grok.context`` to explicitly associate ``SampleIndex`` with the
-``Sample`` application, and again to associate ``AnotherIndex`` with the
-``Another`` application.
-
-We have another problem: the intent is for these views to be ``index`` views.
-This cannot be deduced automatically from the name of the view classes however,
-and left to its own devices, Grok would have called the views ``sampleindex``
-and ``anotherindex``.
-
-Luckily we have another class annotation that can help us here: ``grok.name``.
-We can use it on both view classes (``grok.name('index')``) to explicitly
-explain to Grok what we want.
-
-You can now try to restart the server and create both applications in the Grok
-Admin interface. They should display the correct index pages when you look at
-them.
-
-We can see that the introduction of a second model has complicated our code a
-bit, though you will hopefully agree with us that it is still quite readable.
-We could have avoided the whole problem by simply placing ``Another`` and its
-views in another module such as ``another.py``. Its associated templates would
-then need to be placed in a directory ``another_templates``. Often you will
-find it possible to structure your application so you can use Grok's default
-conventions.
-
-Containers
-----------
-
-A container is a special kind of model object that can contain other objects.
-Our ``Sample`` application is already a container, as it subclasses
-``grok.Container``. What we will do in this section is build an application
-that actually puts something into that container.
-
-Grok applications are typically composed of containers and models. Containers
-are objects that can contain models. This includes other containers, as a
-container is just a special kind of model.
-
-From the perspective of Python, you can think of containers as dictionaries.
-They allow item access (``container['key']``) to get at its contents. They also
-define methods such as ``keys()`` and ``values()``. Containers do a lot more
-than Python dictionaries though: they are persistent, and when you modify them,
-you don't have to use `_p_changed` anywhere to notice you changed them. They
-also send out special events that you can listen to when items are placed in
-them or removed from them. For more on that, see the section on events (TDB).
-
-Our application object will have a single index page that displays the list of
-items in the container. You can click an item in the list to view that item.
-Below the list, it will display a form that allows you to create new items.
-
-Here is the ``app.py`` of our new application:
-
-.. include:: groktut/containers/src/sample/app.py
-  :literal:
-
-As you can see, ``Sample`` is unchanged. We have also created our first non-
-application object, ``Entry``. It is just a ``grok.Model``. It needs to be
-created with an argument ``text`` and this text is stored in it. We intend to
-place instances of ``Entry`` in our ``Sample`` container.
-
-Next are the views. We have an ``index`` page for the ``Sample`` container.
-When its ``update()`` is triggered with two values, ``name`` and ``text``, it
-will create a new ``Entry`` instance with the given text, and place it under
-the container under the name ``name``. We use the dictionary-like interface of
-our ``Sample`` container to put our new ``Entry`` in the container.
-
-Here is the associated template for ``SampleIndex``, ``sampleindex.pt``:
-
-.. include:: groktut/containers/src/sample/app_templates/sampleindex.pt
-  :literal:
-
-The first section in the template (``<h2>Existing entries</h2>``) displays a
-list of the items in the container. We again use dictionary-like access using
-``keys()`` to get a list of all the names of the items in the container. We
-create a link to these items using ``view.url()``.
-
-The next section (``<h2>Add a new entry</h2>``) displays a simple form that
-submits to the index page itself. It has two fields, ``name`` and ``text``,
-which we already have seen handled by ``update()``.
-
-Finally, we have an ``index`` page for ``Entry``. It just has a template to
-display the ``text`` attribute:
-
-.. include:: groktut/containers/src/sample/app_templates/entryindex.pt
-  :literal:
-
-Restart the server and try this application. Call your application ``test``.
-Pay special attention to the URLs.
-
-First, we have the index page of our application:
-
-  http://localhost:8080/test
-
-When we create an entry called ``hello`` in the form, and then click on it in
-the list, you see an URL that looks like this:
-
-  http://localhost:8080/test/hello
-
-We are now looking at the index page of the instance of ``Entry`` called
-``hello``.
-
-What kind of extensions to this application can we think of? We could create an
-``edit`` form that allows you to edit the text of entries. We could modify our
-application so that you can not just add instances of ``Entry``, but also other
-containers. If you made those modifications, you would be on your way to
-building your own content management system with Grok.

Deleted: grok/trunk/doc/tutorial_outline.txt
===================================================================
--- grok/trunk/doc/tutorial_outline.txt	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/tutorial_outline.txt	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,236 +0,0 @@
-================
-Tutorial outline
-================
-
-This is not the tutorial itself, but a sketch of what the tutorial
-could look like. This hopefully inspires people to contribute to the
-tutorial. The structure of the tutorial is very much use-case driven
-and about getting things done. This means we tend to discuss the
-component architecture itself very late.
-
-Note that while I've indicated the overal aim of sections in chapters,
-that doesn't mean a chapter is absolutely decicated to a single
-topic. If for instance in the course of explaining search it becomes
-important to override traversal, it can be discussed right there.
-
-Main tutorial
-=============
-
-Getting started with Grok
--------------------------
-
-This section aims to get a beginner up and running with Grok, using
-grokproject. It doesn't really go into any code yet, except to
-describe what grokproject creates.
-
-  * Setting up grokproject
-
-  * Creating a grok project
-
-  * Starting up Zope
-
-  * An empty Grok project
-
-Showing pages
--------------
-
-We get beginners up to speed with writing view logic in Grok. This is
-basically the first thing beginners want - just get some HTML on the
-screen. Basic templating, supplementing templating with view-level
-methods, and various basic interaction patterns. Models are still out
-of scope. Armed with this knowledge people should already be able to
-write simple web applications with Grok, if at least they don't have
-to worry much about storing data.
-
-  * Publishing a simple web page
-
-  * A second view
-
-  * Making our page dynamic
-
-  * Static resources for our web page
-
-  * Using view methods
-
-  * Generating HTML from Python
-
-  * Completely Python-driven views
-
-  * Doing some calculation before viewing a page
-
-  * Reading URL parameters
-
-  * Simple forms
-
-Models
-------
-
-Once we know how to show things, we need to go into what we're
-actually showing: the model. This involves view/model separation,
-dealing with the ZODB and persistence, and constructing applications
-from models and containers. 
-
-Note that we also include some more advanced view use cases which only
-tend to become relevant with more complicated applications (such as
-redirection).
-
-  * A view for a model
- 
-  * Storing data
- 
-  * Redirection
-
-  * Showing the value in the form
-
-  * The rules of persistence
- 
-  * Containers
-
-Some notes:
-
-* What if a container already contains an item with the same name? We will
-  get an error. How to handle this error elegantly?
-
-Forms
------
-
-Now that we've seen the form and storage basics, we go a step further
-and show the power of automatic form generation from schemas.
-
-Building on the patterns we've seen before, we develop a simple CRUD
-application with an overview screen and add and edit forms. This will
-also include at least a glance at interfaces in the context of
-schemas.
-
-Search
-------
-
-We have a way for a user to enter information. Now we need to build an
-application that does something with it. We extend our CRUD
-application with indexing and search, using the catalog.
-
-By now the application should also be advanced enough to explain
-overriding traversal, for instance to enable simple 'tag' based
-browsing mechanism based on search. We need to show a pattern where
-non-persistent objects are created in traversal.
-
-This will also lead into a brief introduction of utility lookup and
-sites.
-
-XXX setting up the catalog is easy now, but it can be automated a bit
-    further still in Grok.
-
-XXX We probably need hurry.query. This needs some work on the Grok end
-    to expose this nicely.
-
-Custom widgets
---------------
-
-The defaults are never enough when it comes to web forms. This is a
-nice point to introduce making your own custom form widgets.
-
-We will also show how you can use AJAX with Grok so you can give your
-widget some dynamic behavior.
-
-XXX we need to make it easy to make widgets in Grok.
-
-XXX this needs work on the Grok end to at least expose JSON, and perhaps
-     we need to ship with a 'recommended' Javascript library.
-
-Security
---------
-
-Explain how Grok allows you to protect your views. In the course of
-this we also need to explain a bit about Zope 3's user authentication
-system, as we need users to test this with.
-
-XXX We need to flesh out user authentication issues in Grok.
-
-Extending our application
--------------------------
-
-We show one of Zope 3's main strengths: we create a separate codebase
-in a completely separate project that extends the first. Then we
-demonstrate many extension patterns Zope 3 offers:
-
-  * creating an extension project (using buildout and SVN externals?)
-
-  * a new look for old models (skins)
-
-  * the benefit of interfaces
-
-  * events
-
-  * adapters
-
-Appendices
-==========
-
-While these topics may not presuppose a lot of knowledge, we probably
-do not want to scatter all of this through the tutorial itself so as
-not to distract from the main story (though we may change our minds if
-it seems to come out naturally).
-
-Explicit configuration
-----------------------
-
-Should give an introduction on the principles of Grok: explicit
-configuration using directives, with defaults so you can leave them
-off if you follow the grok patterns.
-
-I'm not sure yet whether this can be part of the main flow of the
-text. We at the very least will refer to this at some point in the
-text though, and we need to refer people to this for more information.
-
-The Component Architecture
---------------------------
-
-Explain how many bits and pieces we've seen so far are actually
-aspects of the component architecture.
-
-Automatic testing
------------------
-
-A brief introduction to automatic testing. Introduce how to unit test
-and functional test with doctests.
-
-XXX We probably need to do some development work on a test grokker.
-
-XMLRPC 
-------
-
-Show how to do XMLRPC with Grok.
-
-Extending grok
---------------
-
-Grok can be extended using Grokkers. Explain how to do it here.
-
-Development issues
-------------------
-
-We describe best practices on how to manage your code when developing
-with Grok. This touches topics like setup.py, buildout, and also
-version control systems.
-
- * Pulling in new dependencies from the Cheeseshop.
-
- * Putting your project into SVN
-
- * Uploading your project to the Python Cheeseshop
-
-Items I'm not sure where to place yet
-=====================================
-
-These items will need to find a place in the main narrative or the
-appendices. They're listed here so we don't forget about them:
-
-  * Constructing urls with view.url()
-
-  * base classes
-
-  * Events
-
-  * Showing error pages.
-
-  * Discussion on viewlets/portlets.

Deleted: grok/trunk/doc/upgrade.rst
===================================================================
--- grok/trunk/doc/upgrade.rst	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/upgrade.rst	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1 +0,0 @@
-.. include:: upgrade.txt

Deleted: grok/trunk/doc/upgrade.txt
===================================================================
--- grok/trunk/doc/upgrade.txt	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/doc/upgrade.txt	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,619 +0,0 @@
-.. _upgrade_notes:
-
-
-Upgrade notes
-=============
-
-This document outlines how to update Grok applications so that they continue to
-work with newer versions of the Grok Toolkit. This document only describes
-changes involving incompatibilities or deprecations, not new features (please
-refer to ``CHANGES.txt`` for those).
-
-**Warning**. Please be sure to always backup your data (especially the
-``Data.fs`` file) before you perform upgrades.
-
-.. _upgrade_notes_1.2:
-
-Upgrading to 1.2 (2010-10-26)
------------------------------
-
-To upgrade your Grok based project, make sure your project's ``buildout.cfg``
-extends from the ``versions.cfg`` of the latest Grok Toolkit release. This file
-can be found here::
-
-    http://grok.zope.org/releaseinfo/1.2/versions.cfg
-
-Then re-run ``bootstrap.py`` in your project to prevent potential
-``zc.buildout`` version conflicts. Then run ``bin/buildout`` to get the latest
-versions of all of the packages that comprise the Grok Toolkit.
-
-Extra notes:
-
-* In Grok 1.2 the "zdaemon" support has been removed. If your project still
-  relied on this method of starting and stopping the server you will need to
-  update your prokject.
-
-  The easiest way for find what parts and file to add, is to create a new
-  project using the ``grokproject`` tool and then to compare its structure to
-  your project's structure. Look for the "debug_ini" and "deploy_ini" parts in
-  the ``buildout.cfg`` file and the corresponding configuration file templates.
-
-* A large numner of ``zope.app.`` dependencies have been removed. Even though
-  most of these packages just contained backwards compatibility imports, your
-  application might still contain imports from these ``zope.app.`` packages.
-
-  The best way to update this, is to carefully search for ``zope.app.`` imports
-  in your project and to rewrite them to the new import locations. Note though,
-  that in rare cases, this might break persisted object in your database.
-
-  If this is the case, you will need to add the particular ``zope.app.``
-  package to the ``install_requires`` section in the ``setup.py`` of your
-  project. After a re-run of ``./bin/buildout`` these package are now again
-  available to your project.
-
-  In general it is good practice to explicitely list the dependencies of your
-  project in the ``setup.py``. In other words: if your project imports from
-  packages, these packages should be listed in the ``install_requires`` of your
-  project's ``setup.py``.
-
-* One specific case of a ``zope.app.`` depdendency that got removed and
-  replaced is ``zope.app.testing`` that is used in the test setup of your
-  project. Most of the functionality in ``zope.app.testing`` has been rebuild
-  in ``zope.component.testlayer``, ``zope.app.appsetup``, and
-  ``zope.app.wsgi.testlayer``.
-
-  Again, the easiest way to upgrade this part of your project, is to look a
-  freshly created project using the ``grokproject`` tool. There, the test setup
-  code uses the "new style" test layers for functional testing.
-
-* In some case the configuration step of a dependency is not triggered
-  anymore, where it used to be before most of the ``zope.app.`` dependencies
-  got removed. If this is the case (for example for components in in
-  zope.pluggableauth.plugins), you will need to trigger the configuration
-  yourself from your project's ``configure.zcml`` like so::
-
-    <include package="[PACKAGE_TO_CONFIGURE]" />
-
-  or, for a specific ``*.zcml`` file in package::
-
-    <include package="[PACKAGE_TO_CONFIGURE]" file="[ZCML_FILE]"/>
-
-.. _upgrade_notes_1.1:
-
-Upgrading to 1.1 (2010-05-18)
------------------------------
-
-* `z3c.testsetup` dependency has been removed from grok. If you use
-  grok.testing.register_all_tests in your testsetup, make sure to
-  require ``z3c.testsetup`` (and also ``zope.app.testing``, if you use
-  functional tests) in `setup.py` of your project and use::
-
-    import z3c.testsetsetup
-    z3c.testsetup.register_all_tests(...)
-
-  where you used ``grok.testing.register_all_tests(...)`` before.
-
-.. _upgrade_notes_1.1rc1:
-
-Upgrading to 1.1rc1 (2010-02-25)
---------------------------------
-
-* When upgrading to a newer version of Grok, you should refer to the
-  newest list of versions as defined for this release of Grok.
-
-  For Grok 1.1rc1, download the following file::
-
-    http://grok.zope.org/releaseinfo/grok-1.1rc1.cfg
-
-  And replace ``versions.cfg`` in your project with this file. Then run::
-
-    ./bin/buildout
-
-.. _upgrade_notes_1.1a2:
-
-Upgrading to 1.1a2 (2009-12-22)
--------------------------------
-
-* When upgrading to a newer version of Grok, you should refer to the
-  newest list of versions as defined for this release of Grok.
-
-  For Grok 1.1a2, download the following file::
-
-    http://grok.zope.org/releaseinfo/grok-1.1a2.cfg
-
-  And replace ``versions.cfg`` in your project with this file. Then run::
-
-    ./bin/buildout
-
-.. _upgrade_notes_1.1a1:
-
-Upgrading to 1.1a1 (2009-11-17)
--------------------------------
-
-* When upgrading to a newer version of Grok, you should refer to the
-  newest list of versions as defined for this release of Grok.
-
-  For Grok 1.1a1, download the following file::
-
-    http://grok.zope.org/releaseinfo/grok-1.1a1.cfg
-
-  And replace ``versions.cfg`` in your project with this file. Then run::
-
-    ./bin/buildout
-
-.. _upgrade_notes_1.0b2:
-
-Upgrading to 1.0b2 (2009-09-15)
--------------------------------
-
-* The default permission is now ``zope.View`` as a replacement for
-  ``zope.Public``.  You need to add this permission as a default
-  permission to all users (use ``zope.Anybody``). This requires a
-  change to ``site.zcml`` as follows::
-
-      <grant permission="zope.View"
-             principal="zope.Anybody" />
-
-  **If you do not make this change, all of your views will be
-  unavailable for anonymous and the system will ask the user for a
-  password.**
-
-  This change allows you to protect Grok views that come with the
-  default permission by modifying your ``site.zcml``.
-
-  If you used a previous version of Grok or grokproject you may still
-  have a reference to ``grok.View`` in ``site.zcml`` or
-  ``ftesting.zcml``. This will lead to an error, as Grok does not
-  define ``grok.View`` anymore. It's safe to remove such references.
-
-* When upgrading to a newer version of Grok, you should refer to the
-  newest list of versions as defined for this release of Grok.
-
-  For Grok 1.0b2, download the following file::
-
-    http://grok.zope.org/releaseinfo/grok-1.0b2.cfg
-
-  And replace ``versions.cfg`` in your project with this file.
-
-* There have been a lot of changes in grokproject and the project
-  layout it generates. This gives you a short description of how you
-  can upgrade your existing Grok project that was generated with an
-  older version of grokproject.
-
-  You should upgrade grokproject as follows::
-
-      $ easy_install -U grokproject
-
-  grokproject now creates a project based on `Paste Deploy`_, along
-  with a few other changes to the way various files are managed.
-
-  .. _`Paste Deploy`: http://pythonpaste.org/deploy/
-
-  **Warning**. Please be aware that the ``parts/data`` and
-  ``parts/log`` directories are deprecated and will not be used
-  anymore. The only reasons there are still ``[data]`` and ``[log]``
-  sections in the new ``buildout.cfg``structure is to make sure we
-  don't accidentally throw away important data. Back up at least any
-  important ``Data.fs`` (which contains the ZODB object database of
-  your app) *before* making any changes to a project, or when you
-  upgrade any deployment.
-
-  To switch over your project to use a new layout, create a new, empty
-  project with grokproject and compare it with your current
-  layout. You can then compare it with your existing project layout
-  and make the appropriate changes to your project.
-
-  There have been changes to ``setup.py``, ``buildout.cfg`` and a new
-  ``etc`` directory has appeared.
-
-  The templates for config files are now in ``etc`` - these get
-  generated by buildout into ``parts/etc``.  Find more information on
-  configuration and settings in ``etc/README.txt``.
-
-  The ``Data.fs`` file is now placed in ``var/filestorage``. Please
-  copy your backed-up version of ``Data.fs`` in there to reuse your
-  older ZODB database.
-
-  Log files are now placed in ``var/log``.
-
-  Before re-running buildout to generate the new templates, please be
-  aware that ``parts/zopectl`` and ``parts/app`` will be deleted when
-  you re-run buildout. This means that ``parts/zopectl/access.log``
-  will be removed, and you may want to backup this file first.
-
-  After making these adjustments, you can now run ``buildout`` for the
-  project.
-
-  Start the instance now like::
-
-    bin/paster serve parts/etc/deploy.ini
-
-  or with::
-
-    bin/projectname-ctl fg
-
-  Alternatively there's a profile available that can help debugging errors in
-  your application::
-
-    bin/paster serve parts/etc/debug.ini
-
-  When using this profile it is not the ``zope.publisher`` that handles the
-  exceptions that are raised, but a special middleware is. This middleware
-  then provides a pdb-like debugging user interface in the browser.
-
-  Note that this includes IUnauthorized exceptions not being handled by zope,
-  that would've prevented any login mechanism to work when debugging.
-
-  However, there is a configuration option called ``exempt-exceptions``
-  available in the debug.ini that determines what exceptions should still be
-  handled by zope. By default debug.ini files created by grokproject will
-  exempt the IUnauthorized exceptions from being reraised and thus normal
-  authentication mechanism continue to work::
-
-    [app:zope]
-    use = egg:${egg}#debug
-    filter-with = translogger
-    exempt-exceptions = zope.security.interfaces.IUnauthorized
-
-  Interpreter name has been changed from ``bin/python`` to
-  ``bin/grokpy`` to avoid conflicts with virtualenv.
-
-
-* Old ``buildout.cfg`` contain a ``find-links`` line like this::
-
-   find-links = http://download.zope.org/distribution/
-
-  You should be able to safely remove this, as this points to a
-  repository of old releases that Grok doesn't depend on any more.
-
-  If you have problems after removing it and re-running ``bin/buildout``,
-  you can add it again however. We know that ``megrok.form`` for instance
-  depends on a release that was only available in this repository.
-
-* Note: in 1.0b1 we used to have a split between ``View`` and
-  ``CodeView``.  This split got reverted. Grok's behavior is still the
-  same as in the 1.0a versions - views and the ``render`` method continue
-  to work as they did before.
-
-.. _upgrade_notes_1.0a1:
-
-Upgrading to 1.0b1 (2009-09-14)
--------------------------------
-
-* This release happened was never completed. See the upgrade
-  documentation for 1.0b2 instead.
-
-Upgrading to 1.0a1
-------------------
-
-* The ``grok.RESTProtocol`` class has been removed in favour of a
-  ``grok.restskin()`` directive for interfaces.  For instance, if you
-  previously registered a REST layer as a skin like so::
-
-    class IMyLayer(grok.IRESTLayer):
-        pass
-
-    class MyRestProtocol(grok.RESTProtocol):
-        grok.layer(IMyLayer)
-
-  You can now simply write::
-
-    class IMyLayer(grok.IRESTLayer):
-        grok.restskin('myskin')
-
-  As you can see, ``IRESTLayer`` has been introduced as a baseclass for
-  defining REST layers.
-
-.. _upgrade_notes_0.14:
-
-Upgrading to 0.14
------------------
-
-* The ``grok.Skin`` class has been removed in favour of a
-  ``grok.skin()`` directive for interfaces.  For instance, if you
-  previously registered a browser layer as a skin like so::
-
-    class IMyLayer(grok.IGrokLayer):
-        pass
-
-    class MySkin(grok.Skin):
-        grok.layer(IMyLayer)
-
-  You can now simply write::
-
-    class IMyLayer(grok.IBrowserRequest):
-        grok.skin('myskin')
-
-  As you can see, ``IGrokLayer`` has also been removed, in favour of
-  the exposure of ``IBrowserRequest``.
-
-* The ``grok.admin`` subpackage has been factored out to a separate
-  package ``grokui.admin``. To have the Grok admin UI available in
-  your environment, add ``grokui.admin`` to the required packages in
-  the ``setup.py`` of your package.
-
-  A new Grok application will have an install_requires parameter that
-  looks like this::
-
-      install_requires=['setuptools',
-                        'grok',
-                        'grokui.admin',
-                        'z3c.testsetup',
-                        # Add extra requirements here
-                        ],
-
-.. _upgrade_notes_0.13:
-
-Upgrading to 0.13
------------------
-
-* The directive implementations changed tremendously with the upgrade
-  to Martian 0.10.  Custom implementations of both directives (see
-  next bullet point) and grokkers will have to be adjusted.
-
-  Since the vast majority of directives are class directives, the most
-  common places where information set by directives has to be read are
-  class grokkers (``martian.ClassGrokker``).  For instance, you may
-  have written something like this to implement a custom class grokker
-  previously::
-
-    class RobotGrokker(martian.ClassGrokker):
-        component_class = Robot
-
-        def grok(self, name, factory, module_info, config, **kw):
-            robot_name = martian.util.class_annotation(factory, 'grok.name', '')
-            title = martian.util.class_annotation(factory, 'grok.title', 'A robot')
-            provides = martian.util.class_annotation(factory, 'grok.provides', None)
-            if provides is None:
-                martian.util.check_implements_one(factory)
-                provides = list(zope.interface.implementedBy(factory))[0]
-            config.action(
-                descriminator=('robot', provides, robot_name),
-                callable=provideRobot,
-                args=(factory, provides, robot_name, title),
-                )
-            return True
-
-  As you can see, this grokker needs to retrieve three values from the
-  class it's grokking (``factory``) which are all set by directives:
-
-  - ``grok.name`` with the standard default, an empty string,
-
-  - ``grok.title`` with a custom default, the string ``A robot``,
-
-  - ``grok.provides`` with a computed default.
-
-  With the new directive implementation and the extensions to
-  Martian's ``ClassGrokker``, you are now able to write (and you
-  should write!)::
-
-    def default_provides(factory, module, **data):
-        # This function is available for import from grokcore.component.meta.
-        # It's shown here simply to illustrate how the original grokker would
-        # have been refactored.
-        martian.util.check_implements_one(factory)
-        return list(zope.interface.implementedBy(factory))[0]
-
-    class RobotGrokker(martian.ClassGrokker):
-        martian.component(Robot)
-        martian.directive(grok.name, name='robot_name')
-        martian.directive(grok.title, default='A Robot')
-        martian.directive(grok.provides, get_default=default_provides)
-
-        def execute(self, factory, config, robot_name, title, provides, **kw):
-            config.action(
-                descriminator=('robot', provides, robot_name),
-                callable=provideRobot,
-                args=(factory, provides, robot_name, title),
-                )
-            return True
-
-  What you need to do is provide the directives in the grokker class
-  using ``martian.directive`` and then implement the ``execute``
-  method which will get the class (``factory``) and the configuration
-  context (``config``) as positional arguments and then the values of
-  the directives as keyword parameters.
-
-  Note that when using ``martian.directive``, you may
-
-  - set the name of the keyword parameter if you want it to be
-    different than the directive's name,
-
-  - set a default value if you want it to be different from the
-    directive's standard default,
-
-  - pass in a factory for a computed default value (``get_default``).
-
-  If you need still need to manually retrieve directive values from an
-  object (a class, an instance or a module), you can do so by
-  explicitly calling ``bind`` on the directive (which accepts the same
-  optional parameters as ``martian.directive``), and then the ``get``
-  method of the bound directive, e.g.::
-
-    class_context = grok.context.bind().get(factory, module=module)
-    just_module_context = grok.context.bind().get(module=module)
-
-  In most cases it's possible to avoid this though, and use the
-  ``martian.directive`` directive on the class level.
-
-  You can look at ``src/grok/meta.py`` in Grok to see examples.
-
-* Your custom grokker could previously use ``component_class`` and
-  ``priority`` as class-level variables. These have been changed to
-  the ``martian.component`` and the ``martian.priority`` directives
-  that take the value as its first argument. The new
-  ``martian.directive`` directive was introduced above.
-
-* Custom directives need to be re-implemented using Martian's new
-  ``Directive`` base class.  The directive scope, the type of storage,
-  the validator and a potential default value are all defined as
-  class-level variables:
-
-  - The directive scope can either one of ``martian.CLASS``,
-    ``martian.MODULE``, ``martian.CLASS_OR_MODULE``.
-
-  - The type of storage can be either one of ``martian.ONCE``,
-    ``martian.MULTIPLE``, ``martian.DICT``.
-
-  - An optional validator may be one of ``validateText``,
-    ``validateInterface``, ``validateInterfaceOrClass`` or a custom
-    method.
-
-  - Unless set with a different value, the standard default value will
-    be ``None``.
-
-  For example, consider the implementation of the ``grok.name``
-  directive::
-
-    class name(martian.Directive):
-        scope = martian.CLASS
-        store = martian.ONCE
-        default = u''
-        validate = martian.validateText
-
-  Or a bit more involved (and made-up) example::
-
-    class bases(martian.Directive):
-        scope = martian.CLASS
-        scope = martian.ONCE
-        default = []
-
-        # The factory is called with the parameters of the directive
-        # and may transform the values into whatever should be stored.
-        def factory(self, *values):
-            return list(values)
-
-        # This validator makes sure that the directive can only take
-        # a list of classes an argument
-        def validate(self, *values):
-            for value in values:
-                if not isinstance(value, type):
-                    raise GrokError("%r is not a class!" % value)
-
-* We moved to newer versions of zope packages. Grok's versions for
-  Zope packages are now based on the KGS list for Zope 3.4c1 (the
-  latest list).  This means your code can now get some new deprecation
-  warnings for imports that have been moved. Please check your code
-  and fix your imports if you get those warnings.
-
-* If you were using ``zope.publisher.http.applySkin``, you now must
-  use ``grok.util.applySkin``. This because
-  ``zope.publisher.http.appySkin`` was removed again in later versions
-  of ``zope.publisher``.
-
-* The ``url`` method on ``ViewletManager`` and ``Viewlet`` was
-  removed. Instead you can easily access the ``url`` method of the
-  view itself from within a viewlet or viewlet manager, and the
-  ``view`` name is also available in viewlet templates. There are also
-  new ``viewlet`` and ``viewletmanager`` namespaces in the viewlet
-  templates. Note that ``view`` in a viewlet thus means something else
-  than what it does before. Previous uses of ``view`` in a viewlet
-  template should be renamed to ``viewlet``.
-
-.. _upgrade_notes_0.12:
-
-Upgrading to 0.12
------------------
-
-* Please upgrade grokproject::
-
-    $ easy_install -U grokproject
-
-* If you have existing Grok projects and you want to make use of
-  Grok's new autoinclusion functionality in them, you can place
-  the following line in your project's ``configure.zcml``:
-
-    <includeDependencies package="." />
-
-  This will cause the ZCML for ``setup.py`` dependencies of your
-  package to be loaded automatically. You can now get rid of any
-  manual ``include`` statements (except the one that includes ``grok``
-  itself).
-
-  For new projects created by ``grokproject``, this line will be
-  automatically be added for you and you don't have to do anything except
-  to upgrade ``grokproject``::
-
-    $ easy_install -U grokproject
-
-* The convention that classes ending with -Base automatically become base
-  classes has been removed with martian 0.9.4. Please add the grok.baseclass()
-  directive to these classes explicitly where the 'Base' class convention was
-  relied upon to preserve existing functionality.
-
-.. _upgrade_notes_0.11:
-
-Upgrading to 0.11
------------------
-
-* ``grok.define_permission`` has been removed in favour of a
-  ``grok.Permission`` base class, for reasons of symmetry.  Instead of
-  writing::
-
-    grok.define_permission('myapp.ViewCavePainting')
-
-  you should now write::
-
-    class View(grok.Permission):
-        grok.name('myapp.ViewCavePainting')
-
-  If you also want to supply a title and description for the
-  permission, use the ``grok.title()`` and ``grok.description()``
-  directives on the class.
-
-* ``grok.grok`` and ``grok.grok_component`` have been deprecated.  If
-  you need them for tests (which is their only legimitate use), you
-  should import them both from ``grok.testing``.
-
-* Grokkers should now emit configuration actions instead of
-  registering components right away.  For that they now get a new
-  keyword argument called ``config``, the configuration context.  For
-  example, a grokker that used to do this::
-
-    registerSomeComponent(foo, name)
-
-  should now be doing this::
-
-    config.action(
-        discriminator=('somecomponent', name),
-        callable=registerSomeComponent,
-        args=(name,)
-        )
-
-  The discriminator should be chosen so that registrations with the
-  same discriminator conflict (in the above example, if somebody tried
-  to register two different components under the same name, you'd get
-  a conflict).
-
-* Grokkers no longer get the ``context`` and ``templates`` keyword
-  arguments.  If they need access to these values, they can now get
-  them as module annotations from the ``module_info`` object like
-  this::
-
-      context = module_info.getAnnotation('grok.context')
-      templates = module_info.getAnnotation('grok.templates')
-
-* Note that grokkers must always take arbitrary keyword arguments
-  (``**kw``), as specified by the ``martian.interfaces.IGrokker``
-  interface.  A minimal specification of the ``grok()`` method is
-  therefore::
-
-    def grok(self, name, obj, **kw):
-        ...
-
-  though grokkers will likely want to take ``module_info`` as well as
-  ``config`` explicitly::
-
-    def grok(self, name, obj, module_info, config, **kw):
-        ...
-
-  If your application defines custom grokkers and you're getting a
-  ``TypeError`` about unexpected arguments to ``grok``, you likely
-  need to update the signature of the ``grok()`` method like described
-  above.
-
-
-Upgrading to 0.10
------------------
-
-There were no incompatible changes.

Modified: grok/trunk/documentation.cfg
===================================================================
--- grok/trunk/documentation.cfg	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/documentation.cfg	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,64 +1,17 @@
 [buildout]
-extends = http://svn.zope.org/repos/main/groktoolkit/trunk/grok.cfg
+extends = ../../grok.cfg
 develop = .
 parts =
-  docs
-  build_html
-#  build_pdf
-  cronjob-template
-versions = versions
+  sphinxpython
+  generate_documentation
 
-[versions]
-grok =
-# Override the Grok Toolkit for now.
-collective.recipe.template = 1.8
+[sphinxpython]
+recipe = z3c.recipe.scripts
+interpreter = sphinxpython
+eggs = grok
 
-[docs]
-recipe = zc.recipe.egg
-eggs =
-  grok
-  docutils
-  roman
-  sphinx
-dependent-scripts = true
-scripts =
-  sphinx-build
-  sphinx-quickstart
-
-[build_html]
-recipe = zc.recipe.egg
-eggs = ${docs:eggs}
-dependent-scripts = true
-scripts = sphinx-build=build_html
-arguments = argv=[sys.argv[0], "-b", "html"] + sys.argv[1:] + ["${buildout:directory}/doc", "${buildout:directory}/build/html"]
-
-[build_pdf]
-recipe = zc.recipe.egg
-eggs = ${docs:eggs}
-dependent-scripts = true
-scripts = sphinx-build=build_pdf
-arguments = argv=[sys.argv[0], "-b", "latex"] + sys.argv[1:] + ["${buildout:directory}/doc", "${buildout:directory}/build/latex"]
-
-[cronjob-template]
-recipe = collective.recipe.template
-document_root = ${buildout:directory}/build/docroot
-inline =
-  #!/bin/bash
-  cd ${buildout:directory}
-  svn update
-
-  # `make clean` substitute
-  rm -rf build/*
-
-  # `make html` substitute
-  ./bin/build_html
-
-  if [ $? == 0 ]; then
-      rm -rf ${:document_root}
-      cp -rf build/html ${:document_root}
-  else
-      echo "grokdocs html generation failed"
-  fi
-output = ${buildout:bin-directory}/build.sh
-mode = 755
-
+[generate_documentation]
+recipe = collective.recipe.sphinxbuilder
+source = ${buildout:directory}/doc
+build = ${buildout:directory}/doc/_build
+interpreter = ${buildout:bin-directory}/sphinxpython

Deleted: grok/trunk/documentation_deployment.cfg
===================================================================
--- grok/trunk/documentation_deployment.cfg	2011-01-17 10:15:15 UTC (rev 119617)
+++ grok/trunk/documentation_deployment.cfg	2011-01-17 11:06:31 UTC (rev 119618)
@@ -1,12 +0,0 @@
-[buildout]
-extends = documentation.cfg
-parts += cronjob
-
-[cronjob-template]
-recipe = collective.recipe.template
-document_root = /var/www/html/grok/doc/official
-
-[cronjob]
-recipe = z3c.recipe.usercrontab
-times = 0 * * * *
-command = ${cronjob-template:output} > ${buildout:directory}/build.log 2>&1



More information about the checkins mailing list