[Checkins] SVN: groktoolkit/branches/jw-documentation-rearangement/doc start moving Grok documentation to the groktoolkit

Jan-Wijbrand Kolman janwijbrand at gmail.com
Wed Jan 12 11:38:04 EST 2011


Log message for revision 119545:
  start moving Grok documentation to the groktoolkit

Changed:
  A   groktoolkit/branches/jw-documentation-rearangement/doc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/ACKS.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/Makefile
  A   groktoolkit/branches/jw-documentation-rearangement/doc/README.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/_build/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/_build/Makefile
  A   groktoolkit/branches/jw-documentation-rearangement/doc/_build/make.bat
  A   groktoolkit/branches/jw-documentation-rearangement/doc/_static/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/_static/default.css
  A   groktoolkit/branches/jw-documentation-rearangement/doc/_static/grok.css
  A   groktoolkit/branches/jw-documentation-rearangement/doc/_static/grok_club.gif
  A   groktoolkit/branches/jw-documentation-rearangement/doc/_static/logo.gif
  A   groktoolkit/branches/jw-documentation-rearangement/doc/_static/logo.png
  A   groktoolkit/branches/jw-documentation-rearangement/doc/_static/top_bg.jpg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/bugs.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/changes.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/conf.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/contents.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/copyright.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/adapters.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/annotations.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/container.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/grok_beginner.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/grok_dev.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/menu.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/model.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/permission.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/skin-minimal.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/skin.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/subscriber.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/traversal.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/utility.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/design/views.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/developing_grok.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/docindex.template
  A   groktoolkit/branches/jw-documentation-rearangement/doc/glossary.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/grok_overview.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app_templates/anotherindex.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app_templates/sampleindex.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app_templates/bye.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/ftesting.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/static/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/static/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/tests.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app_templates/entryindex.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app_templates/sampleindex.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app_templates/bye.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/ftesting.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/static/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/static/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/tests.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app_templates/edit.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app_templates/edit.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/static/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/static/style.css
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app_templates/edit.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app_templates/edit.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app_templates/edit.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app_templates/edit.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/bootstrap.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/buildout.cfg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/README.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/debug.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/deploy.ini.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/site.zcml.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/zope.conf.in
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/extends-cache/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/setup.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/__init__.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/app.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/app_templates/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/app_templates/index.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/configure.zcml
  A   groktoolkit/branches/jw-documentation-rearangement/doc/index.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/layout.html
  A   groktoolkit/branches/jw-documentation-rearangement/doc/license.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/make.bat
  A   groktoolkit/branches/jw-documentation-rearangement/doc/naming_conventions.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/reference/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/reference/components.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/reference/conf.py
  A   groktoolkit/branches/jw-documentation-rearangement/doc/reference/decorators.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/reference/directives.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/reference/events.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/reference/exceptions.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/reference/functions.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/reference/index.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/reference/testing.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/reference/utils.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/resources/
  A   groktoolkit/branches/jw-documentation-rearangement/doc/resources/evencaveman.jpg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/resources/grok-standing.jpg
  A   groktoolkit/branches/jw-documentation-rearangement/doc/style.tex
  A   groktoolkit/branches/jw-documentation-rearangement/doc/template.pt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/tutorial.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/tutorial_outline.txt
  A   groktoolkit/branches/jw-documentation-rearangement/doc/upgrade.rst
  A   groktoolkit/branches/jw-documentation-rearangement/doc/upgrade.txt
  A   groktoolkit/branches/jw-documentation-rearangement/documentation.cfg

-=-
Added: groktoolkit/branches/jw-documentation-rearangement/doc/ACKS.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/ACKS.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/ACKS.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,23 @@
+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

Added: groktoolkit/branches/jw-documentation-rearangement/doc/Makefile
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/Makefile	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/Makefile	2011-01-12 16:38:04 UTC (rev 119545)
@@ -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."

Added: groktoolkit/branches/jw-documentation-rearangement/doc/README.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/README.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/README.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,95 @@
+*********************
+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``.

Added: groktoolkit/branches/jw-documentation-rearangement/doc/_build/Makefile
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/_build/Makefile	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/_build/Makefile	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,130 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD = /home/jw/projects/grokdocumentation/groktoolkit/bin/grokpy /home/jw/projects/grokdocumentation/groktoolkit/bin/sphinx-build
+PAPER         =
+BUILDDIR      = /home/jw/projects/grokdocumentation/groktoolkit/doc/_build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) /home/jw/projects/grokdocumentation/groktoolkit/doc
+
+.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/docs.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/docs.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/docs"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/docs"
+	@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."

Added: groktoolkit/branches/jw-documentation-rearangement/doc/_build/make.bat
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/_build/make.bat	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/_build/make.bat	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,170 @@
+ at ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=/home/jw/projects/grokdocumentation/groktoolkit/doc/_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% /home/jw/projects/grokdocumentation/groktoolkit/doc
+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\docs.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\docs.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

Added: groktoolkit/branches/jw-documentation-rearangement/doc/_static/default.css
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/_static/default.css	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/_static/default.css	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,796 @@
+/**
+ * Sphinx Doc Design
+ */
+
+body {
+    font-family: sans-serif;
+    font-size: 100%;
+    background-color: #ff303d;
+    color: #000;
+    margin: 0;
+    padding: 0;
+}
+
+/* :::: LAYOUT :::: */
+
+div.document {
+    background-color: #1c4e63;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 230px;
+}
+
+div.body {
+    background-color: white;
+    padding: 0 20px 30px 20px;
+}
+
+div.sidebarwrapper {
+    padding: 10px 5px 0 10px;
+}
+
+div.sidebar {
+    float: left;
+    width: 230px;
+    margin-left: -100%;
+    font-size: 90%;
+}
+
+div.clearer {
+    clear: both;
+}
+
+div.footer {
+    color: #fff;
+    width: 100%;
+    padding: 9px 0 9px 0;
+    text-align: center;
+    font-size: 75%;
+}
+
+div.footer a {
+    color: #fff;
+    text-decoration: underline;
+}
+
+div.related {
+    background-color: #133f52;
+    color: #fff;
+    width: 100%;
+    height: 30px;
+    line-height: 30px;
+    font-size: 90%;
+}
+
+div.related h3 {
+    display: none;
+}
+
+div.related ul {
+    margin: 0;
+    padding: 0 0 0 10px;
+    list-style: none;
+}
+
+div.related li {
+    display: inline;
+}
+
+div.related li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+div.related a {
+    color: white;
+}
+
+/* ::: TOC :::: */
+div.sidebar h3 {
+    font-family: 'Trebuchet MS', sans-serif;
+    color: white;
+    font-size: 1.4em;
+    font-weight: normal;
+    margin: 0;
+    padding: 0;
+}
+
+div.sidebar h4 {
+    font-family: 'Trebuchet MS', sans-serif;
+    color: white;
+    font-size: 1.3em;
+    font-weight: normal;
+    margin: 5px 0 0 0;
+    padding: 0;
+}
+
+div.sidebar p {
+    color: white;
+}
+
+div.sidebar p.topless {
+    margin: 5px 10px 10px 10px;
+}
+
+div.sidebar ul {
+    margin: 10px;
+    padding: 0;
+    list-style: none;
+    color: white;
+}
+
+div.sidebar ul ul,
+div.sidebar ul.want-points {
+    margin-left: 20px;
+    list-style: square;
+}
+
+div.sidebar ul ul {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+div.sidebar a {
+    color: #98dbcc;
+}
+
+div.sidebar form {
+    margin-top: 10px;
+}
+
+div.sidebar input {
+    border: 1px solid #98dbcc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+/* :::: MODULE CLOUD :::: */
+div.modulecloud {
+    margin: -5px 10px 5px 10px;
+    padding: 10px;
+    line-height: 160%;
+    border: 1px solid #cbe7e5;
+    background-color: #f2fbfd;
+}
+
+div.modulecloud a {
+    padding: 0 5px 0 5px;
+}
+
+/* :::: SEARCH :::: */
+ul.search {
+    margin: 10px 0 0 20px;
+    padding: 0;
+}
+
+ul.search li {
+    padding: 5px 0 5px 20px;
+    background-image: url(file.png);
+    background-repeat: no-repeat;
+    background-position: 0 7px;
+}
+
+ul.search li a {
+    font-weight: bold;
+}
+
+ul.search li div.context {
+    color: #888;
+    margin: 2px 0 0 30px;
+    text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+    font-weight: bold;
+}
+
+/* :::: COMMON FORM STYLES :::: */
+
+div.actions {
+    padding: 5px 10px 5px 10px;
+    border-top: 1px solid #cbe7e5;
+    border-bottom: 1px solid #cbe7e5;
+    background-color: #e0f6f4;
+}
+
+form dl {
+    color: #333;
+}
+
+form dt {
+    clear: both;
+    float: left;
+    min-width: 110px;
+    margin-right: 10px;
+    padding-top: 2px;
+}
+
+input#homepage {
+    display: none;
+}
+
+div.error {
+    margin: 5px 20px 0 0;
+    padding: 5px;
+    border: 1px solid #d00;
+    font-weight: bold;
+}
+
+/* :::: INLINE COMMENTS :::: */
+
+div.inlinecomments {
+    position: absolute;
+    right: 20px;
+}
+
+div.inlinecomments a.bubble {
+    display: block;
+    float: right;
+    background-image: url(style/comment.png);
+    background-repeat: no-repeat;
+    width: 25px;
+    height: 25px;
+    text-align: center;
+    padding-top: 3px;
+    font-size: 0.9em;
+    line-height: 14px;
+    font-weight: bold;
+    color: black;
+}
+
+div.inlinecomments a.bubble span {
+    display: none;
+}
+
+div.inlinecomments a.emptybubble {
+    background-image: url(style/nocomment.png);
+}
+
+div.inlinecomments a.bubble:hover {
+    background-image: url(style/hovercomment.png);
+    text-decoration: none;
+    color: #3ca0a4;
+}
+
+div.inlinecomments div.comments {
+    float: right;
+    margin: 25px 5px 0 0;
+    max-width: 50em;
+    min-width: 30em;
+    border: 1px solid #2eabb0;
+    background-color: #f2fbfd;
+    z-index: 150;
+}
+
+div#comments {
+    border: 1px solid #2eabb0;
+    margin-top: 20px;
+}
+
+div#comments div.nocomments {
+    padding: 10px;
+    font-weight: bold;
+}
+
+div.inlinecomments div.comments h3,
+div#comments h3 {
+    margin: 0;
+    padding: 0;
+    background-color: #2eabb0;
+    color: white;
+    border: none;
+    padding: 3px;
+}
+
+div.inlinecomments div.comments div.actions {
+    padding: 4px;
+    margin: 0;
+    border-top: none;
+}
+
+div#comments div.comment {
+    margin: 10px;
+    border: 1px solid #2eabb0;
+}
+
+div.inlinecomments div.comment h4,
+div.commentwindow div.comment h4,
+div#comments div.comment h4 {
+    margin: 10px 0 0 0;
+    background-color: #2eabb0;
+    color: white;
+    border: none;
+    padding: 1px 4px 1px 4px;
+}
+
+div#comments div.comment h4 {
+    margin: 0;
+}
+
+div#comments div.comment h4 a {
+    color: #d5f4f4;
+}
+
+div.inlinecomments div.comment div.text,
+div.commentwindow div.comment div.text,
+div#comments div.comment div.text {
+    margin: -5px 0 -5px 0;
+    padding: 0 10px 0 10px;
+}
+
+div.inlinecomments div.comment div.meta,
+div.commentwindow div.comment div.meta,
+div#comments div.comment div.meta {
+    text-align: right;
+    padding: 2px 10px 2px 0;
+    font-size: 95%;
+    color: #538893;
+    border-top: 1px solid #cbe7e5;
+    background-color: #e0f6f4;
+}
+
+div.commentwindow {
+    position: absolute;
+    width: 500px;
+    border: 1px solid #cbe7e5;
+    background-color: #f2fbfd;
+    display: none;
+    z-index: 130;
+}
+
+div.commentwindow h3 {
+    margin: 0;
+    background-color: #2eabb0;
+    color: white;
+    border: none;
+    padding: 5px;
+    font-size: 1.5em;
+    cursor: pointer;
+}
+
+div.commentwindow div.actions {
+    margin: 10px -10px 0 -10px;
+    padding: 4px 10px 4px 10px;
+    color: #538893;
+}
+
+div.commentwindow div.actions input {
+    border: 1px solid #2eabb0;
+    background-color: white;
+    color: #135355;
+    cursor: pointer;
+}
+
+div.commentwindow div.form {
+    padding: 0 10px 0 10px;
+}
+
+div.commentwindow div.form input,
+div.commentwindow div.form textarea {
+    border: 1px solid #3c9ea2;
+    background-color: white;
+    color: black;
+}
+
+div.commentwindow div.error {
+    margin: 10px 5px 10px 5px;
+    background-color: #fbe5dc;
+    display: none;
+}
+
+div.commentwindow div.form textarea {
+    width: 99%;
+}
+
+div.commentwindow div.preview {
+    margin: 10px 0 10px 0;
+    background-color: #70d0d4;
+    padding: 0 1px 1px 25px;
+}
+
+div.commentwindow div.preview h4 {
+    margin: 0 0 -5px -20px;
+    padding: 4px 0 0 4px;
+    color: white;
+    font-size: 1.3em;
+}
+
+div.commentwindow div.preview div.comment {
+    background-color: #f2fbfd;
+}
+
+div.commentwindow div.preview div.comment h4 {
+    margin: 10px 0 0 0!important;
+    padding: 1px 4px 1px 4px!important;
+    font-size: 1.2em;
+}
+
+/* :::: SUGGEST CHANGES :::: */
+div#suggest-changes-box input, div#suggest-changes-box textarea {
+    border: 1px solid #ccc;
+    background-color: white;
+    color: black;
+}
+
+div#suggest-changes-box textarea {
+    width: 99%;
+    height: 400px;
+}
+
+
+/* :::: PREVIEW :::: */
+div.preview { 
+    background-image: url(style/preview.png);
+    padding: 0 20px 20px 20px;
+    margin-bottom: 30px;
+}
+
+
+/* :::: INDEX PAGE :::: */
+
+table.contentstable {
+    width: 90%;
+}
+
+table.contentstable p.biglink {
+    line-height: 150%;
+}
+
+a.biglink {
+    font-size: 1.3em;
+}
+
+span.linkdescr {
+    font-style: italic;
+    padding-top: 5px;
+    font-size: 90%;
+}
+
+/* :::: INDEX STYLES :::: */
+
+table.indextable td {
+    text-align: left;
+    vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+    height: 10px;
+}
+
+table.indextable tr.cap {
+    margin-top: 10px;
+    background-color: #f2f2f2;
+}
+
+img.toggler {
+    margin-right: 3px;
+    margin-top: 3px;
+    cursor: pointer;
+}
+
+form.pfform {
+    margin: 10px 0 20px 0;
+}
+
+/* :::: GLOBAL STYLES :::: */
+
+.docwarning {
+    background-color: #ffe4e4;
+    padding: 10px;
+    margin: 0 -20px 0 -20px;
+    border-bottom: 1px solid #f66;
+}
+
+p.subhead {
+    font-weight: bold;
+    margin-top: 20px;
+}
+
+a {
+    color: #355f7c;
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: 'Trebuchet MS', sans-serif;
+    background-color: #f2f2f2;
+    font-weight: normal;
+    color: #20435c;
+    border-bottom: 1px solid #ccc;
+    margin: 20px -20px 10px -20px;
+    padding: 3px 0 3px 10px;
+}
+
+div.body h1 { margin-top: 0; font-size: 200%; }
+div.body h2 { font-size: 160%; }
+div.body h3 { font-size: 140%; }
+div.body h4 { font-size: 120%; }
+div.body h5 { font-size: 110%; }
+div.body h6 { font-size: 100%; }
+
+a.headerlink {
+    color: #c60f0f;
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+a.headerlink:hover {
+    background-color: #c60f0f;
+    color: white;
+}
+
+div.body p, div.body dd, div.body li {
+    text-align: justify;
+    line-height: 130%;
+}
+
+div.body td {
+    text-align: left;
+}
+
+ul.fakelist {
+    list-style: none;
+    margin: 10px 0 10px 20px;
+    padding: 0;
+}
+
+/* "Footnotes" heading */
+p.rubric {
+    margin-top: 30px;
+    font-weight: bold;
+}
+
+/* "Topics" */
+
+div.topic {
+    background-color: #eee;
+    border: 1px solid #ccc;
+    padding: 0 7px 0 7px;
+    margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+    font-size: 1.1em;
+    font-weight: bold;
+    margin-top: 10px;
+}
+
+/* Admonitions */
+
+div.admonition {
+    margin-top: 10px;
+    margin-bottom: 10px;
+    padding: 7px;
+}
+
+div.admonition dt {
+    font-weight: bold;
+}
+
+div.admonition dl {
+    margin-bottom: 0;
+}
+
+div.admonition p {
+    display: inline;
+}
+
+div.seealso {
+    background-color: #ffc;
+    border: 1px solid #ff6;
+}
+
+div.warning {
+    background-color: #ffe4e4;
+    border: 1px solid #f66;
+}
+
+div.note {
+    background-color: #eee;
+    border: 1px solid #ccc;
+}
+
+p.admonition-title {
+    margin: 0px 10px 5px 0px;
+    font-weight: bold;
+    display: inline;
+}
+
+p.admonition-title:after {
+    content: ":";
+}
+
+div.body p.centered {
+    text-align: center;
+    margin-top: 25px;
+}
+
+table.docutils {
+    border: 0;
+}
+
+table.docutils td, table.docutils th {
+    padding: 1px 8px 1px 0;
+    border-top: 0;
+    border-left: 0;
+    border-right: 0;
+    border-bottom: 1px solid #aaa;
+}
+
+table.field-list td, table.field-list th {
+    border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+    border: 0 !important;
+}
+
+dl {
+    margin-bottom: 15px;
+    clear: both;
+}
+
+dd p {
+    margin-top: 0px;
+}
+
+dd ul, dd table {
+    margin-bottom: 10px;
+}
+
+dd {
+    margin-top: 3px;
+    margin-bottom: 10px;
+    margin-left: 30px;
+}
+
+.refcount {
+    color: #060;
+}
+
+dt:target,
+.highlight {
+    background-color: #fbe54e;
+}
+
+dl.glossary dt {
+    font-weight: bold;
+    font-size: 1.1em;
+}
+
+th {
+    text-align: left;
+    padding-right: 5px;
+}
+
+pre {
+    padding: 5px;
+    background-color: #efc;
+    color: #333;
+    border: 1px solid #ac9;
+    border-left: none;
+    border-right: none;
+}
+
+tt {
+    background-color: #ecf0f3;
+    padding: 0 1px 0 1px;
+    font-size: 0.95em;
+}
+
+tt.descname {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.2em;
+}
+
+tt.descclassname {
+    background-color: transparent;
+}
+
+tt.xref, a tt {
+    background-color: transparent;
+    font-weight: bold;
+}
+
+.footnote:target  { background-color: #ffa }
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+    background-color: transparent;
+}
+
+.optional {
+    font-size: 1.3em;
+}
+
+.versionmodified {
+    font-style: italic;
+}
+
+form.comment {
+    margin: 0;
+    padding: 10px 30px 10px 30px;
+    background-color: #eee;
+}
+
+form.comment h3 {
+    background-color: #326591;
+    color: white;
+    margin: -10px -30px 10px -30px;
+    padding: 5px;
+    font-size: 1.4em;
+}
+
+form.comment input,
+form.comment textarea {
+    border: 1px solid #ccc;
+    padding: 2px;
+    font-family: sans-serif;
+    font-size: 100%;
+}
+
+form.comment input[type="text"] {
+    width: 240px;
+}
+
+form.comment textarea {
+    width: 100%;
+    height: 200px;
+    margin-bottom: 10px;
+}
+
+.system-message {
+    background-color: #fda;
+    padding: 5px;
+    border: 3px solid red;
+}
+
+/* :::: PRINT :::: */
+ at media print {
+    div.document, 
+    div.documentwrapper, 
+    div.bodywrapper {
+        margin: 0;
+        width : 100%;
+    }
+
+    div.sidebar,
+    div.related,
+    div.footer,
+    div#comments div.new-comment-box,
+    #top-link {
+        display: none;
+    }
+}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/_static/grok.css
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/_static/grok.css	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/_static/grok.css	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,940 @@
+/*
+ * Grok Official Documentation CSS
+ *
+ * (clean me up! improve me! make me look nicer!)
+ *
+ */
+
+body {
+    font-family: sans-serif;
+    font-size: 100%;
+    background-color: #11303d;
+    background-color: #dddddd;
+    background: #cfcccc url("top_bg.jpg") repeat-x;
+    color: #000;
+    margin: 0;
+    padding: 0;
+}
+
+td {
+    vertical-align: top;
+}
+
+/* :::: LAYOUT :::: */
+
+div.document {
+    background-color: #dddddd;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 250px;
+}
+
+div.body {
+    background-color: white;
+    padding: 1.5em;
+    border-left: 1px solid #999;
+    
+}
+
+div.clearer {
+    clear: both;
+}
+
+div.footer {
+    color: #740;
+    width: 100%;
+    padding: 9px 0 9px 0;
+    text-align: center;
+    font-size: 75%;
+}
+
+div.footer a {
+    color: #740;
+    text-decoration: underline;
+}
+
+div.header {
+    background: #999999 url("top_bg.jpg") repeat-x;
+    padding: 0.5em 1em 0 1em; 
+}
+
+div.header a{
+    color: #520;
+    padding: 0.5em;
+    text-decoration: none;
+}
+
+div.globalnav {
+    color: #740;
+    border-bottom: 1px solid #aaa;
+    width: 100%;
+    font-size: small;
+}
+
+div.globalnav h3 {
+    display: none;
+}
+
+#globalnavwrapper {
+   padding: 2px;
+   margin: 0.5em 0 0 0;
+}
+
+div.globalnav ul {
+    margin: 0 0 0 0;
+    padding: 0;
+    list-style: none;
+}
+
+div.globalnav li {
+    display: inline;
+    padding: 2px 0.5em;
+    margin: 0 1px;
+    background-color: #eee;
+    border: 1px solid #999;
+}
+
+div.globalnav a {
+    color: #436976;
+    text-decoration: none;
+}
+
+div.globalnav li:hover {
+    background-color: white;
+}
+
+/* ::: Table of Contents :::: */
+
+.document > div.sidebarwrapper {
+    padding: 10px 5px 0 10px;
+}
+
+.sphinxsidebar {
+    float: left;
+    width: 250px;
+    margin-left: -100%;
+    font-size: small;
+    color: #333333;
+    padding: 8px;
+}
+
+.sphinxsidebar a {
+    color: #436976;
+}
+
+.sphinxsidebar h3 {
+    font-family: 'Trebuchet MS', sans-serif;
+    font-size: 1.4em;
+    font-weight: normal;
+    margin: 0;
+    padding: 0;
+}
+
+.sphinxsidebar h4 {
+    font-family: 'Trebuchet MS', sans-serif;
+    font-size: 1.3em;
+    font-weight: normal;
+    margin: 5px 0 0 0;
+    padding: 0;
+}
+
+.sphinxsidebar p.topless {
+    margin: 5px 10px 10px 10px;
+}
+
+.sphinxsidebar ul {
+    margin: 10px;
+    padding: 0;
+    list-style: none;
+    color: #c90;
+}
+
+.sphinxsidebar ul ul,
+.sphinxsidebar ul.want-points {
+    margin-left: 20px;
+    list-style: square;
+    color: #436976;
+}
+
+.sphinxsidebar ul ul {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+.sphinxsidebar ul li {
+    margin: 0.25em 0 0.5em 0;
+}
+
+.sphinxsidebar form {
+    margin-top: 10px;
+}
+
+.sphinxsidebar input {
+    border: 1px solid #555555;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+/* Grok Tutorial style sidebar */
+.section div.sidebar {
+    margin: 1em 2em;
+    padding: 0.5em 2em 1em 100px;
+    background-color: #fafaf8;
+    border: 1px solid #aaa;
+    border-top-width: 6px;
+    background-image: url(grok_club.gif);
+    background-repeat: no-repeat;
+}
+
+.section .sidebar-title {
+    font-weight: bold;
+    font-size: 110%;
+}
+
+/* :::: MODULE CLOUD :::: */
+div.modulecloud {
+    margin: -5px 10px 5px 10px;
+    padding: 10px;
+    line-height: 160%;
+    border: 1px solid #cbe7e5;
+    background-color: #f2fbfd;
+}
+
+div.modulecloud a {
+    padding: 0 5px 0 5px;
+}
+
+/* :::: SEARCH :::: */
+ul.search {
+    margin: 10px 0 0 20px;
+    padding: 0;
+}
+
+ul.search li {
+    padding: 5px 0 5px 20px;
+    background-image: url(file.png);
+    background-repeat: no-repeat;
+    background-position: 0 7px;
+}
+
+ul.search li a {
+    font-weight: bold;
+}
+
+ul.search li div.context {
+    color: #888;
+    margin: 2px 0 0 30px;
+    text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+    font-weight: bold;
+}
+
+/* :::: COMMON FORM STYLES :::: */
+
+div.actions {
+    padding: 5px 10px 5px 10px;
+    border-top: 1px solid #cbe7e5;
+    border-bottom: 1px solid #cbe7e5;
+    background-color: #e0f6f4;
+}
+
+form dl {
+    color: #333;
+}
+
+form dt {
+    clear: both;
+    float: left;
+    min-width: 110px;
+    margin-right: 10px;
+    padding-top: 2px;
+}
+
+input#homepage {
+    display: none;
+}
+
+div.error {
+    margin: 5px 20px 0 0;
+    padding: 5px;
+    border: 1px solid #d00;
+    font-weight: bold;
+}
+
+/* :::: INLINE COMMENTS :::: */
+
+div.inlinecomments {
+    position: absolute;
+    right: 20px;
+}
+
+div.inlinecomments a.bubble {
+    display: block;
+    float: right;
+    background-image: url(style/comment.png);
+    background-repeat: no-repeat;
+    width: 25px;
+    height: 25px;
+    text-align: center;
+    padding-top: 3px;
+    font-size: 0.9em;
+    line-height: 14px;
+    font-weight: bold;
+    color: black;
+}
+
+div.inlinecomments a.bubble span {
+    display: none;
+}
+
+div.inlinecomments a.emptybubble {
+    background-image: url(style/nocomment.png);
+}
+
+div.inlinecomments a.bubble:hover {
+    background-image: url(style/hovercomment.png);
+    text-decoration: none;
+    color: #3ca0a4;
+}
+
+div.inlinecomments div.comments {
+    float: right;
+    margin: 25px 5px 0 0;
+    max-width: 50em;
+    min-width: 30em;
+    border: 1px solid #2eabb0;
+    background-color: #f2fbfd;
+    z-index: 150;
+}
+
+div#comments {
+    border: 1px solid #2eabb0;
+    margin-top: 20px;
+}
+
+div#comments div.nocomments {
+    padding: 10px;
+    font-weight: bold;
+}
+
+div.inlinecomments div.comments h3,
+div#comments h3 {
+    margin: 0;
+    padding: 0;
+    background-color: #2eabb0;
+    color: white;
+    border: none;
+    padding: 3px;
+}
+
+div.inlinecomments div.comments div.actions {
+    padding: 4px;
+    margin: 0;
+    border-top: none;
+}
+
+div#comments div.comment {
+    margin: 10px;
+    border: 1px solid #2eabb0;
+}
+
+div.inlinecomments div.comment h4,
+div.commentwindow div.comment h4,
+div#comments div.comment h4 {
+    margin: 10px 0 0 0;
+    background-color: #2eabb0;
+    color: white;
+    border: none;
+    padding: 1px 4px 1px 4px;
+}
+
+div#comments div.comment h4 {
+    margin: 0;
+}
+
+div#comments div.comment h4 a {
+    color: #d5f4f4;
+}
+
+div.inlinecomments div.comment div.text,
+div.commentwindow div.comment div.text,
+div#comments div.comment div.text {
+    margin: -5px 0 -5px 0;
+    padding: 0 10px 0 10px;
+}
+
+div.inlinecomments div.comment div.meta,
+div.commentwindow div.comment div.meta,
+div#comments div.comment div.meta {
+    text-align: right;
+    padding: 2px 10px 2px 0;
+    font-size: 95%;
+    color: #538893;
+    border-top: 1px solid #cbe7e5;
+    background-color: #e0f6f4;
+}
+
+div.commentwindow {
+    position: absolute;
+    width: 500px;
+    border: 1px solid #cbe7e5;
+    background-color: #f2fbfd;
+    display: none;
+    z-index: 130;
+}
+
+div.commentwindow h3 {
+    margin: 0;
+    background-color: #2eabb0;
+    color: white;
+    border: none;
+    padding: 5px;
+    font-size: 1.5em;
+    cursor: pointer;
+}
+
+div.commentwindow div.actions {
+    margin: 10px -10px 0 -10px;
+    padding: 4px 10px 4px 10px;
+    color: #538893;
+}
+
+div.commentwindow div.actions input {
+    border: 1px solid #2eabb0;
+    background-color: white;
+    color: #135355;
+    cursor: pointer;
+}
+
+div.commentwindow div.form {
+    padding: 0 10px 0 10px;
+}
+
+div.commentwindow div.form input,
+div.commentwindow div.form textarea {
+    border: 1px solid #3c9ea2;
+    background-color: white;
+    color: black;
+}
+
+div.commentwindow div.error {
+    margin: 10px 5px 10px 5px;
+    background-color: #fbe5dc;
+    display: none;
+}
+
+div.commentwindow div.form textarea {
+    width: 99%;
+}
+
+div.commentwindow div.preview {
+    margin: 10px 0 10px 0;
+    background-color: #70d0d4;
+    padding: 0 1px 1px 25px;
+}
+
+div.commentwindow div.preview h4 {
+    margin: 0 0 -5px -20px;
+    padding: 4px 0 0 4px;
+    color: white;
+    font-size: 1.3em;
+}
+
+div.commentwindow div.preview div.comment {
+    background-color: #f2fbfd;
+}
+
+div.commentwindow div.preview div.comment h4 {
+    margin: 10px 0 0 0!important;
+    padding: 1px 4px 1px 4px!important;
+    font-size: 1.2em;
+}
+
+/* :::: SUGGEST CHANGES :::: */
+div#suggest-changes-box input, div#suggest-changes-box textarea {
+    border: 1px solid #dddddd;
+    background-color: white;
+    color: black;
+}
+
+div#suggest-changes-box textarea {
+    width: 99%;
+    height: 400px;
+}
+
+
+/* :::: PREVIEW :::: */
+div.preview { 
+    background-image: url(style/preview.png);
+    padding: 0 20px 20px 20px;
+    margin-bottom: 30px;
+}
+
+
+/* :::: INDEX PAGE :::: */
+
+table.contentstable {
+    width: 90%;
+    margin-top: -1em;
+    margin-left: 2em;
+}
+
+table.contentstable p.biglink {
+    line-height: 150%;
+}
+
+a.biglink {
+    font-size: 1.3em;
+}
+
+span.linkdescr {
+    color: #555;
+    padding-top: 0.25em;
+    font-size: 90%;
+}
+
+/* :::: INDEX STYLES :::: */
+
+table.indextable td {
+    text-align: left;
+    vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+    height: 10px;
+}
+
+table.indextable tr.cap {
+    margin-top: 10px;
+    background-color: #f2f2f2;
+}
+
+img.toggler {
+    margin-right: 3px;
+    margin-top: 3px;
+    cursor: pointer;
+}
+
+form.pfform {
+    margin: 10px 0 20px 0;
+}
+
+/* :::: GLOBAL STYLES :::: */
+
+.docwarning {
+    background-color: #ffe4e4;
+    padding: 10px;
+    margin: 0 -20px 0 -20px;
+    border-bottom: 1px solid #f66;
+}
+
+p.subhead {
+    font-weight: bold;
+    margin-top: 20px;
+}
+
+a {
+    color: #355f7c;
+    color: #a70;
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: 'Trebuchet MS', sans-serif;
+    font-weight: normal;
+    color: #c90;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 0.5em 0;
+    padding: 3px 1em 3px 0.25em;
+}
+
+div.body h1 { margin-top: 0; background-color: #f2f2f2; font-size: 200%; }
+div.body h2 { font-size: 160%; background-color: #f2f2f2; }
+div.body h3 { font-size: 140%; border-bottom-width: 0; padding-left: 0;  }
+div.body h4 { font-size: 120%; border-bottom-width: 0; padding-left: 0;  }
+div.body h5 { font-size: 110%; border-bottom-width: 0; padding-left: 0;  }
+div.body h6 { font-size: 100%; border-bottom-width: 0; padding-left: 0;  }
+
+a.headerlink {
+    color: #dddddd;
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+a.headerlink:hover {
+    color: #555555;
+}
+
+div.body p, div.body dd, div.body li {
+    line-height: 150%;
+}
+
+div.body td {
+    text-align: left;
+}
+
+ul.fakelist {
+    list-style: none;
+    margin: 10px 0 10px 20px;
+    padding: 0;
+}
+
+/* "Footnotes" heading */
+p.rubric {
+    margin-top: 30px;
+    font-weight: bold;
+}
+
+/* "Topics" */
+
+div.topic {
+    background-color: #eeeeee;
+    border: 1px solid #dddddd;
+    padding: 0 7px 0 7px;
+    margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+    font-size: 1.1em;
+    font-weight: bold;
+    margin-top: 10px;
+}
+
+.topic ul {
+    margin: 0 0 0.5em 1.5em;
+    padding: 0;
+}
+
+.section blockquote {
+    margin: 0em;
+    padding: 0.5em;
+}
+
+.simple li {
+    list-style-type: circle;
+}
+
+/* Admonitions */
+
+div.admonition {
+    margin: 0.5em 0;
+    padding: 0.5em;
+}
+
+div.admonition dt {
+    font-weight: bold;
+}
+
+div.admonition dl {
+    margin-bottom: 0;
+}
+
+div.admonition p {
+    display: inline;
+}
+
+div.seealso {
+    padding: 0;
+    background-color: #ffc;
+    border: 1px solid #ff6;
+}
+
+div.seealso .first {
+    background-color: #ffa;
+    padding: 0.25em 0.5em;
+    display: block;
+    float: left;
+    margin: 0 0.5em 0 0;
+}
+
+div.seealso .last {
+    padding: 0.25em 0;
+    display: block;
+    margin: 0;
+}
+
+div.warning {
+    background-color: #ffe4e4;
+    border: 1px solid #f66;
+}
+
+div.note {
+    background-color: #eeeeee;
+    border: 1px solid #dddddd;
+}
+
+
+/* only applies to the class name */
+dl.class {
+    color: #555555;
+    background: #fafaf8;
+    padding: 0 1em 1em 1em;
+    border: 1px solid #eed;
+}
+
+dl.class dt {
+    margin: 0;
+    padding: 0;
+}
+
+dl.class > dt {
+    padding: 0.5em;
+    margin: 0 -1em;
+    background-color: #eed;
+}
+
+dl.class dd {
+    color: black;
+    font-size: 100%;
+    padding: 0;
+    margin: 0.5em 1em 0.5em 1em;
+}
+
+dl.class > dd {
+    margin: 0.5em 0 0 0;
+    padding: 0;
+}
+
+/* only applies to functions */
+dl.function {
+    color: #555555;
+    background: #fafaf8;
+    padding: 0 1em 1em 1em;
+    border: 1px solid #eed;
+}
+
+dl.function dt {
+    margin: 0;
+    padding: 0;
+}
+
+dl.function > dt {
+    padding: 0.5em;
+    margin: 0 -1em;
+    background-color: #eed;
+}
+
+dl.function dd {
+    color: black;
+    font-size: 100%;
+    padding: 0;
+    margin: 0.5em 1em 0.5em 1em;
+}
+
+dl.function > dd {
+    margin: 0.5em 0 0 0;
+    padding: 0;
+}
+
+p.admonition-title {
+    margin: 0 0.5em 0.5em 0;
+    display: inline;
+}
+
+p.admonition-title:after {
+    content: ":";
+}
+
+div.body p.centered {
+    text-align: center;
+    margin-top: 25px;
+}
+
+table.docutils {
+    border: 0;
+}
+
+table.docutils td, table.docutils th {
+    padding: 1px 8px 1px 0;
+    border: 0;
+}
+
+table.field-list td, table.field-list th {
+    border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+    border: 0 !important;
+}
+
+dl {
+    margin-bottom: 15px;
+    clear: both;
+}
+
+dd p {
+    margin-top: 0px;
+}
+
+dd ul, dd table {
+    margin-bottom: 10px;
+}
+
+dd {
+    margin-top: 3px;
+    margin-bottom: 10px;
+    margin-left: 30px;
+}
+
+.refcount {
+    color: #060;
+}
+
+dt:target,
+.highlight {
+    background-color: #fbe54e;
+}
+
+dl.glossary dt {
+    font-weight: bold;
+    font-size: 1.1em;
+}
+
+th {
+    text-align: left;
+    padding-right: 5px;
+}
+
+pre {
+    padding: 1em;
+    background-color: #fafafa;
+    color: #333333;
+    border: 2px dotted #eee;
+    border-left: none;
+    border-right: none;
+    font-size: medium;
+    line-height: 150%;
+}
+
+tt {
+    background-color: #ecf0f3;
+    padding: 0;
+}
+
+tt.descname {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.2em;
+}
+
+tt.descclassname {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.2em;
+    /* a little hand kerning for grok.Whatever typography */
+    margin-right: -1px;
+}
+
+tt.xref, a tt {
+    background-color: transparent;
+    font-weight: bold;
+}
+
+.footnote:target  { background-color: #ffa }
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+    background-color: transparent;
+}
+
+.optional {
+    font-size: 1.3em;
+}
+
+.versionmodified {
+    font-style: italic;
+}
+
+form.comment {
+    margin: 0;
+    padding: 10px 30px 10px 30px;
+    background-color: #eee;
+}
+
+form.comment h3 {
+    background-color: #326591;
+    color: white;
+    margin: -10px -30px 10px -30px;
+    padding: 5px;
+    font-size: 1.4em;
+}
+
+form.comment input,
+form.comment textarea {
+    border: 1px solid #dddddd;
+    padding: 2px;
+    font-family: sans-serif;
+    font-size: 100%;
+}
+
+form.comment input[type="text"] {
+    width: 240px;
+}
+
+form.comment textarea {
+    width: 100%;
+    height: 200px;
+    margin-bottom: 10px;
+}
+
+.system-message {
+    background-color: #fda;
+    padding: 5px;
+    border: 3px solid red;
+}
+
+img.logo {
+    border-width: 0;
+    margin-bottom: 1em;
+}
+
+/* :::: PRINT :::: */
+ at media print {
+    div.document, 
+    div.documentwrapper, 
+    div.bodywrapper {
+        margin: 0;
+        width : 100%;
+    }
+
+    div.sidebar,
+    div.globalnav,
+    div.footer,
+    div#comments div.new-comment-box,
+    #top-link {
+        display: none;
+    }
+}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/_static/grok_club.gif
===================================================================
(Binary files differ)


Property changes on: groktoolkit/branches/jw-documentation-rearangement/doc/_static/grok_club.gif
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: groktoolkit/branches/jw-documentation-rearangement/doc/_static/logo.gif
===================================================================
(Binary files differ)


Property changes on: groktoolkit/branches/jw-documentation-rearangement/doc/_static/logo.gif
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: groktoolkit/branches/jw-documentation-rearangement/doc/_static/logo.png
===================================================================
(Binary files differ)


Property changes on: groktoolkit/branches/jw-documentation-rearangement/doc/_static/logo.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: groktoolkit/branches/jw-documentation-rearangement/doc/_static/top_bg.jpg
===================================================================
(Binary files differ)


Property changes on: groktoolkit/branches/jw-documentation-rearangement/doc/_static/top_bg.jpg
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: groktoolkit/branches/jw-documentation-rearangement/doc/bugs.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/bugs.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/bugs.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,64 @@
+.. _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.

Added: groktoolkit/branches/jw-documentation-rearangement/doc/changes.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/changes.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/changes.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+.. include:: ../CHANGES.txt

Added: groktoolkit/branches/jw-documentation-rearangement/doc/conf.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/conf.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/conf.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,144 @@
+# -*- coding: utf-8 -*-
+#
+# Grok Reference documentation build configuration file, created by
+# sphinx-quickstart.py on Wed Feb 20 02:11:17 2008.
+#
+# 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).
+#
+# All configuration values have a default value; values that are commented out
+# show the default value as assigned to them.
+
+import sys
+import pkg_resources
+
+from os import path, curdir
+
+# If your extensions are in another directory, add it here.
+#sys.path.append('some/directory')
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc',
+              'sphinx.ext.doctest',
+              'sphinx.ext.intersphinx',
+              # 'sphinx.ext.viewcode', # This is currently broken?
+              ]
+
+# Order autodoc generated docs in source code order.
+autodoc_member_order = 'bysource'
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['.']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General substitutions.
+project = 'Official Grok'
+copyright = '2006-2010, The Zope Foundation'
+
+# The default replacements 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
+# The full version, including alpha/beta/rc tags.
+release = version
+if release.endswith('dev'):
+    release = '%s (unreleased)' % release
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+unused_docs = ['build']
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+
+# Options for HTML output
+# -----------------------
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+html_use_smartypants = True
+
+# Custom sidebar templates, maps page names to filenames relative to this file.
+#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'}
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+#html_copy_source = True
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Grokdoc'
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# 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'
+
+# 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')]
+
+
+# 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 = []
+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'),
+    ]
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = '
+latex_preamble = '''
+\usepackage{epsfig}
+
+'''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []

Added: groktoolkit/branches/jw-documentation-rearangement/doc/contents.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/contents.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/contents.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,20 @@
+===========================
+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

Added: groktoolkit/branches/jw-documentation-rearangement/doc/copyright.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/copyright.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/copyright.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,11 @@
+*********
+Copyright
+*********
+
+Grok and this documentation is:
+
+Copyright © 2006-2009 Zope Community and Contributors. All rights reserved.
+
+----------
+
+See: :ref:`license` for complete license and permissions information.

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/adapters.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/adapters.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/adapters.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+import grok
+from zope.publisher.interfaces.browser import IBrowserRequest, IBrowserView
+from zope.contentprovider.interfaces import IContentProvider
+from calc import Calculator
+
+class SingleAdapter(grok.Adapter):
+    grok.context(Calculator)
+    grok.adapts(Calculator)  # generally allowed, but not in this case, because there's already grok.context
+    grok.implements(ISomething)  # if this is not specified, app breaks
+    grok.provides(ISomething)  # if adapter implements more than one interface
+    grok.name('')  # this is actually the default
+
+    def something(self):
+        """self.context is automatically provided"""
+        return self.context.foo
+
+class CalculatorContentProvider(grok.MultiAdapter)
+    grok.adapts(Calculator, IBrowserRequest, IBrowserView)
+    grok.implements(IContentProvider)
+
+    def __init__(self, context, request, view):
+        self.context = context
+        self.request = request
+        self.view = view
+
+    # ...

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/annotations.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/annotations.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/annotations.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,28 @@
+import grok
+from zope import interface
+from BTrees.OOBTree import OOTreeSet
+
+class Article(grok.Model):
+    pass
+
+class IComments(interface.Interface):
+
+    def addComment(text):
+        pass
+
+    def getComments():
+        pass
+
+class Comments(grok.Annotation):
+    grok.context(Article)  # this is actually the default
+    grok.implements(IComments)
+    grok.name('annotations.Comments')  # this is actually the default
+
+    def __init__(self): 
+        self.comments = OOTreeSet()
+
+    def addComment(self, text):
+        self.comments.insert(text)
+
+    def getComments(self):
+        return list(self.comments)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/container.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/container.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/container.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+import grok
+
+class Contact(grok.Model):
+    pass
+
+class AddressBook(grok.App, grok.Container):
+    pass
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/grok_beginner.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/grok_beginner.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/grok_beginner.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,412 @@
+==========================
+Grok: Making Zope 3 Easier
+==========================
+
+**NOTE:** This document was written *before* grok was implemented.  It
+has been part of the design phase during which it served well to
+discuss and preserve grok's goals.  The actual implementation of grok
+differs from the concrete code examples given here.  This is NOT a
+grok tutorial nor should it be seen as any part of grok's current
+documentation!
+
+
+Publishing web pages
+====================
+
+You want to publish a web site that is in a directory. This includes
+any pictures and javascript and CSS you may have in that directory::
+
+  import grok
+
+  class Website(grok.View):
+      grok.files('mydirectory')
+
+XXX use htdocs here, familiar to some people
+
+Once you do this, you can browse into these from the Zope 3 root site.
+Files and assets in any subdirectories will also be published. (XXX
+how?)
+
+Dynamic pages
+=============
+
+Often you want your web pages not to be static but *dynamic*. A web
+page is dynamic when, before the web page is served to your user for
+display in a browser, you want to generate part or all of the
+information of the web page automatically. 
+
+Zope reads your HTML files as Zope Page Templates (ZPT), meaning you
+can use TAL (Template Attribute Language) to script your
+templates. TAL is added to HTML as attributes, meaning your HTML still
+looks very familiar. For an example of very simple TAL, consider this
+HTML snippet::
+
+  <p tal:content="python:1 + 1">Result here</p>
+
+This will generate the following::
+
+  <p>2</p>
+
+This means that the result of the Python expression `1 + 1` is
+dynamically inserted as the content of this `p` tag, replacing what
+was already there.
+
+You can add TAL to any of your HTML pages to make them dynamic.
+
+For more about TAL see XXX (TAL tutorial in here?)
+
+Using Python
+============
+
+Just TAL by itself, even when you use `python:` to embed snippets of
+Python, is limited. The idea of good application design is to use TAL
+just for fairly simple templating purposes, and to do anything a bit
+more complicated in Python code. Using TAL with Python code is easy:
+you just add methods to your view class and use them from your
+template. 
+
+Here we add a method that formats the current date and time::
+
+  from zope import grok
+  from datetime import datetime
+
+  class Website(grok.View):
+      grok.files('mydirectory')
+      
+      def currentDatetime(self):
+          return datetime.now().strftime('%Y-%m-%d %H:%M')
+
+We can then use this with TAL to display the current date and time::
+
+  <p tal:content="view/currentDatetime">Datetime goes here</p>
+
+All the methods you add to the class of your site are automatically
+available on the special `view` name from within your
+templates. `view` is one of the few names that are available in views
+by default.
+
+Note that we have used TAL's built-in `path` language here; this can
+be used for simple method calls instead of spelling it out explicitly.
+For the same effect, you can also use it using Python directly::
+
+  <p tal:content="python:view.currentDatetime()">Datetime goes here</p>
+
+This can be useful when you want to pass parameters to your methods.
+
+Generating HTML from Python
+===========================
+
+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::
+
+  from zope import grok
+
+  class Website(grok.View):
+      grok.files('mydirectory')
+    
+      def someHTML(self):
+           return '<strong>%s</strong>' % (1 + 1)
+
+And then with TAL in one of your templates::
+
+  <p tal:content="structure view/someHTML">Result goes here</p>
+
+Generating the whole page from Python
+=====================================
+
+If for some reason you do not want to use a HTML template but just
+want to generate HTML directly from Python, this is also possible::
+
+  class Foo(grok.View):
+      @grok.page('serverload.html')
+      def serverLoad(self):
+          return '<html>..</html>'
+
+XXX a word on unicode
+
+Simple forms
+============
+
+Typical web applications have forms. Let's make a web form and use
+it. First we'll add the following form to one of our templates::
+
+  <form action="hello.html" method="post">
+    <p>
+    Please type your name: <input type="text" name="name" value="" /><br/>
+    <input type="submit" value="Submit" />
+    </p>
+  </form>
+
+As you can see, this form submits to the template named
+`hello.html`. Create such a template in your site and put the
+following TAL in there::
+
+  <html><body>
+  <p>Hello, <strong tal:content="request/form/name">name</strong></p>
+  </body></html>
+
+Now when you go to the form and submit it with the name `John`, you
+should see a web page that says:
+
+  Hello **John**
+
+Simple forms with Python
+========================
+
+Let's make a simple calculator to demonstrate how we combine this with
+Python::
+
+  <form action="sum.html" method="post">
+    <p>
+    First value: <input type="text" name="first" value="" /><br />
+    Second value: <input type="text" name="second" value="" /><br />
+    <input type="submit" value="Get the sum" />
+    </p>
+  </form>
+
+And create the following template `sum.html`::
+
+  <html><body>
+  <p>The sum is: <strong tal:content="data/sum">the sum goes here</strong></p>
+  </body></html>
+
+We've referred to a method `sum` here that does not exist yet, so let's
+implement it. It takes the raw values in the request and adds them to
+together, returning the sum::
+
+  from zope import grok
+
+  from ... import TemplateFile
+
+  class Website(grok.View):
+      grok.files('mydirectory')
+
+      @grok.page('sum.html')
+      def sum(self):
+          # before
+          self.sendEmail()
+          # call template (pull calculateSum2)
+          result = self.renderTemplate('sum.html', sum=self.calculateSum())
+          # post processing
+          result = result.replace('foo', 'bar')
+          return result
+
+
+      def sum(self):
+          self.before()
+          result = self.render('sum.html', **self.push())
+          result = self.after(result)
+          return result
+
+      def before(self):
+          pass
+
+class Website(grok.View):
+      grok.files('mydirectory')
+  
+      class sum(object):
+          """corresponds to sum.html"""
+ 
+          @grok.before()
+          def sendEmail(self):
+            ...
+
+          @grok.after()
+          def barify(self, result):
+              return result.replace('foo', 'bar')
+
+          def calculateSum(self):
+              return ...
+
+          def sum2(self):
+              return ...
+
+      class fancysum(sum):
+          """corresponds to fancysum.html"""
+
+           def calculateSum(self):
+                ...
+
+     
+      @grok.data('sum.html', 'sum')      
+      def sum(self):
+          # get hold of the form, from the request object that
+          # we can get from self
+          form = self.request.form
+          # now get first and second from the form; if no value found
+          # assume it's 0
+          first = form.get('first', 0)
+          second = form.get('second', 0)
+          # convert the input which was text to the numbers
+          # note that we don't handle any errors yet in case someone fills in
+          # something that's not a number
+          first = int(first)
+          second = int(second)
+          # now add the numbers and return this result
+          return first + second
+
+      @grok.page('sum.html')
+      def sum(self):
+          return "<html>...</html>"
+
+
+Form side effects
+=================
+
+Often you don't just want to see a result page when a user submits a
+form, but you want the let the system do some work just before we show
+the result. An example of this is to send an email. Another common
+example is to store the data that's in the form in a database
+somewhere. 
+
+This can be easily accomplished using the `@grok.before` decorator,
+which allows us to execute some Python code just before the template
+is rendered::
+
+  class Website(grok.View):
+      grok.templates('mydirectory')
+    
+      @grok.before('email_sent.html')
+      def email(self):
+          ... send the email XXX ... 
+
+
+Storing data
+============
+
+Instead of emailing the data, what if we wanted to record what the
+user entered instead? Zope offers a number of options for storing
+data, such as making a connection to relational databases (XXX which
+we'll handle later?), but Zope also ships with a powerful database of
+its own: the Zope Object Database (ZODB).
+
+The ZODB is a database of Python objects. You can store any Python object
+in it, and there are just a few things you need to be aware of initially:
+
+* You should subclass your own data classes from persistent.Persistent
+  so it's easy to store them in the ZODB.
+
+* To make sure the ZODB knows you changed a mutable attribute in the
+  instance, set the special `_p_changed` attribute on that instance to
+  `True`. This is only necessary if that attribute is not `Persistent`
+  itself. It's not necessary when you assign to an attribute directly
+  using `=`.
+
+This may sound complicated but it's not. Don't worry for now - most
+things work as normal in Python, and the rules just described are not
+difficult.
+
+So how do we get a space in the database to store our data in?
+`zope.grok` supports a special area where you can store your data.
+
+To get to the database in Python code, call `grok.database()`. This
+gives us access to a dictionary-like object, in which we can store our
+own sub objects::
+
+  from zope import grok
+  from persistent import Persistent
+
+  class NamesStorage(Persistent):
+     def __init__(self):
+        self.names = []
+
+    def addName(self, name):
+        self.names.append(name)
+        self._p_changed = True
+
+  class Website(grok.View):
+     grok.templates('mydirectory')
+   
+     def getNamesStorage(self):
+         """Get the names storage, or create it if it's not there yet.
+         """
+         db = grok.database()
+         storage = db.get('myapp.names_storage')
+         if storage is None:
+             db['myapp.names_storage'] = NamesStorage()
+         return storage
+
+     def storeName(self):
+         """
+         Retrieve the name from request and store it in
+         the names section.
+         """
+         storage = self.getNamesStorage()
+         storage.addName(self.request['name'])
+         
+XXX should following be separate section?
+
+Note that storing names in a list is not very efficient if the list of
+names grows to a larger size, as the object database will need to load
+the whole list of names into memory each time it is changed. We can
+avoid this using BTrees. XXX BTree explanation
+
+XXX showing the names in a web page
+
+Self-posting forms 
+==================
+
+It's a good design for many forms to be *self-posting*, that is, the
+result of a form submission shows the original form again. This way,
+mistakes by the user can be easily shown in the context of the form,
+and the user can correct them. When the form submission does succeed,
+the user is commonly redirected to another page.
+
+Let's first make a form that posts to itself, we'll call it just
+`form.html`::
+
+  <html><body>
+    <form action="." method="post">
+      <input type="text" name="number" value="" />
+    </form>
+  </body></html>
+
+We expect the user to enter an integer number, and we also want it the
+number to be required. Only if those conditions are true 
+....
+
+XXX can't use . perhaps, need to do absolute trick and explain it: request/URL
+
+n. .. self posting form ..
+
+Powerful forms using formlib
+============================
+
+class Foo(grok.View):
+
+    class Form(grok.Form):
+       grok.name('entry.html')
+       # would really be step 7 to control the template
+       # that renders the form. (this template needs to be
+       # moved)
+       template = grok.Template('entry.html')
+       
+       form_fields = grok.Fields(
+          name=schema.TextLine(title='Name'),
+          )
+
+       @grok.action('Submit')
+       def handle_submit(self, action, data):
+           .. send email ..
+           self.message = "The mail has successfully been sent."
+
+
+
+class MeetingView(grok.view):
+
+    grok.context(IMeeting, id=getfromrequestpath)
+
+n. You want to associate your application to a specific site
+
+n. You want to create a site content object
+
+n. You want to create a content object and associate views to that.
+
+n. You want to index content objects to search them.
+
+
+Some basic explanation of what's going on with unicode in Zope 3.

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/grok_dev.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/grok_dev.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/grok_dev.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,394 @@
+==========================
+Grok: Making Zope 3 Easier
+==========================
+
+**NOTE:** This document was written *before* grok was implemented.  It
+has been part of the design phase during which it served well to
+discuss and preserve grok's goals.  The actual implementation of grok
+differs from the concrete code examples given here.  This is NOT a
+grok tutorial nor should it be seen as any part of grok's current
+documentation!
+
+Introduction
+============
+
+The Grok project tries to it easier to develop Zope 3
+applications. Zope 3 is typically configured using ZCML, the Zope
+Configuration Markup Language. ZCML is non-Python and very explicit.
+
+ZCML was in part inspired by the difficulties surrounding
+configuration in Zope 2. Zope 2 is heavy on implicit configuration
+("no docstring means no public access", "a permission used is a
+permission defined"). In addition, lots of the configuration happens
+in Python code, such as in the `__init__.py` of a product. These
+techniques can lead to problems: hard to understand configuration code
+interweaved with non-configuration code. Such code tends to be
+difficult to maintain, extend, and evolve.
+
+ZCML aims to separate configuration strongly from software to avoid
+these problems. The ZCML model in combination with the notion of
+explicit interfaces offers a strong model for evolving software over a
+longer period of time.
+
+ZCML has drawbacks however. Zope 3's setup for modularity, components
+and evolution results in more entities for a programmer to worry
+about: explicit interfaces, a multiplication of files and modules, a
+large list of places to import from, a series of ZCML directives to
+remember. Even though individual entities may be easier to understand,
+the combination of such can make the whole more difficult to
+understand, and there is just a lot to learn overall.
+
+This is especially off-putting to developers who are trying to start
+learning Zope 3. Even experienced programmers can be frustrated by so
+much need to state obvious things explicitly - the multiplication of
+entities in Zope 3 hurts agility of development. Finally, ZCML can be
+intimidating to a Python programmer merely by being non-Python, and
+XML in particular. While the latter is at least in part a superficial
+concern, it is one that stops people from trying Zope 3.
+
+Grok aims to reduce the visibility of ZCML to the Zope 3
+programmer. Grok also aims to reduce the entities a programmer needs
+to worry about: ideally a Zope 3 application should be able to fit
+completely inside a single module. Grok does not aim to do away with
+ZCML altogether: explicit configuration is valuable. Grok merely aims
+to keep the advanced concepts out of the programmer's face when not
+needed.
+
+How does Grok aim accomplish these goals? We will try to follow the
+guidelines that work for Ruby on Rails:
+
+* DRY: Don't Repeat Yourself
+
+* Convention over configuration
+
+Grok is specified as autogenerated ZCML. This is for convenience of
+specification: Grok does not need to be implemented this way but could
+be calling underlying component architecture APIs directly where
+needed. In fact, one of the aims of Grok is to produce more readable
+errors that guide programmers into the right direction to solve their
+problem.
+
+Grok does not aim to make the programmer do correct security - an
+application written with Grok without the programmer taking any
+particular actions will be entirely public by default. Convenience of
+development trumps security here. The idea of Grok is that the
+programmer should have the easiest time possible to get an application
+running first, and then can gradually tighten the application in
+various ways, including security, later on.
+
+Views
+-----
+
+To declare a browser view, a new class-level declaration `views` is
+added, with as argument the class or interface the view is being
+declared for::
+
+  from zope import grok
+
+  class FooView(grok.View):
+     grok.views(Foo)
+
+As you can see, Grok views are inherited from `grok.View`.
+
+This is equivalent to the following ZCML::
+
+  <browser:page
+    name="FooView"
+    for="Foo"
+    class="FooView" 
+    permission="zope.Public"
+    />
+
+Note that the name is deduced entirely from the name of the view
+class. Where this is not desired, the view name can be controlled
+using the `name` declaration on the view:
+
+  from zope import grok
+
+  class FooView(grok.View):
+      grok.name("info.html")
+      grok.views(Foo)
+
+      @grok.page('info.info')
+      ...
+
+which translates to::
+
+  <browser:page
+     name="info.html"
+     for="Foo"
+     class="FooView"
+     permission="zope.Public"
+   />
+
+It's also possible to set the skin the view is in using ``skin``
+declaration::
+
+  from zope import grok
+  from myskin import IMySkin
+
+  class FooView(grok.View):
+     grok.skin(IMySkin)
+
+XXX can we somehow stop the concept of interface from being introduced
+here? Class-based skins?
+
+Views that do not specify *any* declarations but inherit from
+grok.View are also automatically registered, for everything (`*`)::
+
+  from zope import grok
+
+  class MyView(grok.View):
+     def getData(self):
+         return fadfkjdlkfjd
+     __call__ = template('foo.pt')
+
+is equivalent to the following ZCML::
+
+  <browser:page
+     name="MyView"
+     for="*"
+     class="MyView"
+     permission="zope.Public"
+     />
+
+View Security 
+-------------
+
+The default permission on views generated by Grok is `zope.Public`. At
+first glance, this seems to be going back to the bad old insecure days
+of Zope 2. Zope 3 has a different security model though: content
+objects can declare their own security. Since Grok declares content
+objects entirely public by default as well however, that is not a very
+strong argument.
+
+The more important argument for this "wide-open" default is that
+dealing with security issues early on in application development tends
+to be very painful and distracting for most application developers,
+breaking their flow. The temptation is therefore large to just give
+any permissions that will permit the developer to continue. Security
+issues are typically ignored until a later stage of development. We
+recognize this pattern of development, and we can't really enforce
+developers doing security right anyway, so Grok doesn't aim to try.
+
+Of course it is possible to override the default, using a class
+declaration on the view called `permission`::
+
+  from zope import grok
+
+  class MyView:
+     grok.views(SomeContent)
+     grok.permission('zope.ManageContent')
+
+Non-existing permissions are not created automatically - new
+permissions have to be declared explicitly, using ZCML.
+
+Finally, Grok also offers a "security testing" mode, where the default
+permission of all views in a package is specified by the
+developer. This can be used at a later stage during development to
+flush out any security problems.
+
+XXX explain spelling for that
+
+Class security
+--------------
+
+Attributes, both reading and writing on content are protected with the
+`zope.Public` permission by default. The aim of Grok is to get out of
+the programmers hair.
+
+How does Grok determine that something is a content class and thus
+should have its attributes made public?
+
+Grok determines something is a content class if:
+
+* it has views that directly view it
+
+* it is a subclass of a class that has views
+
+* it has an interface that has views registered for it
+
+For the purposes of security, views registered for `*` do *not* count
+as views registered for a class or interface.
+
+To restrict the permission of a content class explicitly, the same
+`permission` class declaration can be used as the one defined for
+views. This declaration sets the default access permission for *all*
+attributes of the class::
+
+  from zope import grok
+
+  class FooContent:
+     grok.permission('zope.ManageContent')
+
+It is often desirable to make an exception for some attributes, however::
+
+  from zope ipmort grok
+
+  class FooContent:
+     grok.permission('myapp.View')
+
+     @@grok.protected('myapp.Edit')
+     def protectedMethod(self):
+         pass
+
+     @@grok.private()
+     def privateMethod(self):
+         pass
+
+     def _alsoPrivate():
+         pass
+
+As soon as specific declarations are used to restrict the access to
+various methods, the default view permission of `zope.Public` does not
+apply anymore for that class.
+
+Importing 
+---------
+
+As you've seen from the examples, every import in a simple Grok
+application will be from the `zope.grok` package. This means that the
+developer does not need to remember a complicated set of imports from
+a wide-ranging set of packages just to build a simple package.
+
+This is the opposite of the current trend in Zope 3 development:
+imports from `zope.app.zapi`, intended to be an easy location to get
+important stuff are replaced with the imports from the real location.
+
+`zope.app.zapi` as an approach to simplify things failed for a number
+of reasons: it not very coherent, so hard to predict what ended up
+there, and it was incomplete: to build a real Zope 3 application you
+always needed to import from places beyond `zope.app.zapi`. In
+contrast, `zope.grok` aims to provide a relatively small number of
+names to use, and that should be *all* needed to produce a simple
+`zope.grok`-based application.
+
+Of course as a grok-based application grows developers will find
+themselves importing from other package. This should be a voyage of
+gradual discovery for the developer. There should be no need to go the
+whole way right away.
+
+XXX possible exceptions: zope.schema, zope.formlib
+
+Schema-classes
+--------------
+
+It is possible to define the schema of a class directly::
+
+  from zope import grok
+
+  class MyContent(grok.Content):
+     class data:
+         foo = TextLine(u'Foo')
+
+Fields defined are automatically created as attributes on instances
+using the defaults specified by the fields (the default default if no
+default is specified).
+
+XXX schema really should accept pure ascii strings in all cases
+    instead of unicode strings, and not *require* a u'' in front of
+    strings and give an obscure error. If you need non-ascii, *then*
+    you worry about unicode. Yet another thing less to explain to
+    beginners however.
+
+XXX we cannot use the name `schema` for the schema inner class as that
+    would conflict with `from zope import schema`...
+
+By default the schema is readable and writeable by all.
+
+The schema read and write permissions for schema fields can be set
+using special class declarations::
+
+  from zope import grok
+
+  class MyContent(grok.Content):
+     class data:
+        read_permission('myapp.View')
+        write_permission('myapp.Edit')
+
+        foo = TextLine(u'Foo')
+
+XXX want to handle the usecase of a class with multiple related
+    schemas that have an inheritance relationship to each other?
+
+No interfaces necessary
+-----------------------
+
+A Grok application can be written without a single interface in
+sight. No interfaces means less entities for the developer to care
+about, and the goal of grok is to avoid having to worry about
+interfaces when building an application. Interfaces can always be
+added later during the evolution of an application.
+
+XXX exception for skins at present..
+
+As an application grows a developer can start introducing interfaces:
+grok does not *stop* the use of interfaces.
+
+Adapters
+--------
+
+XXX is this something to be treated by grok or is this an "advanced
+topic" outside the purview of grok? It should be easy to recognize
+adapters that use `adapts()` and automatically register them.
+
+Forms
+-----
+
+Let's see how `zope.formlib` fits in with grok::
+
+  from zope import schema
+  from zope import grok
+
+  class MyContent(grok.Content):
+     class data:
+         name = schema.TextLine("Name")
+         age = schema.Int("Age")
+
+  class MyContentView(grok.EditForm):
+     grok.name('edit.html')
+     grok.views(MyContent)
+
+     # XXX can it be automatically deduced where the fields come from
+     # at this point?
+     form_fields = grok.Fields()
+
+     grok.action('Ok')
+     def handle_input(self, action, data):
+        pass
+
+XXX should be really be covering up formlib.form? ``grok.Fields()``
+    seems to imply we might have to.
+
+Templates
+---------
+
+This sets up a template to use::
+
+  from zope import grok
+
+  class MyView(grok.View):
+     grok.template('mytemplate.pt')
+
+XXX Sensible default behavior:
+
+  * use template for __call__ if no __call__ defined
+
+  * template/update pattern?
+
+Menus
+-----
+
+XXX How to make things show up in menus? When we create a new content
+object we at least want an easy way to create it, though not
+necessarily through the ZMI. Menu class declaration?
+
+TDB
+---
+
+* Easy way to generate add views
+
+* easy local utility registration?
+
+* bread - easy creation of tables, catalog-based search
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/menu.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/menu.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/menu.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,192 @@
+"""megrok.menu
+
+A simple but extensible menu system for Zope 3.
+
+What is a menu?
+
+    For web applications there are two competing design patterns that can be
+    handled under the term 'menu': classic GUI menus and web site navigation.
+
+    The essential difference in those two is the 'status' or 'context' of the
+    menu. In classic GUI applications, a menu is (more or less) stateless,
+    independent of the view to the application that is currently being used.
+
+    In classic web sites, the navigation gives a navigatable overview of the
+    site's hierarchy using an 'active' flag to indicate the user's position in
+    the site.
+
+    In web applications those two concepts start to mix.
+
+    The basic implementation of the menu system takes care of the classic
+    listing of options a user has in a specific context.
+
+    An extension mechanism is used to provide status-annotation to menu items
+    to show where a user currently is.
+
+Design goals:
+
+    -   Simple, central, menu definition without ZCML
+
+    -   Allow submenus.
+
+    -   Make status determination pluggable to allow for application-specific
+        complex scenarios without tainting the menu system.
+
+Menu rendering process:
+
+    -   create set of choices (apply filters in context, permissions, condition)
+
+    -   apply (status) annotations
+
+Determining whether an item is active:
+
+    a) Model based
+
+    - find out which object belongs to the menu item
+
+    - Is this object the same as the context of the menu?
+
+    b) View based
+
+    - find out which view belongs to the menu item
+
+    - Is it the currently published view?
+
+    Generalisation: 
+
+Zope/Grok stuff:
+
+    -   Menus are utilities
+
+Questions:
+
+    -   How to integrate with skin layers?  
+
+    -   Aren't menus just browser views? (context, request)
+
+    -   Two variations: allow menu items to render their HTML, or not? 
+
+        Allow HTML:
+
+            - provides ability to implement various menu item types
+
+            - codes in presentation
+
+        Don't allow HTML:
+
+            - more flexible to customize?
+
+        -> use views on menu items!
+"""
+
+import grok
+from megrok import menu
+
+class AddressBook(grok.Model):
+    pass
+
+class Contact(grok.Model):
+    pass
+
+class EditContact(grok.EditForm):
+    grok.context(Contact)
+    grok.annotation("title", _(u"Edit XY"))
+
+
+layout = grok.PageTemplate("""\
+<html>
+<body>
+
+    <!-- Most simple: Render the whole menu -->
+    <div tal:replace="structure menu/main/@@links"/>
+
+    <!-- Variation 1: Render whole menu as drop down list -->
+    <div tal:replace="structure menu/main/@@dropdown"/>
+
+    <!-- Variation 2: Render menu manually, get each item as link
+    <ul>
+        <li tal:repeat="item menu/main">
+            <a tal:replace="structure item/@@link">
+        </li>
+    </ul>
+
+    <!-- Variation 3: Render menu and items manually 
+    <ul tal:repeat="item menu/main"><a tal:attributes="href item/action" tal:content="item/title"></ul>
+    </ul>
+
+    <!-- Variation 4: Render option elements automatically -->
+    <select>
+        <option tal:repeat="item menu:main" tal:replace="item/@@option">
+    </select>
+
+    <!-- Bind the menu to a different object explicitly -->
+    <div tal:replace="structure python:menu['main'].bind(object1, request)"/>
+    '
+    <!-- Alternative: use a grok variable in the templates: -->
+    <div tal:replace="structure grok/menu/main/context:asdf/"/>
+
+
+
+    <grok:menu 
+</body>
+</html>""")
+
+class IMenuItem(Interface):
+
+    action
+    title
+    submenu
+
+
+main = menu.Menu(
+    menu.View(EditContact),         # Link to a view. Necessary information: context, name
+                                    # Link to a generic action/URL
+    menu.Action(_("External action"), "string:http://${context/"),
+    menu.SubMenu(
+        menu.Item(
+
+
+############ Implementation sketches
+
+class ViewMenuItem(object):
+
+    def __init__(self, view):
+        # View must be a view
+        
+
+class Action(object):
+    
+    def __init__(self, title, target):
+        self.title = title
+        self.target = target    # TALES expression
+
+    def 
+
+
+class BaseMenuItem(object):
+
+    def __init__(self, condition):
+        self.condition = condition
+
+    def checkCondition(context, request):
+        # - does this item apply in the given context?
+        # - does the user have the necessary permissions
+        # - does the user supplied condition evalute to true? 
+    
+
+class Menu(object):
+
+    def __init__(self, menu_items):
+        # XXX assert: All items must be menu items
+        self.menu_items = menu_items
+
+    def __call__(self, context, request):
+        relevant_items = []
+
+        for item in self.menu_items:
+            if not item.checkCondition(context, request):
+                continue
+
+            relevant_item.append(item)
+
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/model.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/model.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/model.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,56 @@
+"""
+Schema-driven development with grok
+"""
+import grok
+
+grok.directory('contact')
+
+class Contact(grok.SchemaModel):
+    """
+    This works now:
+
+      >>> c = Contact(name=u'Martijn', city=u'Rotterdam')
+      >>> c.name
+      u'Martijn'
+
+    Also w/o kw:
+
+      >>> c = Contact(u'Martijn', u'Rotterdam')
+      >>> c.name
+      u'Martijn'
+
+    """
+    class fields:
+        name = schema.TextLine()
+        city = schema.TextLine()
+
+
+class Edit(grok.EditForm):
+    pass
+    # this will automatically render an edit form, and use an
+    # 'edit.html' template if available
+
+class Index(grok.DisplayForm):
+    pass
+    # this will automatically render an display form, and use an
+    # 'index.html' template if available
+
+class Add(grok.AddForm):
+    grok.context(Contact)  # this is actually the default
+    grok.container(IContainer)  # this is actually the default
+
+class FancyEdit(grok.EditForm):
+    """ use cases:
+
+    * (actions with permissions)
+
+    *
+
+    """
+
+    @grok.action("Save")
+    def save(self, **data):
+        """
+        this overrides any actions defined on the base class
+        """
+        self.applyChanges(data)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/permission.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/permission.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/permission.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+import grok
+
+grok.definepermission('grok.Complex')  # define permission first
+
+class Complex(grok.Model):
+    # this sets the default for all methods
+    grok.require('zope.Public')  # this is actually the default
+
+    # this sets the default for reading all attributes that are not methods
+    grok.readable('zope.Public')  # this is actually the default
+
+    # this sets the default for writing all attributes that are not methods
+    grok.writable('zope.Public')  # this is actually the default
+
+    # this overrides the above
+    grok.readable('grok.Complex', 'attr1') # override default
+    grok.readable('zope.ManageServices', 'attr2') # override default
+    grok.writable('zope.ManageContent', 'attr1', 'attr2') # override default
+
+    def __init__(self):
+        self.attr1 = 1
+        self.attr2 = 2
+
+    @grok.require('some.permission')
+    def doSomethingVerySecret(self):
+        pass
+
+    @grok.require('zope.Public')  # this is actually the default
+    def imPublic(self):
+        pass
+
+class SubClass(Complex):
+    # it's all inherited
+
+    grok.readable('zope.Public', 'attr1')
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/skin-minimal.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/skin-minimal.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/skin-minimal.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,18 @@
+import grok
+from zope import interface
+
+
+grok.definelayer('my')
+grok.defineskin('my')                 # Picks up the layer 'my' if it exists
+
+grok.layer('my')                      # If there is only a single layer defined
+                                      # in a module, it will be the default
+
+
+class Painting(grok.View):
+    pass
+
+
+fireplace = grok.PageTemplate("""\
+<html><body></body></html>
+""")

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/skin.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/skin.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/skin.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,25 @@
+import grok
+from zope import interface
+
+
+grok.definelayer('my')
+grok.definelayer('admin')
+
+grok.layer('my')
+
+grok.defineskin('my', ['my'])         # this is the default
+grok.defineskin('my')                 # does the same as the line above
+grok.defineskin('admin', ['admin', 'my'])
+
+
+class Painting(grok.View):
+    pass
+
+
+fireplace = grok.PageTemplate("""\
+<html><body></body></html>
+""")
+
+
+class AdminPainting(grok.View):
+    grok.layer('adminlayer')

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/subscriber.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/subscriber.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/subscriber.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,11 @@
+from zope.lifecycleevent.interfaces import IObjectModifiedEvent
+from calc import Calculator
+import grok
+
+ at grok.subscriber(Calculator, IObjectModifiedEvent)
+def calculatorChanged(calc, event):
+    pass
+
+
+# perhaps alias zope.event.notify to grok.notify???
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/traversal.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/traversal.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/traversal.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,50 @@
+import grok
+
+class Appointment(grok.Model):
+    pass
+
+class Day(grok.Model):
+
+    def getAppointment(self, number):
+        if number in self.appointments:
+            return Appointment(number)
+        return None # try to look up views then
+
+    def traverse(self, name):
+        return self.getAppointment(int(number))
+    
+class Calendar(grok.Model):
+    def getYear(self, year):
+        return Year(year)
+
+    def traverse(self, name):
+        return self.getYear(int(number))
+
+# interpretation of traverse:
+
+# * do the traverse traversal first
+
+# * if this raises an error, propagate exception, do not swallow it (test)
+
+# * if this returns None, fall back on "normal" traversal for the
+    object (i.e. container traversal)
+
+"""
+http://.../calendar/2006/10/13/1/
+           ^^^^^^^^ ^^^^ ^^ ^^ ^
+            Cal.    Year  ...  A.
+"""
+
+#XXX routes (http://routes.groovie.org/) for advanced cases
+
+
+# instead of traverser on the model, you can also write a separate
+# traverser component:
+
+class CalendarTraverser(grok.Traverser):
+    grok.context(Calendar)  # this is actually the default
+    grok.register(site=CalendarApp)  #...
+
+    def traverse(self, name):
+        now look up stuff on self.context with 'name'...
+        return that

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/utility.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/utility.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/utility.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,31 @@
+import grok
+
+class Calculator(grok.GlobalUtility):
+    grok.implements(ICalculator)  # if this is not specified, it breaks
+    grok.name('')  # this is actually the default
+    grok.provides(ICalculator) # this is actually the default
+
+grok.global_utility(factory, provides=IFace, name=u'')
+
+class Calculator(grok.LocalUtility):
+    grok.utility_provides(ICalculator)
+
+class Anything(grok.Model):
+    pass
+
+class NonPersistent(object):
+    pass
+
+class SpecialAnything(Anything):
+    pass
+
+class Foo(grok.Model, grok.Site):    
+    grok.local_utility(Anything, hide=False, name_in_container='foo',
+                       persistent=None)
+    grok.local_adapter()
+    grok.local_view()
+
+class Foo2(Foo):
+    grok.local_utility(SpecialAnything)
+
+    

Added: groktoolkit/branches/jw-documentation-rearangement/doc/design/views.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/design/views.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/design/views.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,85 @@
+import grok
+
+grok.templatedir('calc_templates')  # this is actually the default (from module name, calc.py)
+
+class Calculator(grok.Model):
+    pass
+
+class Sum(grok.View):
+    """Simple view for a model"""
+    grok.context(Calculator)  # this is actually the default (from module)
+    grok.template('sum')  # this is actually the default (from class name)
+    grok.name('sum')  # this is actually the default (from class name)
+    grok.require('zope.Public')  # this is actually the default
+
+    def calculateSum(self):
+        """you can pull this in the template through view/calculateSum"""
+
+    def update(self):    
+        """executed before the template is rendered"""
+        self.sum = self.calculateSum()
+        self.sendEmail()
+
+    def sendEmail(self):
+        """send an email here"""
+
+class PDFSum(grok.View):
+
+    def update(self):
+        pass
+
+    def render(self):
+        return pdfdata
+
+sum = grok.PageTemplate("""\
+<p tal:content="view/calculateSum">...</p>
+<p tal:content="view/precalculatedSum">...</p>
+""")
+
+
+from zope import schema
+
+class Index(grok.Form):
+    """a form
+
+    this is the default view for the Calculator model (because it's
+    called Index)
+    """
+
+    class fields:
+        operand = schema.Int(title=u'Operand')
+        operator = schema.Choice(...)
+        operand2 = schema.Int(...)
+
+    @grok.action('Calculate')
+    def calculate(self, operand, operator, operand2):
+        """it's possible to receive any number of form fields in any
+        order, or just use **kw to receive them all in a dict"""
+        self.result = operator(operand, operand2)
+
+    # this will raise a helpful error message at startup time (encoded
+    # strings)
+    @grok.action('Bääää')
+    def whatever(self, **data):
+        pass
+
+index = grok.PageTemplate("""\
+<form tal:attributes="action request/URL">
+<p tal:condition="exists:view/result">
+  The result is: <span tal:replace="view/result" />
+</p>
+
+XXX render fields
+XXX render actions
+</form>
+""")
+
+class CalculatorXMLRPC(grok.XMLRPC):
+
+    @grok.require('zope.Public')  # this is actually the default
+    def sum(self, operand, operator, operand2):
+        return ...
+
+    @grok.require('something.else')
+    def whatever(self):
+        return ...

Added: groktoolkit/branches/jw-documentation-rearangement/doc/developing_grok.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/developing_grok.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/developing_grok.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,123 @@
+===============
+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!

Added: groktoolkit/branches/jw-documentation-rearangement/doc/docindex.template
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/docindex.template	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/docindex.template	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,87 @@
+{% 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

Added: groktoolkit/branches/jw-documentation-rearangement/doc/glossary.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/glossary.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/glossary.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,99 @@
+=================
+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
+
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/grok_overview.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/grok_overview.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/grok_overview.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,1374 @@
+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>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,15 @@
+import grok
+  
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Another(grok.Application, grok.Model):
+    pass
+
+class SampleIndex(grok.View):
+    grok.context(Sample)
+    grok.name('index')
+    
+class AnotherIndex(grok.View):
+    grok.context(Another)
+    grok.name('index')

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app_templates/anotherindex.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app_templates/anotherindex.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app_templates/anotherindex.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p>Another index</p>
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app_templates/sampleindex.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app_templates/sampleindex.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/app_templates/sampleindex.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p>Sample index</p>
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_model/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,11 @@
+import grok
+  
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    pass
+
+class Bye(grok.View):
+    pass
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app_templates/bye.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app_templates/bye.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app_templates/bye.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p>Bye world!</p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p>Hello world!</p>
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_second_view/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    def information(self):
+        return "This is important information!"
+
+class Index(grok.View):
+    pass

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p tal:content="python:context.information()">replaced</p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,9 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    def information(self):
+        return "This is important information!"
+
+class Index(grok.View):
+    def reversed_information(self):
+        return ''.join(reversed(self.context.information()))

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,10 @@
+<html>
+<body>
+<p>The information:
+  <span tal:content="python:context.information()">info</span>
+</p>
+<p>The information, reversed: 
+  <span tal:replace="python:view.reversed_information()">info</span>
+</p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/a_view_for_a_model2/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+# this directory is a package

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,7 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    pass # see app_templates/index.pt

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,32 @@
+Do a functional doctest test on the app.
+========================================
+
+:Test-Layer: functional
+
+Let's first create an instance of Sample at the top level:
+
+   >>> from sample.app import Sample
+   >>> root = getRootFolder()
+   >>> root['app'] = Sample()
+
+
+Run tests in the testbrowser
+----------------------------
+
+The zope.testbrowser.browser module exposes a Browser class that
+simulates a web browser similar to Mozilla Firefox or IE.  We use that
+to test how our application behaves in a browser.  For more
+information, see http://pypi.python.org/pypi/zope.testbrowser.
+
+Create a browser and visit the instance you just created:
+
+   >>> from zope.testbrowser.testing import Browser
+   >>> browser = Browser()
+   >>> browser.open('http://localhost/app')
+
+Check some basic information about the page you visit:
+
+   >>> browser.url
+   'http://localhost/app'
+   >>> browser.headers.get('Status').upper()
+   '200 OK'

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,11 @@
+<html>
+<head>
+</head>
+<body>
+  <h1>Congratulations!</h1>
+
+  <p>Your Grok application is up and running.
+  Edit <code>sample/app_templates/index.pt</code> to change
+  this page.</p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/ftesting.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/ftesting.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/ftesting.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,34 @@
+<configure
+   xmlns="http://namespaces.zope.org/zope"
+   i18n_domain="sample"
+   package="sample"
+   >
+
+  <include package="sample" />
+
+  <!-- Typical functional testing security setup -->
+  <securityPolicy
+      component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy"
+      />
+
+  <unauthenticatedPrincipal
+      id="zope.anybody"
+      title="Unauthenticated User"
+      />
+  <grant
+      permission="zope.View"
+      principal="zope.anybody"
+      />
+
+  <principal
+      id="zope.mgr"
+      title="Manager"
+      login="mgr"
+      password="mgrpw"
+      />
+
+  <role id="zope.Manager" title="Site Manager" />
+  <grantAll role="zope.Manager" />
+  <grant role="zope.Manager" principal="zope.mgr" />
+
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/static/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/static/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/static/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,2 @@
+Put static files here, like javascript and css.  They will be
+available as static/<filename> in views.

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/tests.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/tests.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/an_empty_grok_project/src/sample/tests.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,10 @@
+import os.path
+import z3c.testsetup
+from zope.app.wsgi.testlayer import BrowserLayer
+
+import sample
+
+browser_layer = BrowserLayer(sample)
+
+test_suite = z3c.testsetup.register_all_tests(
+    'sample', globs={'getRootFolder': browser_layer.getRootFolder})

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+import grok
+  
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    def render(self):
+        return "ME GROK NO TEMPLATE"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/completely_python_driven_views/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,21 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Entry(grok.Model):
+    def __init__(self, text):
+        self.text = text
+
+class SampleIndex(grok.View):
+    grok.context(Sample)
+    grok.name('index')
+
+    def update(self, name=None, text=None):
+        if name is None or text is None:
+            return
+        self.context[name] = Entry(text)
+
+class EntryIndex(grok.View):
+    grok.context(Entry)
+    grok.name('index')

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app_templates/entryindex.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app_templates/entryindex.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app_templates/entryindex.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+<html>
+<head>
+</head>
+<body>
+  <h2>Entry <span tal:replace="python:context.__name__"></span></h2>
+  <p tal:content="python:context.text"></p>
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app_templates/sampleindex.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app_templates/sampleindex.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/app_templates/sampleindex.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,21 @@
+<html>
+<head>
+</head>
+<body>
+  <h2>Existing entries</h2>
+  <ul>
+    <li tal:repeat="key python:context.keys()">
+      <a tal:attributes="href python:view.url(key)" 
+         tal:content="python:key"></a>
+    </li>
+  </ul>
+ 
+  <h2>Add a new entry</h2>
+  <form tal:attributes="action python:view.url()" method="POST">
+    Name: <input type="text" name="name" value="" /><br />
+    Text: <input type="text" name="text" value="" /><br />
+    <input type="submit" value="Add entry" />
+  </form>
+
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/containers/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,9 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    def update(self):
+        self.alpha = 2 ** 8
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p tal:content="python:view.alpha">result</p>
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/doing_some_calculation_before_viewing_a_page/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,12 @@
+import grok
+  
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    grok.context(Sample)
+
+class Bye(grok.View):
+    grok.context(Sample)
+    
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app_templates/bye.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app_templates/bye.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app_templates/bye.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p>Bye world!</p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p>Hello world!</p>
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/explicitly_associating_a_view_with_a_model/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,9 @@
+import grok
+  
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    def some_html(self):
+        return "<b>ME GROK BOLD</b>"
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p tal:content="structure python:view.some_html()"></p>
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/generating_html_from_python/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    pass
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p tal:content="python: 1 + 1">this is replaced</p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/making_our_page_dynamic/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,7 @@
+import grok
+  
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    pass

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,32 @@
+Do a functional doctest test on the app.
+========================================
+
+:Test-Layer: functional
+
+Let's first create an instance of Sample at the top level:
+
+   >>> from sample.app import Sample
+   >>> root = getRootFolder()
+   >>> root['app'] = Sample()
+
+
+Run tests in the testbrowser
+----------------------------
+
+The zope.testbrowser.browser module exposes a Browser class that
+simulates a web browser similar to Mozilla Firefox or IE.  We use that
+to test how our application behaves in a browser.  For more
+information, see http://pypi.python.org/pypi/zope.testbrowser.
+
+Create a browser and visit the instance you just created:
+
+   >>> from zope.testbrowser.testing import Browser
+   >>> browser = Browser()
+   >>> browser.open('http://localhost/app')
+
+Check some basic information about the page you visit:
+
+   >>> browser.url
+   'http://localhost/app'
+   >>> browser.headers.get('Status').upper()
+   '200 OK'

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p>Hello world!</p>
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/ftesting.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/ftesting.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/ftesting.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,34 @@
+<configure
+   xmlns="http://namespaces.zope.org/zope"
+   i18n_domain="sample"
+   package="sample"
+   >
+
+  <include package="sample" />
+
+  <!-- Typical functional testing security setup -->
+  <securityPolicy
+      component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy"
+      />
+
+  <unauthenticatedPrincipal
+      id="zope.anybody"
+      title="Unauthenticated User"
+      />
+  <grant
+      permission="zope.View"
+      principal="zope.anybody"
+      />
+
+  <principal
+      id="zope.mgr"
+      title="Manager"
+      login="mgr"
+      password="mgrpw"
+      />
+
+  <role id="zope.Manager" title="Site Manager" />
+  <grantAll role="zope.Manager" />
+  <grant role="zope.Manager" principal="zope.mgr" />
+
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/static/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/static/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/static/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,2 @@
+Put static files here, like javascript and css.  They will be
+available as static/<filename> in views.

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/tests.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/tests.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/publishing_a_simple_web_page/src/sample/tests.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,10 @@
+import os.path
+import z3c.testsetup
+from zope.app.wsgi.testlayer import BrowserLayer
+
+import sample
+
+browser_layer = BrowserLayer(sample)
+
+test_suite = z3c.testsetup.register_all_tests(
+    'sample', globs={'getRootFolder': browser_layer.getRootFolder})

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    def update(self, value1, value2):
+        self.sum = int(value1) + int(value2)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p tal:content="python:view.sum">sum</p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    def update(self, value1=0, value2=0):
+        self.sum = int(value1) + int(value2)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p tal:content="python:view.sum">sum</p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/reading_url_parameters2/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,14 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    text = 'default text'
+
+class Index(grok.View):
+    pass
+
+class Edit(grok.View):
+    def update(self, text=None):
+        if text is None:
+            return
+        self.context.text = text
+        self.redirect(self.url('index'))

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app_templates/edit.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app_templates/edit.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app_templates/edit.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+<html>
+<body>
+<form tal:attributes="action view/url" method="POST">
+Text to store: <input type="text" name="text" value="" /><br />
+<input type="submit" value="Store" />
+</form>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<html>
+<body>
+<p>The text: <span tal:replace="python:context.text">text</span></p>
+<p><a tal:attributes="href python:view.url('edit')">Edit this page</a></p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/redirection/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,10 @@
+import grok
+  
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    def render(self):
+        self.response.setHeader('Content-Type',
+                                'text/xml; charset=UTF-8')
+        return "<doc>Some XML</doc>"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/setting_the_content_type/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,14 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    text = 'default text'
+
+class Index(grok.View):
+    pass
+
+class Edit(grok.View):
+    def update(self, text=None):
+        if text is None:
+            return
+        self.context.text = text
+        self.redirect(self.url('index'))

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app_templates/edit.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app_templates/edit.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app_templates/edit.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+<html>
+<body>
+<form tal:attributes="action view/url" method="POST">
+Text to store: <input type="text" name="text" tal:attributes="value python:context.text" value="" /><br />
+<input type="submit" value="Store" />
+</form>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<html>
+<body>
+<p>The text: <span tal:replace="python:context.text">text</span></p>
+<p><a tal:attributes="href python:view.url('edit')">Edit this page</a></p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/showing_the_value_in_the_form/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    def update(self, value1=0, value2=0):
+        self.sum = int(value1) + int(value2)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,10 @@
+<html>
+<body>
+<form tal:attributes="action python:view.url()" method="GET">
+  Value 1: <input type="text" name="value1" value="" /><br />
+  Value 2: <input type="text" name="value2" value="" /><br />
+  <input type="submit" value="Sum!" />
+</form>
+<p>The sum is: <span tal:replace="python:view.sum">sum</span></p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,14 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    def update(self, value1=None, value2=None):
+        try:
+            value1 = int(value1)
+            value2 = int(value2)
+        except (TypeError, ValueError):
+            self.sum = "No sum"
+            return
+        self.sum = value1 + value2

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,10 @@
+<html>
+<body>
+<form tal:attributes="action python:view.url()" method="GET">
+  Value 1: <input type="text" name="value1" value="" /><br />
+  Value 2: <input type="text" name="value2" value="" /><br />
+  <input type="submit" value="Sum!" />
+</form>
+<p>The sum is: <span tal:replace="python:view.sum">sum</span></p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/simple_forms2/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,7 @@
+import grok
+  
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    pass

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,9 @@
+<html>
+<head>
+<link rel="stylesheet" type="text/css" 
+      tal:attributes="href static/style.css" />
+</head>
+<body>
+<p>Hello world!</p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/static/style.css
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/static/style.css	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/static_resources_for_our_web_page/src/sample/static/style.css	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,3 @@
+body {
+    background-color: #FF0000;
+}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,13 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    text = 'default text'
+
+class Index(grok.View):
+    pass
+
+class Edit(grok.View):
+    def update(self, text=None):
+        if text is None:
+            return
+        self.context.text = text

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app_templates/edit.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app_templates/edit.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app_templates/edit.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+<html>
+<body>
+<form tal:attributes="action view/url" method="POST">
+Text to store: <input type="text" name="text" value="" /><br />
+<input type="submit" value="Store" />
+</form>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p>The text: <span tal:replace="python:context.text">text</span></p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/storing_data/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+# this directory is a package

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,7 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    pass # see app_templates/index.pt

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,11 @@
+<html>
+<head>
+</head>
+<body>
+  <h1>Congratulations!</h1>
+
+  <p>Your Grok application is up and running.
+  Edit <code>sample/app_templates/index.pt</code> to change
+  this page.</p>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/template/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,17 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    def __init__(self):
+        super(Sample, self).__init__()
+        self.list = []
+    
+class Index(grok.View):
+    pass
+
+class Edit(grok.View):
+    def update(self, text=None):
+        if text is None:
+            return
+        # this code has a BUG!
+        self.context.list.append(text)
+        self.redirect(self.url('index'))

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app_templates/edit.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app_templates/edit.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app_templates/edit.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+<html>
+<body>
+<form tal:attributes="action view/url" method="POST">
+Text to store: <input type="text" name="text" value="" /><br />
+<input type="submit" value="Store" />
+</form>
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,9 @@
+<html>
+<body>
+We store the following texts:
+<ul>
+  <li tal:repeat="text python:context.list" tal:content="text"></li>
+</ul>
+<a tal:attributes="href python:view.url('edit')">Add a text</a>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,17 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    def __init__(self):
+        super(Sample, self).__init__()
+        self.list = []
+    
+class Index(grok.View):
+    pass
+
+class Edit(grok.View):
+    def update(self, text=None):
+        if text is None:
+            return
+        self.context.list.append(text)
+        self.context._p_changed = True
+        self.redirect(self.url('index'))

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app_templates/edit.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app_templates/edit.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app_templates/edit.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+<html>
+<body>
+<form tal:attributes="action view/url" method="POST">
+Text to store: <input type="text" name="text" value="" /><br />
+<input type="submit" value="Store" />
+</form>
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,9 @@
+<html>
+<body>
+We store the following texts:
+<ul>
+  <li tal:repeat="text python:context.list" tal:content="text"></li>
+</ul>
+<a tal:attributes="href python:view.url('edit')">Add a text</a>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence2/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,20 @@
+import grok
+
+class Sample(grok.Application, grok.Container):
+    def __init__(self):
+        super(Sample, self).__init__()
+        self.list = []
+
+    def addText(self, text):
+        self.list.append(text)
+        self._p_changed = True
+        
+class Index(grok.View):
+    pass
+
+class Edit(grok.View):
+    def update(self, text=None):
+        if text is None:
+            return
+        self.context.addText(text)
+        self.redirect(self.url('index'))

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app_templates/edit.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app_templates/edit.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app_templates/edit.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,8 @@
+<html>
+<body>
+<form tal:attributes="action view/url" method="POST">
+Text to store: <input type="text" name="text" value="" /><br />
+<input type="submit" value="Store" />
+</form>
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,9 @@
+<html>
+<body>
+We store the following texts:
+<ul>
+  <li tal:repeat="text python:context.list" tal:content="text"></li>
+</ul>
+<a tal:attributes="href python:view.url('edit')">Add a text</a>
+</body>
+</html>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/the_rules_of_persistence3/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/bootstrap.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/bootstrap.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/bootstrap.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,260 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+    [sys.executable, '-Sc',
+     'try:\n'
+     '    import ConfigParser\n'
+     'except ImportError:\n'
+     '    print 1\n'
+     'else:\n'
+     '    print 0\n'],
+    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded.  This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient.  However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+    # We will restart with python -S.
+    args = sys.argv[:]
+    args[0:0] = [sys.executable, '-S']
+    args = map(quote, args)
+    os.execv(sys.executable, args)
+# Now we are running with -S.  We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+    if k in ('setuptools', 'pkg_resources') or (
+        hasattr(v, '__path__') and
+        len(v.__path__)==1 and
+        not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+        # This is a namespace package.  Remove it.
+        sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+    if value:
+        if '://' not in value: # It doesn't smell like a URL.
+            value = 'file://%s' % (
+                urllib.pathname2url(
+                    os.path.abspath(os.path.expanduser(value))),)
+        if opt_str == '--download-base' and not value.endswith('/'):
+            # Download base needs a trailing slash to make the world happy.
+            value += '/'
+    else:
+        value = None
+    name = opt_str[2:].replace('-', '_')
+    setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="use_distribute", default=False,
+                   help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or file location for the setup file. "
+                        "If you use Setuptools, this will default to " +
+                        setuptools_source + "; if you use Distribute, this "
+                        "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+                  callback=normalize_to_url, nargs=1, type="string",
+                  help=("Specify a URL or directory for downloading "
+                        "zc.buildout and either Setuptools or Distribute. "
+                        "Defaults to PyPI."))
+parser.add_option("--eggs",
+                  help=("Specify a directory for storing eggs.  Defaults to "
+                        "a temporary directory that is deleted when the "
+                        "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+                  dest='accept_buildout_test_releases',
+                  action="store_true", default=False,
+                  help=("Normally, if you do not specify a --version, the "
+                        "bootstrap script and buildout gets the newest "
+                        "*final* versions of zc.buildout and its recipes and "
+                        "extensions for you.  If you use this flag, "
+                        "bootstrap and buildout will get the newest releases "
+                        "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.eggs:
+    eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+    eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+    if options.use_distribute:
+        options.setup_source = distribute_source
+    else:
+        options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+    args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+    import pkg_resources
+    import setuptools # A flag.  Sometimes pkg_resources is installed alone.
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez_code = urllib2.urlopen(
+        options.setup_source).read().replace('\r\n', '\n')
+    ez = {}
+    exec ez_code in ez
+    setup_args = dict(to_dir=eggs_dir, download_delay=0)
+    if options.download_base:
+        setup_args['download_base'] = options.download_base
+    if options.use_distribute:
+        setup_args['no_fake'] = True
+    ez['use_setuptools'](**setup_args)
+    if 'pkg_resources' in sys.modules:
+        reload(sys.modules['pkg_resources'])
+    import pkg_resources
+    # This does not (always?) update the default working set.  We will
+    # do it.
+    for path in sys.path:
+        if path not in pkg_resources.working_set.entries:
+            pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+       '-c',
+       quote('from setuptools.command.easy_install import main; main()'),
+       '-mqNxd',
+       quote(eggs_dir)]
+
+if not has_broken_dash_S:
+    cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+    find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+    cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+    setup_requirement = 'distribute'
+else:
+    setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+    pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+    os.environ,
+    PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+    # Figure out the most recent final version of zc.buildout.
+    import setuptools.package_index
+    _final_parts = '*final-', '*final'
+    def _final_version(parsed_version):
+        for part in parsed_version:
+            if (part[:1] == '*') and (part not in _final_parts):
+                return False
+        return True
+    index = setuptools.package_index.PackageIndex(
+        search_path=[setup_requirement_path])
+    if find_links:
+        index.add_find_links((find_links,))
+    req = pkg_resources.Requirement.parse(requirement)
+    if index.obtain(req) is not None:
+        best = []
+        bestv = None
+        for dist in index[req.project_name]:
+            distv = dist.parsed_version
+            if _final_version(distv):
+                if bestv is None or distv > bestv:
+                    best = [dist]
+                    bestv = distv
+                elif distv == bestv:
+                    best.append(dist)
+        if best:
+            best.sort()
+            version = best[-1].version
+if version:
+    requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+    import subprocess
+    exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+    sys.stdout.flush()
+    sys.stderr.flush()
+    print ("An error occurred when trying to install zc.buildout. "
+           "Look above this message for any errors that "
+           "were output by easy_install.")
+    sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+    shutil.rmtree(eggs_dir)

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/buildout.cfg
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/buildout.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/buildout.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,96 @@
+[buildout]
+extends = http://svn.zope.org/repos/main/groktoolkit/branches/1.2/grok.cfg
+extends-cache = extends-cache
+find-links =
+include-site-packages = false
+develop = .
+parts =
+    app
+    debug_ini
+    deploy_ini
+    i18n
+    mkdirs
+    site_zcml
+    test
+    zope_conf
+    zpasswd
+    interactive_debugger
+newest = false
+versions = versions
+extensions = buildout.dumppickedversions
+
+[app]
+recipe = z3c.recipe.scripts
+eggs = Sample
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[deploy_ini]
+recipe = collective.recipe.template
+input = etc/deploy.ini.in
+output = ${buildout:parts-directory}/etc/deploy.ini
+host = 127.0.0.1
+port = 8080
+
+[debug_ini]
+recipe = collective.recipe.template
+input = etc/debug.ini.in
+output = ${buildout:parts-directory}/etc/debug.ini
+host = 127.0.0.1
+port = 8080
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = sample
+eggs = sample
+domain = sample
+output = src/sample/locales
+zcml =
+
+[mkdirs]
+recipe = z3c.recipe.mkdir
+paths =
+    ${zope_conf:filestorage}
+    ${zope_conf:logfiles}
+    ${zope_conf:blobstorage}
+
+[site_zcml]
+recipe = collective.recipe.template
+input = etc/site.zcml.in
+output = ${buildout:parts-directory}/etc/site.zcml
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = Sample
+defaults = ['-v']
+
+[zope_conf]
+recipe = collective.recipe.template
+input = etc/zope.conf.in
+output = ${buildout:parts-directory}/etc/zope.conf
+filestorage = ${buildout:directory}/var/filestorage
+blobstorage = ${buildout:directory}/var/blobstorage
+logfiles = ${buildout:directory}/var/log
+extra =
+# 'extra' is copied verbatim. Use it for product config sections and so.
+
+# This section is named so that the zpasswd utility is
+# called `zpasswd`
+[zpasswd]
+recipe = z3c.recipe.scripts
+eggs =
+  Sample
+  zope.password
+entry-points =
+  zpasswd=zope.password.zpasswd:main
+
+[interactive_debugger]
+recipe = z3c.recipe.scripts
+eggs = Sample
+entry-points =
+  interactive_debugger=grokcore.startup.startup:interactive_debug_prompt
+arguments = zope_conf="${zope_conf:output}"

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/README.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/README.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/README.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,26 @@
+In this directory you can find templates which are used by
+``zc.buildout`` to create the configuration files in the parts/etc/ subdir
+of your project.
+
+If you modify files in this directory, you have to run::
+
+  $ bin/buildout
+
+afterwards to rebuild the configuration files in parts/etc/.
+
+In the templates you can use placesholders recognized by zc.buildout
+to name local paths, etc. A zc.buildout placeholder looks like this::
+
+  ${buildout:directory}
+
+which gives you the path of the project directory and will be
+substituted with the real path when you run buildout the next
+time. The set of available placeholders depends on your
+buildout.cfg.
+
+You can also modify files in parts/etc directly, but those changes
+will be overwritten after running bin/buildout the next time.
+
+To run your project you can do::
+
+  $ bin/paster serve parts/etc/deploy.ini

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/debug.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/debug.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/debug.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,67 @@
+# debug.ini
+#
+# Debugging configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:Sample#debug
+filter-with = translogger
+exempt-exceptions = zope.security.interfaces.IUnauthorized
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/deploy.ini.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/deploy.ini.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/deploy.ini.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,60 @@
+# deploy.ini
+#
+# Deployment configuration for use with paster/WSGI
+#
+
+[loggers]
+keys = root, wsgi
+
+[handlers]
+keys = console, accesslog
+
+[formatters]
+keys = generic, accesslog
+
+[logger_root]
+level = INFO
+handlers = console
+
+[logger_wsgi]
+level = INFO
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[handler_accesslog]
+class = FileHandler
+args = (os.path.join(r'${buildout:directory}', 'parts', 'log', 'access.log'),
+        'a')
+level = INFO
+formatter = accesslog
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s] %(message)s
+
+[formatter_accesslog]
+format = %(message)s
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+logger_name = wsgi
+
+[app:main]
+use = egg:Sample
+filter-with = translogger
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
+
+[DEFAULT]
+# set the name of the zope.conf file
+zope_conf = %(here)s/zope.conf

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/site.zcml.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/site.zcml.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/site.zcml.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="sample">
+
+  <include package="sample" />
+
+    <configure i18n_domain="sample">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login="grok"
+                 password_manager="SHA1"
+                 password="8977f073739bd029629243732eb682db005a7541f7509622"
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/zope.conf.in
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/zope.conf.in	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/etc/zope.conf.in	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,40 @@
+# Identify the component configuration used to define the site:
+site-definition ${site_zcml:output}
+
+<zodb>
+  # Standard blob storage
+  <blobstorage>
+    blob-dir ${zope_conf:blobstorage}
+    <filestorage>
+      path ${zope_conf:filestorage}/Data.fs
+    </filestorage>
+  </blobstorage>
+
+# Uncomment this if you want a blob-less standard file storage instead:
+#  <filestorage>
+#       path ${zope_conf:filestorage}
+#  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+
+</zodb>
+
+<eventlog>
+# logfiles are setup in the debug.ini and deploy.ini files.
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
+
+# Extra configuration lines can be added to zope_conf's extra option. Put for
+# instance productconf sections in here.
+${zope_conf:extra}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/setup.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/setup.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/setup.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+
+version = '0.0'
+
+setup(name='Sample',
+      version=version,
+      description="",
+      long_description="""\
+""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
+      keywords="",
+      author="",
+      author_email="",
+      url="",
+      license="",
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        'grokcore.startup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      sample-debug = grokcore.startup:interactive_debug_prompt
+      sample-ctl = grokcore.startup:zdaemon_controller
+      [paste.app_factory]
+      main = grokcore.startup:application_factory
+      debug = grokcore.startup:debug_application_factory
+      """,
+      )

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/__init__.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/__init__.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/__init__.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+#

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/app.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/app.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/app.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,10 @@
+import grok
+from datetime import datetime
+
+class Sample(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):    
+    def current_datetime(self):
+        now = datetime.now()
+        return now.strftime('%Y-%m-%d %H:%M')

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/app_templates/index.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/app_templates/index.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/app_templates/index.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p tal:content="python:view.current_datetime()">Hello world!</p>
+</body>
+</html>
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/configure.zcml
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/configure.zcml	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/groktut/using_view_methods/src/sample/configure.zcml	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: groktoolkit/branches/jw-documentation-rearangement/doc/index.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/index.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/index.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,7 @@
+Official Grok Documentation Overview
+************************************
+
+.. toctree::
+   :hidden:
+
+   contents.rst

Added: groktoolkit/branches/jw-documentation-rearangement/doc/layout.html
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/layout.html	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/layout.html	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,35 @@
+{% 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 %}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/license.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/license.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/license.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,62 @@
+.. _license:
+
+***********
+The License
+***********
+
+Zope Public License (ZPL) Version 2.1
+-------------------------------------
+
+A copyright notice accompanies this license document that
+identifies the copyright holders.
+
+This license has been certified as open source. It has also
+been designated as GPL compatible by the Free Software
+Foundation (FSF).
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the
+following conditions are met:
+
+1. Redistributions in source code must retain the
+   accompanying copyright notice, this list of conditions,
+   and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the accompanying
+   copyright notice, this list of conditions, and the
+   following disclaimer in the documentation and/or other
+   materials provided with the distribution.
+
+3. Names of the copyright holders must not be used to
+   endorse or promote products derived from this software
+   without prior written permission from the copyright
+   holders.
+
+4. The right to distribute this software or to use it for
+   any purpose does not give you the right to use
+   Servicemarks (sm) or Trademarks (tm) of the copyright
+   holders. Use of them is covered by separate agreement
+   with the copyright holders.
+
+5. If any files are modified, you must cause the modified
+   files to carry prominent notices stating that you changed
+   the files and the date of any change.
+
+Disclaimer
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS''
+  AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+  NO EVENT SHALL THE COPYRIGHT HOLDERS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+  DAMAGE.
+
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/make.bat
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/make.bat	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/make.bat	2011-01-12 16:38:04 UTC (rev 119545)
@@ -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

Added: groktoolkit/branches/jw-documentation-rearangement/doc/naming_conventions.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/naming_conventions.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/naming_conventions.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,33 @@
+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.

Added: groktoolkit/branches/jw-documentation-rearangement/doc/reference/components.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/reference/components.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/reference/components.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,1687 @@
+
+**********
+Components
+**********
+
+.. Here we documented the component base classes. For the directive
+    possible for each component we document only the specifics within
+    its context. We then refer to the directives documented in the
+    directives.rst file.
+
+The :mod:`grok` module defines a set of base classes for creating new
+components of different types, that provide basic Zope 3 functionality in a
+convenient way. Grok applications are built by subclassing these components.
+
+Components in Grok and Zope 3 are any plain Python object, that declare they
+provide one or more Interface(s). The inclusion of these Grok base
+classes in your own class inheritance automatically handles the
+component registration with the Zope Component Architecture. This process of
+introspecting your Grok code during initialization and wiring together
+components based on common conventions that you follow in the structure
+of your source code is called "grokking".
+
+Core components
+~~~~~~~~~~~~~~~
+
+
+
+:class:`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 :class:`grok.Container` and :class:`grok.Model` object
+instances.
+
+.. autoclass:: grok.Application
+   :members:
+
+
+:class:`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 Database (ZODB).
+
+.. autoclass:: grok.Model
+   :members:
+
+    .. attribute:: __parent__
+
+       The parent in the location hierarchy.
+
+       If you recursively follow the :attr:`__parent__` attribute, you
+       will always reach a reference to a top-level grok.Application
+       object instance.
+
+    .. attribute:: __name__
+
+        The name within the parent.
+
+        Traverse the parent with this name to get the object.
+
+        Name in Grok means "human-readable identifier" as the
+        :attr:`__name__` attribute is used to reference the object
+        within an URL.
+
+
+:class:`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.container.interfaces.IContainer interface using a BTree, providing
+reasonable performance for large collections of objects.
+
+.. autoclass:: grok.Container
+
+    .. attribute:: __parent__
+
+       The parent in the location hierarchy.
+
+       If you recursively follow the :attr:`__parent__` attribute, you
+       will always reach a reference to a top-level grok.Application
+       object instance.
+
+    .. attribute:: __name__
+
+        The name within the parent.
+
+        Traverse the parent with this name to get the object.
+
+        Name in Grok means "human-readable identifier" as the
+        :attr:`__name__` attribute is used to reference the object
+        within an URL.
+
+    .. method:: items(key=None)
+
+        Return an iterator over the key-value pairs in the container.
+
+        If ``None`` is passed as `key`, this method behaves as if no argument
+        were passed.
+
+        If `key` is in the container, the first item provided by the iterator
+        will correspond to that key.  Otherwise, the first item will be for
+        the key that would come next if `key` were in the container.
+
+    .. method:: keys(key=None)
+
+        Return an iterator over the keys in the container.
+
+        If ``None`` is passed as `key`, this method behaves as if no argument
+        were passed.
+
+        If `key` is in the container, the first key provided by the iterator
+        will be that key.  Otherwise, the first key will be the one that would
+        come next if `key` were in the container.
+
+    .. method:: values(key=None)
+
+        Return an iterator over the values in the container.
+
+        If ``None`` is passed as `key`, this method behaves as if no argument
+        were passed.
+
+        If `key` is in the container, the first value provided by the iterator
+        will correspond to that key.  Otherwise, the first value will be for
+        the key that would come next if `key` were in the container.
+
+
+    .. method:: __getitem__(key)
+
+        Get a value for a key
+
+        A KeyError is raised if there is no value for the key.
+
+    .. method:: get(key, default=None)
+
+        Get a value for a key
+
+        The default is returned if there is no value for the key.
+
+    .. method:: __contains__(key)
+
+        Tell if a key exists in the mapping.
+
+
+    .. method:: __iter__()
+
+        Return an iterator for the keys of the mapping object.
+
+    .. method:: values()
+
+        Return the values of the mapping object.
+
+    .. method:: items()
+
+        Return the items of the mapping object.
+
+    .. method:: __len__()
+
+        Return the number of items.
+
+    .. method:: has_key(key)
+
+        Tell if a key exists in the mapping.
+
+    .. method:: __setitem__(name, object)
+
+        Add the given `object` to the container under the given name.
+
+        Raises a ``TypeError`` if the key is not a unicode or ascii string.
+        Raises a ``ValueError`` if key is empty.
+
+        The container might choose to add a different object than the
+        one passed to this method.
+
+        If the object doesn't implement `IContained`, then one of two
+        things must be done:
+
+        1. If the object implements `ILocation`, then the `IContained`
+           interface must be declared for the object.
+
+        2. Otherwise, a `ContainedProxy` is created for the object and
+           stored.
+
+        The object's `__parent__` and `__name__` attributes are set to the
+        container and the given name.
+
+        If the old parent was ``None``, then an `IObjectAddedEvent` is
+        generated, otherwise, an `IObjectMovedEvent` is generated.  An
+        `IContainerModifiedEvent` is generated for the container.
+
+        If the object replaces another object, then the old object is
+        deleted before the new object is added, unless the container
+        vetos the replacement by raising an exception.
+
+        If the object's `__parent__` and `__name__` were already set to
+        the container and the name, then no events are generated and
+        no hooks.  This allows advanced clients to take over event
+        generation.
+
+    .. method:: __delitem__(name)
+
+        Delete the named object from the container.
+
+        Raises a ``KeyError`` if the object is not found.
+
+        If the deleted object's `__parent__` and `__name__` match the
+        container and given name, then an `IObjectRemovedEvent` is
+        generated and the attributes are set to ``None``. If the object
+        can be adapted to `IObjectMovedEvent`, then the adapter's
+        `moveNotify` method is called with the event.
+
+        Unless the object's `__parent__` and `__name__` attributes were
+        initially ``None``, generate an `IContainerModifiedEvent` for the
+        container.
+
+        If the object's `__parent__` and `__name__` were already set to
+        ``None``, then no events are generated.  This allows advanced
+        clients to take over event generation.
+
+
+**Example 1: Perform Create, Read, Update and Delete (CRUD) on a container**
+
+.. code-block:: python
+
+    # define a container and a model and then create them
+    class BoneBag(grok.Container): pass
+    class Bone(grok.Model): pass
+    bag = BoneBag()
+    skull = Bone()
+
+    # ... your classes are then "grokked" by Grok ...
+
+    # store an object in a container
+    bag['bone1'] = skull
+
+    # test for containment
+    bag.has_key('bone1')
+
+    # retrieve an object from a container
+    first_bone = bag['bone1']
+
+    # iterate through objects in a container with .values()
+    # you can also use .keys() and .items()
+    for bone in bag.values():
+        bone.marks = 'teeth'
+
+    # delete objects using the del keyword
+    del bag['bone1']
+
+
+:class:`grok.OrderedContainer`
+==============================
+
+OrderedContainers act just like Containers, but also support the ability
+to maintain order on the items within the container. This implementation
+maintains a persistent list of keys on a private attribute, so it's
+important to note that OrderedContainers will have poorer performance than
+a normal Container.
+
+.. autoclass:: grok.OrderedContainer
+   :members:
+
+
+Indexes
+~~~~~~~
+
+:class:`grok.Indexes`
+=====================
+
+:class:`Indexes` are local utilities for holding a set of indexes
+alongside a :class:`grok.Site` or :class:`grok.Application`. An index
+is a data structure that provides a way of quickly finding certain
+types of objects, i.e. it provides catalog functionality for
+attributes/contents of stored objects.
+
+.. autodata:: grok.Indexes
+
+    **Directives:**
+
+    :func:`grok.context(context_obj_or_interface)`
+        Required. Identifies the type of objects that should be
+        catalogued. The ``context`` type can also be set module-wide.
+
+        .. seealso::
+
+            :func:`grok.context`
+
+    :func:`grok.site(application_type_or_interface)`
+        Required. Identifies the type of site or application in which
+        objects should be catalogued.
+
+        .. seealso::
+
+            :func:`grok.site`
+
+
+Grok Index Definitions
+======================
+
+.. automodule:: grok.index
+   :members:
+   :inherited-members:
+   :undoc-members:
+
+**Example 1: Index the Mammoths in a Herd**
+
+Imagine you have a herd of mammoths, and you wish to quickly find a
+mammoth based on their last name. First we will create a simple Grok
+application that defines a Herd and some Mammoths:
+
+.. code-block:: python
+
+    import grok
+    import grok.index
+    import zope.interface
+    import zope.schema
+
+    class Herd(grok.Container, grok.Application):
+        pass
+
+    class IMammoth(zope.interface.Interface):
+        full_name = zope.schema.TextLine(title=u'Full Name')
+
+    class MammothIndexes(grok.Indexes):
+        grok.site(Herd)
+        grok.context(IMammoth)
+
+        full_name = grok.index.Text()
+
+    class Mammoth(grok.Model):
+        grok.implements(IMammoth)
+
+        def __init__(self, full_name):
+            self.full_name = full_name
+
+We can now create a Herd application, add some Mammoths to the Herd, and
+query for those Mammoths by their last name.
+
+Imagine ``root`` is our ZODB root as provided for instance by a
+debugger::
+
+    >>> herd = Herd()
+    >>> root['herd'] = herd   # <-- the indexes are created here
+
+We manually set the 'site' to search. This happens automatically when
+we do for instance regular browser requests::
+
+    >>> from zope.site.hooks import setSite
+    >>> setSite(herd)
+
+Populate the herd::
+
+    >>> herd['one'] = Mammoth('Manfred Mammoth')
+    >>> herd['two'] = Mammoth('Joe Mammoth')
+    >>> herd['three'] = Mammoth('Marty the Wooly')
+
+Search the herd::
+
+    >>> import zope.component
+    >>> from zope.catalog.interfaces import ICatalog
+    >>> catalog = zope.component.getUtility(ICatalog)
+    >>> mammoths = catalog.searchResults(full_name='Mammoth')
+
+``mammoths`` would be a list containing ``'Manfred Mammoth'`` and
+``'Joe Mammoth'`` but not ``'Marty the Wooly'``
+
+
+Adapters
+~~~~~~~~
+
+.. currentmodule:: grok
+
+:class:`grok.Adapter`
+=====================
+
+An Adapter takes an object providing an existing interface and extends
+it to provide a new interface.
+
+The object providing the existing interface is passed to the Adapter
+in the constructor, and is stored in an attribute named 'context.
+The source code for the `grok.Adapter` base class is simply:
+
+.. code-block:: python
+
+    class Adapter(object):
+        def __init__(self, context):
+            self.context = context
+
+.. autoclass:: grok.Adapter
+   :members:
+
+    .. The Adapter class itself does not provide docstrings.
+
+    Base class to define an adapter. Adapters are automatically
+    registered when a module is "grokked".
+
+    .. attribute:: context
+
+        The adapted object.
+
+    **Directives:**
+
+    :data:`grok.context(context_obj_or_interface)`
+        Maybe required. Identifies the type of objects or interface for
+        the adaptation.
+
+    .. seealso::
+
+        :func:`grok.context`
+
+    :data:`grok.implements(\*interfaces)`
+        Required. Identifies the interface(s) the adapter implements.
+
+    .. seealso::
+
+        :func:`grok.implements`
+
+    :data:`grok.name(name)`
+        Optional. Identifies the name used for the adapter
+        registration. If ommitted, no name will be used.
+
+        When a name is used for the adapter registration, the adapter
+        can only be retrieved by explicitely using its name.
+
+    .. seealso::
+
+        :func:`grok.name`
+
+    :func:`grok.provides(name)`
+        Maybe required.
+
+    .. seealso::
+
+        :func:`grok.provides`
+
+
+**Example 1: Simple adaptation example**
+
+.. code-block:: python
+
+    import grok
+    from zope import interface
+
+    class Cave(grok.Model):
+        "Cave is the class being adapted (the adaptee)"
+
+        def __init__(self, size=100):
+            self.size = size
+
+    class IHome(interface.Interface):
+        "IHome is the interface we want to add to a Cave"
+
+        def renovate():
+            "Enlarge Cave"
+
+    class CaveHome(grok.Adapter):
+        "Turns a Cave into a Home"
+        grok.context(Cave)
+        grok.implements(IHome) # the new interface provided by the adapter
+
+        def renovate(self):
+            # the adaptee is an attribute named 'context'
+            # and is passed in to the constructor
+            self.context.size += 10
+
+    # Adapation (component look-up) is invoked by passing the adaptee
+    # to the interface as a constructor and returns the component adapted to
+    home = IHome(cave)
+    home.renovate()
+
+    # Multiple adapters can exist that adapt and provide the same interfaces.
+    # They can be distinguished by name.
+
+    import zope.component
+
+    class LargeCaveHome(grok.Adapater):
+        "Turns a Cave in a large Home"
+        grok.context(Cave)
+        grok.implements(IHome)
+        grok.name('largehome')
+
+        def renovate(self):
+            self.context.size += 200
+
+    largehome = zope.component.getAdapter(cave, IHome, name='largehome')
+    largehome.renovate()
+
+:class:`grok.MultiAdapter`
+==========================
+
+A MultiAdapter takes multiple objects providing existing interface(s)
+and extends them to provide a new interface.
+
+The :class:`grok.MultiAdapter` base class does not provide a default
+constructor implementation, it's up to the individual multi-adapters
+to determine how to handle the objects being adapted.
+
+.. autoclass:: grok.MultiAdapter
+   :members:
+
+    Base class to define a Multi Adapter.
+
+    **Directives:**
+
+    :data:`grok.adapts(\*objects_or_interfaces)`
+        Required. Identifies the combination of types of objects or interfaces
+        for the adaptation.
+
+    :data:`grok.implements(\*interfaces)`
+        Required. Identifies the interfaces(s) the adapter implements.
+
+    :data:`grok.name(name)`
+        Optional. Identifies the name used for the adapter registration. If
+        ommitted, no name will be used.
+
+        When a name is used for the adapter registration, the adapter
+        can only be retrieved by explicitely using its name.
+
+    :data:`grok.provides(name)`
+        Only required if the adapter implements more than one
+        interface.  :func:`grok.provides` is required to disambiguate
+        for which interface the adapter will be registered for.
+
+**Example: A home is made from a cave and a fireplace.**
+
+.. code-block:: python
+
+    import grok
+    import zope.component
+    import zope.interface
+
+    class Fireplace(grok.Model): pass
+    class Cave(grok.Model): pass
+    class IHome(zope.interface.Interface): pass
+
+    class Home(grok.MultiAdapter):
+        grok.adapts(Cave, Fireplace)
+        grok.implements(IHome)
+
+        def __init__(self, cave, fireplace):
+            self.cave = cave
+            self.fireplace = fireplace
+
+    home = zope.component.getMultiAdapter((cave, fireplace), IHome)
+
+**Example: A Grok View is a MultiAdapter**
+
+In Grok, MultiAdapters are most commonly encountered in the form of
+Views. A View is a MultiAdapter which adapts the `request` and the
+`context` to provide the `IGrokView` interface. You can lookup a
+View component using the `getMultiAdapter` function.
+
+.. code-block:: python
+
+    class FireplaceView(grok.View):
+        grok.context(Fireplace)
+        grok.name('fire-view')
+
+    class AlternateFireplaceView(grok.View):
+        grok.context(Fireplace)
+
+        def render(self):
+            fireplaceview = zope.component.getMultiAdapter(
+                (self.context, self.request), IGrokView, name='fire-view'
+            )
+            return fireplaceview.render()
+
+
+:class:`grok.Annotation`
+========================
+
+Annotation components are persistent writeable adapters.
+
+.. autoclass:: grok.Annotation
+   :members:
+
+   Inherits from the :class:`persistent.Persistent` class.
+
+
+**Example: Storing annotations on model objects**
+
+.. code-block:: python
+
+    import grok
+    from zope import interface
+
+    # Create a model and an interface you want to adapt it to
+    # and an annotation class to implement the persistent adapter.
+    class Mammoth(grok.Model):
+        pass
+
+    class ISerialBrand(interface.Interface):
+        unique = interface.Attribute("Brands")
+
+    class Branding(grok.Annotation):
+        grok.implements(IBranding)
+        unique = 0
+
+    # Grok the above code, then create some mammoths
+    manfred = Mammoth()
+    mumbles = Mammoth()
+
+    # creating Annotations work just like Adapters
+    livestock1 = ISerialBrand(manfred)
+    livestock2 = ISerialBrand(mumbles)
+
+    # except you can store data in them, this data will transparently persist
+    # in the database for as long as the object exists
+    livestock1.unique = 101
+    livestock2.unique = 102
+
+    # attributes not listed in the interface will also be persisted
+    # on the annotation
+    livestock2.foo = "something"
+
+Utilities
+~~~~~~~~~
+
+:class:`grok.GlobalUtility`
+===========================
+
+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.
+
+Examples of global utilities are database connections, XML parsers,
+and web service proxies.
+
+.. autoclass:: grok.GlobalUtility
+   :members:
+
+    Base class to define a globally registered utility. Global utilities are
+    automatically registered when a module is "grokked".
+
+    **Directives:**
+
+    :data:`grok.implements(\*interfaces)`
+        Required. Identifies the interfaces(s) the utility implements.
+
+    :data:`grok.name(name)`
+        Optional. Identifies the name used for the adapter registration. If
+        ommitted, no name will be used.
+
+        When a name is used for the global utility registration, the global
+        utility can only be retrieved by explicitely using its name.
+
+    :data:`grok.provides(name)`
+        Maybe required. If the global utility implements more than one
+        interface, :func:`grok.provides` is required to disambiguate
+        for what interface the global utility will be registered.
+
+
+:class:`grok.LocalUtility`
+==========================
+
+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.
+
+An example is for database connections or web service proxies,
+where you need to dynamically provide the connection settings
+so that they can be edited through-the-web.
+
+.. autoclass:: grok.LocalUtility
+   :members:
+
+    Defines utilities that will be registered local to a
+    :class:`grok.Site` or :class:`grok.Application` object by using
+    the :func:`grok.local_utility` directive.
+
+    **Directives:**
+
+    :data:`grok.implements(\*interfaces)`
+        Optional. Identifies the interfaces(s) the utility implements.
+
+    :data:`grok.name(name)`
+        Optional. Identifies the name used for the adapter registration. If
+        ommitted, no name will be used.
+
+        When a name is used for the local utility registration, the
+        local utility can only be retrieved by explicitely using its
+        name.
+
+    :data:`grok.provides(name)`
+        Maybe required. If the local utility implements more than one
+        interface or if the implemented interface cannot be
+        determined, :func:`grok.provides` is required to disambiguate
+        for what interface the local utility will be registered.
+
+  	.. seealso::
+
+	    Local utilities need to be registered in the context of
+	    :class:`grok.Site` or :class:`grok.Application` using the
+	    :func:`grok.local_utility` directive.
+
+:class:`grok.Site`
+==================
+
+Contains a Site Manager. Site Managers act as containers for registerable
+components.
+
+If a Site Manager is asked for an adapter or utility, it checks for those
+it contains before using a context-based lookup to find another site
+manager to delegate to. If no other site manager is found they defer to
+the global site manager which contains file based utilities and adapters.
+
+.. autoclass:: grok.Site
+   :members:
+
+    .. automethod:: grok.Site.getSiteManager()
+
+        Returns the site manager contained in this object.
+
+        If there isn't a site manager, raise a component lookup.
+
+    .. automethod:: grok.Site.setSiteManager(sitemanager)
+
+        Sets the site manager for this object.
+
+Views
+~~~~~
+
+:class:`grok.View`
+==================
+
+Views handle interactions between the user and the model. The are
+constructed with context and request attributes, are responsible for
+providing a response. The request attribute in a View will always be
+for a normal HTTP Request.
+
+The determination of what :class:`View` gets used for what
+:class:`Model` is made by walking the URL in the HTTP Request object
+sepearted by the ``/`` character. This process is called "Traversal".
+
+.. autoclass:: grok.View
+
+    .. attribute:: context
+
+        The object that the view is presenting. This is often an instance of
+        a grok.Model class, but can be a grok.Application, grok.Container
+        object or any type of Python object.
+
+    .. attribute:: request
+
+        The HTTP Request object.
+
+    .. autoattribute:: grok.View.response
+
+        The HTTP Response object that is associated with the request.
+
+        This is also available as ``self.request.response``, but the
+        response attribute is provided as a convenience.
+
+    .. attribute:: static
+
+        Directory resource containing the static files of the view's
+        package.
+
+    .. autoattribute:: grok.View.body
+
+        Get the body of the associated request.
+
+    .. automethod:: grok.View.redirect
+
+        Redirect to `url`.
+
+        The headers of the :attr:`response` are modified so that the
+        calling browser gets a redirect status code. Please note, that
+        this method returns before actually sending the response to
+        the browser.
+
+        `url` is a string that can contain anything that makes sense
+        to a browser. Also relative URIs are allowed.
+
+        `status` is a number representing the HTTP status code sent
+        back. If not given or ``None``, ``302`` or ``303`` will be
+        sent, depending on the HTTP protocol version in use (HTTP/1.0
+        or HTTP/1.1).
+
+        `trusted` is a boolean telling whether we're allowed to
+        redirect to 'external' hosts. Normally redirects to other
+        hosts than the one the request was sent to are forbidden and
+        will raise a :exc:`ValueError`.
+
+     .. automethod:: grok.View.url
+
+        If no arguments given, construct URL to view itself.
+
+        If only obj argument is given, construct URL to obj.
+
+        If only name is given as the first argument, construct URL
+        to context/name.
+
+        If both object and name arguments are supplied, construct
+        URL to obj/name.
+
+     .. automethod:: grok.View.default_namespace
+
+        Returns a dictionary of namespaces that the template
+        implementation expects to always be available.
+
+        This method is *not* intended to be overridden by application
+        developers.
+
+     .. automethod:: grok.View.namespace
+
+        Returns a dictionary that is injected in the template
+        namespace in addition to the default namespace.
+
+        This method *is* intended to be overridden by the application
+        developer.
+
+     .. automethod:: grok.View.update
+
+        This method is meant to be implemented by :class:`grok.View`
+        subclasses.  It will be called *before* the view's associated
+        template is rendered and can be used to pre-compute values
+        for the template.
+
+        update() can take arbitrary keyword parameters which will be
+        filled in from the request (in that case they *must* be
+        present in the request).
+
+     .. automethod:: grok.View.render
+
+        A view can either be rendered by an associated template, or
+        it can implement this method to render itself from Python.
+        This is useful if the view's output isn't XML/HTML but
+        something computed in Python (plain text, PDF, etc.)
+
+        render() can take arbitrary keyword parameters which will be
+        filled in from the request (in that case they *must* be
+        present in the request).
+
+     .. automethod:: grok.View.application_url
+
+     .. automethod:: grok.View.flash
+
+
+
+:class:`grok.ViewletManager`
+============================
+
+A ViewletManager is a component that provides access to a set of
+content providers (Viewlets). The ViewletManager's responsibilities are:
+
+  * Aggregation of all viewlets registered for the manager.
+
+  * Apply a set of filters to determine the availability of the viewlets.
+
+  * Sort the viewlets based on some implemented policy. The default is to
+    numerically sort accoring to the `grok.order([number])` directive on a
+    Viewlet.
+
+  * Provide an environment in which the viewlets are rendered.
+
+  * Render itself containing the HTML content of the viewlets.
+
+ViewletManager's also implement a read-only mapping API, so the Viewlet's
+that they contain can be read like a normal Python dictionary.
+
+.. autoclass:: grok.ViewletManager
+
+   .. XXX: undocumented: sort(), filter(), get().
+
+   .. attribute:: context
+
+       Typically the Model object for which this ViewletManager is being
+       rendered in the context of.
+
+   .. attribute:: request
+
+       The Request object.
+
+   .. attribute:: view
+
+       Reference to the View that the ViewletManager is being provided
+       in.
+
+   .. automethod:: grok.ViewletManager.default_namespace
+
+       Returns a dictionary of namespaces that the template
+       implementation expects to always be available.
+
+       This method is *not* intended to be overridden by application
+       developers.
+
+   .. automethod:: grok.ViewletManager.namespace
+
+      Returns a dictionary that is injected in the template
+      namespace in addition to the default namespace.
+
+      This method *is* intended to be overridden by the application
+      developer.
+
+   .. automethod:: grok.ViewletManager.update
+
+      This method is called before the ViewletManager is rendered, and
+      can be used to perform pre-computation.
+
+   .. automethod:: grok.ViewletManager.render
+
+      This method renders the content provided by this ViewletManager.
+      Typically this will mean rendering and concatenating all of the
+      Viewlets managed by this ViewletManager.
+
+
+**Example: Register a ViewletManager and Viewlet and use them from a template for a View**
+
+This is a very simple example, ViewletManagers and Viewlets can be used to
+support more complex HTML layout use cases, such as discriminating on the
+view or context in which a particular ViewletManager will be rendered. For
+example, a web site about caves and herds might want to show information in
+the sidebar specific to either a cave or a herd, depending upon whether a page
+is displaying information about a cave or a herd.
+
+.. code-block:: python
+
+    class ViewForACave(grok.View):
+        def render():
+            return grok.PageTemplate("""
+            <html><body>
+                <div tal:content="structure provider:cave" />
+            </body></html>
+            """)
+
+    class CaveManager(grok.ViewletManager):
+        grok.view(ViewForACave)
+        grok.name('cave')
+
+    class CaveViewlet(grok.Viewlet):
+        grok.order(30)
+        grok.viewletmanager(CaveManager)
+
+        def render(self):
+            return "Cave"
+
+
+:class:`grok.Viewlet`
+=====================
+
+Viewlets are a flexible way to compound HTML snippets.
+
+Viewlets are typically used for the layout of the web site. Often all the
+pages of the site have the same layout with header, one or two columns, the
+main content area and a footer.
+
+.. autoclass:: grok.Viewlet
+   :members:
+
+    .. attribute:: context
+
+        Typically the Model object for which this Viewlet is being
+        rendered in the context of.
+
+    .. attribute:: request
+
+        The Request object.
+
+    .. attribute:: view
+
+        Reference to the View that the Viewlet is being provided in.
+
+    .. attribute:: viewletmanager
+
+        Reference to the ViewletManager that is rendering this Viewlet.
+
+    .. automethod:: grok.Viewlet.default_namespace
+
+        Returns a dictionary of namespaces that the template
+        implementation expects to always be available.
+
+        This method is *not* intended to be overridden by application
+        developers.
+
+    .. automethod:: grok.Viewlet.namespace
+
+       Returns a dictionary that is injected in the template
+       namespace in addition to the default namespace.
+
+       This method *is* intended to be overridden by the application
+       developer.
+
+    .. automethod::  grok.Viewlet.update
+
+        This method is called before the Viewlet is rendered, and
+        can be used to perfrom pre-computation.
+
+    .. automethod:: grok.Viewlet.render
+
+        This method renders the content provided by this Viewlet.
+
+
+:class:`grok.JSON`
+==================
+
+Specialized View that returns data in JSON format.
+
+Python data returned is automatically converted into JSON format using
+the simplejson library. Every method name in a grok.JSON component is
+registered as the name of a JSON View. The exceptions are names that
+begin with an _ or special names such as __call__. The grok.require
+decorator can be used to protect methods with a permission.
+
+.. autoclass:: grok.JSON
+
+    .. attribute:: context
+
+        Object that the JSON handler presents.
+
+    .. attribute:: request
+
+        Request that JSON handler was looked up with.
+
+    .. autoattribute:: response
+
+        The response sent back to the client.
+
+    .. attribute:: body
+
+        The text of the request body.
+
+    .. automethod:: redirect
+
+        Redirect to `url`.
+
+        The headers of the :attr:`response` are modified so that the
+        calling browser gets a redirect status code. Please note, that
+        this method returns before actually sending the response to
+        the browser.
+
+        `url` is a string that can contain anything that makes sense
+        to a browser. Also relative URIs are allowed.
+
+        `status` is a number representing the HTTP status code sent
+        back. If not given or ``None``, ``302`` or ``303`` will be
+        sent, depending on the HTTP protocol version in use (HTTP/1.0
+        or HTTP/1.1).
+
+        `trusted` is a boolean telling whether we're allowed to
+        redirect to 'external' hosts. Normally redirects to other
+        hosts than the one the request was sent to are forbidden and
+        will raise a :exc:`ValueError`.
+
+    .. automethod:: url
+
+    .. automethod:: publishTraverse
+
+        Lookup a name and return an object with `self.context` as its parent.
+        The method can use the request to determine the correct object.
+
+        The `request` argument is the publisher request object. The
+        `name` argument is the name that is to be looked up. It must
+        be an ASCII string or Unicode object.
+
+        If a lookup is not possible, raise a :exc:`NotFound` error.
+
+    .. automethod:: browserDefault
+
+        Returns an object and a sequence of names.
+
+        The publisher calls this method at the end of each traversal path.
+        If the sequence of names is not empty, then a traversal step is made
+        for each name. After the publisher gets to the end of the sequence,
+        it will call browserDefault on the last traversed object.
+
+        The default behaviour in Grok is to return `self.context` for
+        the object and ``'index'`` for the default view name.
+
+        Note that if additional traversal steps are indicated (via a
+        nonempty sequence of names), then the publisher will try to adjust
+        the base href.
+
+
+**Example 1: Create a public and a protected JSON view.**
+
+.. code-block:: python
+
+    class MammothJSON(grok.JSON):
+        """
+        Returns JSON from URLs in the form of:
+
+        http://localhost/stomp
+        http://localhost/dance
+        """
+
+        grok.context(zope.interface.Interface)
+
+        def stomp(self):
+            return {'Manfred stomped.': ''}
+
+        @grok.require('zope.ManageContent')
+        def dance(self):
+            return {'Manfred does not like to dance.': ''}
+
+
+:class:`grok.REST`
+==================
+
+Specialized View for making web services that conform to the REST style.
+These Views can define methods named GET, PUT, POST and DELETE, which will
+be invoked based on the Request type.
+
+.. autoclass:: grok.REST
+
+    .. attribute:: context
+
+        Object that the REST handler presents.
+
+    .. attribute:: request
+
+        Request that REST handler was looked up with.
+
+    .. autoattribute:: response
+
+        The response sent back to the client.
+
+    .. autoattribute:: body
+
+        The text of the request body.
+
+    .. automethod:: url
+
+    .. automethod:: redirect
+
+        Redirect to `url`.
+
+        The headers of the :attr:`response` are modified so that the
+        calling browser gets a redirect status code. Please note, that
+        this method returns before actually sending the response to
+        the browser.
+
+        `url` is a string that can contain anything that makes sense
+        to a browser. Also relative URIs are allowed.
+
+        `status` is a number representing the HTTP status code sent
+        back. If not given or ``None``, ``302`` or ``303`` will be
+        sent, depending on the HTTP protocol version in use (HTTP/1.0
+        or HTTP/1.1).
+
+        `trusted` is a boolean telling whether we're allowed to
+        redirect to 'external' hosts. Normally redirects to other
+        hosts than the one the request was sent to are forbidden and
+        will raise a :exc:`ValueError`.
+
+
+:class:`grok.XMLRPC`
+====================
+
+Specialized View that responds to XML-RPC.
+
+.. autoclass:: grok.XMLRPC
+
+    .. attribute:: context
+
+        Object that the REST handler presents.
+
+    .. attribute:: request
+
+        Request that REST handler was looked up with.
+
+    .. autoattribute:: grok.XMLRPC.response
+
+        The response sent back to the client.
+
+    .. autoattribute:: grok.XMLRPC.body
+
+        The text of the request body.
+
+    .. automethod:: grok.XMLRPC.url
+
+    .. automethod:: grok.XMLRPC.redirect
+
+
+**Example 1: Create a public and a protected XML-RPC view.**
+
+The grok.require decorator can be used to protect methods with a permission.
+
+.. code-block:: python
+
+    import grok
+    import zope.interface
+
+    class MammothRPC(grok.XMLRPC):
+        grok.context(zope.interface.Interface)
+
+        def stomp(self):
+            return 'Manfred stomped.'
+
+        @grok.require('zope.ManageContent')
+        def dance(self):
+            return 'Manfred doesn\'t like to dance.'
+
+
+:class:`grok.Traverser`
+=======================
+
+A Traverser is used to map from a URL to an object being published (Model)
+and the View used to interact with that object.
+
+.. autoclass:: grok.Traverser
+
+    Override the :meth:`traverse` method to supply the desired custom
+    traversal behaviour.
+
+    .. attribute:: context
+
+        The object that is being traversed.
+
+    .. attribute:: request
+
+        The HTTP Request object.
+
+    .. automethod:: traverse
+
+        You must provide your own implementation of this method to do
+        what you want. If you return ``None``, Grok will use the
+        default traversal behaviour.
+
+    .. automethod:: browserDefault
+
+        Returns an object and a sequence of names.
+
+        The publisher calls this method at the end of each traversal path.
+        If the sequence of names is not empty, then a traversal step is made
+        for each name. After the publisher gets to the end of the sequence,
+        it will call browserDefault on the last traversed object.
+
+        The default behaviour in Grok is to return `self.context` for
+        the object and ``'index'`` for the default view name.
+
+        Note that if additional traversal steps are indicated (via a
+        nonempty sequence of names), then the publisher will try to adjust
+        the base href.
+
+    .. automethod:: publishTraverse
+
+        Lookup a name and return an object with `self.context` as its parent.
+        The method can use the request to determine the correct object.
+
+        The `request` argument is the publisher request object. The
+        `name` argument is the name that is to be looked up. It must
+        be an ASCII string or Unicode object.
+
+        If a lookup is not possible, raise a :exc:`NotFound` error.
+
+
+**Example 1: Traverse into a Herd Model and return a Mammoth Model**
+
+.. code-block:: python
+
+    import grok
+
+    class Herd(grok.Model):
+
+       def __init__(self, name):
+           self.name = name
+
+    class HerdTraverser(grok.Traverser):
+       grok.context(Herd)
+
+       def traverse(self, name):
+           return Mammoth(name)
+
+    class Mammoth(grok.Model):
+
+       def __init__(self, name):
+           self.name = name
+
+
+:class:`grok.PageTemplate`
+==========================
+
+Page Templates are the default templating system for Grok, they are an
+implementation of the Template Attribute Language (TAL). Page Templates
+are typically created from a string.
+
+.. code-block:: python
+
+    grok.PageTemplate("<h1>Hello World!</h1>")
+
+.. autoclass:: grok.PageTemplate
+
+    .. automethod:: grok.PageTemplate._initFactory
+
+        Template language specific initializations on the view factory.
+
+    .. automethod:: grok.PageTemplate.render
+
+        Renders the template.
+
+    .. automethod:: grok.PageTemplate.setFromString
+
+    .. automethod:: grok.PageTemplate.setFromFilename
+
+    .. automethod:: grok.PageTemplate.getNamespace
+
+    .. automethod:: grok.PageTemplate.namespace
+
+
+:class:`grok.PageTemplateFile`
+==============================
+
+Creates a Page Template from a filename.
+
+.. code-block:: python
+
+    grok.PageTemplateFile("my_page_template.pt")
+
+.. autoclass:: grok.PageTemplateFile
+
+    .. automethod:: grok.PageTemplateFile._initFactory
+
+        Template language specific initializations on the view factory.
+
+    .. automethod:: grok.PageTemplateFile.render
+
+        Renders the template.
+
+    .. automethod:: grok.PageTemplateFile.setFromString
+
+    .. automethod:: grok.PageTemplateFile.setFromFilename
+
+    .. automethod:: grok.PageTemplateFile.getNamespace
+
+    .. automethod:: grok.PageTemplateFile.namespace
+
+
+
+Forms
+~~~~~
+
+Forms inherit from the :class:`grok.View` class. They are a specialized type of
+View that renders an HTML Form.
+
+:class:`grok.Form`
+==================
+
+.. autoclass:: grok.Form
+
+    .. attribute:: template
+
+        Template used to display the form
+
+    .. attribute:: context
+
+        The object for which the form is rendered.
+
+    .. attribute:: prefix
+
+        Page-element prefix. All named or identified page elements in a
+        subpage should have names and identifiers that begin with a subpage
+        prefix followed by a dot.
+
+    .. automethod:: setPrefix
+
+        Update the subpage prefix
+
+    .. attribute:: label
+
+        A label to display at the top of a form.
+
+    .. attribute:: status
+
+        An update status message. This is normally generated by success or
+        failure handlers.
+
+    .. attribute:: errors
+
+        Sequence of errors encountered during validation.
+
+    .. attribute:: form_result
+
+        Return from action result method.
+
+    .. attribute:: form_reset
+
+        Boolean indicating whether the form needs to be reset.
+
+    .. attribute:: form_fields
+
+        The form's form field definitions.
+
+        This attribute is used by many of the default methods.
+
+    .. attribute:: widgets
+
+        The form's widgets.
+
+        - set by :meth:`setUpWidgets`
+
+        - used by :meth:`validate`
+
+    .. autoattribute:: actions
+
+    .. autoattribute:: body
+
+        The text of the request body.
+
+    .. autoattribute:: response
+
+        The response sent back to the client.
+
+    .. automethod:: setUpWidgets
+
+        Set up the form's widgets.
+
+        The default implementation uses the form definitions in the
+        :attr:`form_fields` attribute and :meth:`setUpInputWidgets`.
+
+        The function should set the :attr:`widgets` attribute.
+
+    .. automethod:: validate
+
+        The default form validator
+
+        If an action is submitted and the action doesn't have it's own
+        validator then this function will be called.
+
+    .. automethod:: resetForm
+
+        Reset any cached data because underlying content may have changed.
+
+    .. automethod:: grok.Form.error_views
+
+        Return views of any errors.
+
+        The errors are returned as an iterable.
+
+    .. automethod:: applyData
+
+        Save form data to an object.
+
+        This returns a dictionary with interfaces as keys and lists of
+        field names as values to indicate which fields in which
+        schemas had to be changed in order to save the data.  In case
+        the method works in update mode (e.g. on EditForms) and
+        doesn't have to update an object, the dictionary is empty.
+
+    .. automethod:: application_url
+
+    .. automethod:: applyChanges
+
+        .. deprecated:: 0.13
+           Use :meth:`applyData` instead.
+
+    .. automethod:: availableActions
+
+    .. automethod:: browserDefault
+
+    .. automethod:: default_namespace
+
+    .. automethod:: flash
+
+    .. automethod:: namespace
+
+    .. automethod:: publishTraverse
+
+    .. automethod:: redirect
+
+    .. automethod:: render
+
+    .. automethod:: update
+
+    .. automethod:: update_form
+
+    .. automethod:: url
+
+
+:class:`grok.AddForm`
+=====================
+
+Add forms are used for creating new objects. The widgets for this form
+are not bound to any existing content or model object.
+
+.. autoclass:: grok.AddForm
+   :members:
+   :undoc-members:
+
+   Inherits from :class:`grok.Form`.
+
+
+:class:`grok.EditForm`
+======================
+
+Edit forms are used for editing existing objects. The widgets for this form
+are bound to the object set in the `context` attribute.
+
+.. autoclass:: grok.EditForm
+   :members:
+   :undoc-members:
+
+   Inherits from :class:`grok.Form`.
+
+
+:class:`grok.DisplayForm`
+=========================
+
+Display forms are used to display an existing object. The widgets for this
+form are bound to the object set in the `context` attribute.
+
+.. autoclass:: grok.DisplayForm
+   :members:
+   :undoc-members:
+
+   Inherits from :class:`grok.Form`.
+
+
+Security
+~~~~~~~~
+
+:class:`grok.Permission`
+========================
+
+Permissions are used to protect Views so that they can only be called
+by an authenticated principal. If a View in Grok does not have a
+:func:`grok.require` directive declaring a permission needed to use
+the View, then the default anonymously viewable `zope.View` permission
+used.
+
+.. autoclass:: grok.Permission
+
+    Base class for permissions. You must specify a unique name for
+    every permission using the :func:`grok.name` directive. The convention
+    for ensuring uniqueness is to prefix your permission name with the
+    name of your Grok package followed by a dot,
+    e.g. ``'mypackage.MyPermissionName'``.
+
+    .. attribute:: id
+
+        Id as which this permission will be known and used. This is set
+        to the value specified in the :func:`grok.name` directive.
+
+    .. attribute:: title
+
+        Human readable identifier for this permission.
+
+    .. attribute:: description
+
+        Description of the permission.
+
+    **Directives:**
+
+    :data:`grok.name(name)`
+
+        Required. Identifies the unique name (also used as the id) of the
+        permission.
+
+    :data:`grok.title(title)`
+
+        Optional. Stored as the title attribute for this permission.
+
+    :data:`grok.description(description)`
+
+        Optional. Stored as the description attribute for this permission.
+
+
+**Example 1: Define a new Permission and use it to protect a View**
+
+.. code-block:: python
+
+    import grok
+    import zope.interface
+
+    class Read(grok.Permission):
+        grok.name('mypackage.Read')
+
+    class Index(grok.View):
+        grok.context(zope.interface.Interface)
+        grok.require('mypackage.Read')
+
+
+:class:`grok.Role`
+==================
+
+Roles provide a way to group together a collection of permissions. Principals
+(aka Users) can be granted a Role which will allow them to access all Views
+protected by the Permissions that the Role contains.
+
+.. autoclass:: grok.Role
+   :members:
+   :inherited-members:
+   :undoc-members:
+
+   .. attribute:: id
+
+       Id as which this role will be known and used. This is set
+       to the value specified in the :func:`grok.name` directive.
+
+   .. attribute:: title
+
+       Human readable identifier for this permission.
+
+   .. attribute:: description
+
+       Description of the permission.
+
+   **Directives:**
+
+   :data:`grok.name(name)`
+
+       Required. Identifies the unique name (also used as the id) of the
+       role.
+
+   :data:`grok.permissions(permissions)`
+
+       Required. Declare the permissions granted to this role. These
+       can refer by permission class or by name.
+
+   :data:`grok.title(title)`
+
+       Optional. Stored as the title attribute for this role.
+
+   :data:`grok.description(description)`
+
+       Optional. Stored as the description attribute for this role.
+
+**Example 1: Define a new 'paint.Artist' Role and assign it to the 'paint.grok' principal**
+
+.. code-block:: python
+
+    import grok
+    import zope.interface
+
+    class ViewPermission(grok.Permission):
+        grok.name('paint.ViewPainting')
+
+    class EditPermission(grok.Permission):
+        grok.name('paint.EditPainting')
+
+    class ErasePermission(grok.Permission):
+        grok.name('paint.ErasePainting')
+
+    class ApprovePermission(grok.Permission):
+        grok.name('paint.ApprovePainting')
+
+    class Artist(grok.Role):
+        """
+        An Artist can view, create and edit paintings. However, they can
+        not approve their painting for display in the Art Gallery Cave.
+        """
+        grok.name('paint.Artist')
+        grok.title('Artist')
+        grok.description('An artist owns the paintings that they create.')
+        grok.permissions(ViewPermission, EditPermission, ErasePermission)
+        # alternatively, use permission names
+        # grok.permissions(
+        #    'paint.ViewPainting', 'paint.EditPainting', 'paint.ErasePainting')
+
+    class CavePainting(grok.View):
+        grok.context(zope.interface.Interface)
+        grok.require(ViewPermission)
+
+        def render(self):
+            return 'What a beautiful painting.'
+
+    class EditCavePainting(grok.View):
+        grok.context(zope.interface.Interface)
+        grok.require(EditPermission)
+
+        def render(self):
+            return 'Let\'s make it even prettier.'
+
+    class EraseCavePainting(grok.View):
+        grok.context(zope.interface.Interface)
+        grok.require(ErasePermission)
+
+        def render(self):
+            return 'Oops, mistake, let\'s erase it.'
+
+    class ApproveCavePainting(grok.View):
+        grok.context(zope.interface.Interface)
+        grok.require(ApprovePermission)
+
+        def render(self):
+            return 'Painting owners cannot approve their paintings.'
+
+    # The app variable will typically be your Application instance,
+    # but could also be a container within your application.
+    from zope.securitypolicy.interfaces import IPrincipalRoleManager
+    IPrincipalRoleManager(app).assignRoleToPrincipal(
+       'paint.Artist', 'paint.grok')

Added: groktoolkit/branches/jw-documentation-rearangement/doc/reference/conf.py
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/reference/conf.py	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/reference/conf.py	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,139 @@
+# -*- coding: utf-8 -*-
+#
+# Grok Reference documentation build configuration file, created by
+# sphinx-quickstart.py on Wed Feb 20 02:11:17 2008.
+#
+# 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).
+#
+# All configuration values have a default value; values that are commented out
+# show the default value as assigned to them.
+
+import sys
+
+#import os
+from os import path, curdir
+import re
+
+
+version = 'Unknown'
+setupfilepath = path.join(path.dirname(
+    path.dirname(path.abspath(curdir))), 'setup.py')
+reg = re.compile("^\s*version=.(.+).,.*")
+for line in open(setupfilepath, 'r').read().split():
+    m = reg.match(line)
+    if m:
+        version = m.groups()[0]
+
+
+
+
+# If your extensions are in another directory, add it here.
+#sys.path.append('some/directory')
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
+#extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+#templates_path = []
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'contents'
+
+# General substitutions.
+project = 'Grok Reference'
+copyright = '2006-2008, The Zope Foundation'
+
+# The default replacements for |version| and |release|, also used in various
+# other places throughout the built documents.
+#
+# The short X.Y version.
+version = version
+# The full version, including alpha/beta/rc tags.
+release = version
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+
+# Options for HTML output
+# -----------------------
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+html_use_smartypants = True
+
+# Content template for the index page, filename relative to this file.
+#html_index = ''
+
+# Custom sidebar templates, maps page names to filenames relative to this file.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# filenames relative to this file.
+#html_additional_pages = {}
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+#html_copy_source = True
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Grok Referencedoc'
+
+# 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 = 'default.css'
+
+# 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')]
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, document class [howto/manual]).
+#latex_documents = []
+latex_documents = [
+    ('reference.tex', 'Grok Reference', 'The Grok Team', 'manual')
+    ]
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = '
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []

Added: groktoolkit/branches/jw-documentation-rearangement/doc/reference/decorators.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/reference/decorators.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/reference/decorators.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,82 @@
+**********
+Decorators
+**********
+
+Grok uses a few decorators to register functions or methods for specific
+functionality.
+
+
+:func:`grok.subscribe` -- register a function as a subscriber for an event
+==========================================================================
+
+.. function:: subscribe(*classes_or_interfaces)
+
+    Declare that the decorated function subscribes to an event or a
+    combination of objects and events.
+
+    Applicable on module-level for functions. Requires at least one
+    class or interface as argument.
+
+
+:func:`grok.action` -- declare a form submit handler
+=====================================================
+
+.. function:: action(label, **options)
+
+    Decorator that defines an action factory based on a form
+    method. The method receives the form data as keyword
+    parameters.
+
+
+:func:`grok.require` -- protect a method with a permission
+==========================================================
+
+.. function:: require(name_or_class)
+
+    The decorated method will be protected by the permission. Used in
+    web service views such as REST or XML-RPC.
+
+
+:func:`grok.adapter/grok.implementer` -- declare an adapter factory
+====================================================================
+
+These decorators are always used in tandem to declare an adapter factory.
+
+.. function:: grok.adapter(*classes_or_interfaces) 
+
+    Describes that a function adapts an object or a combination
+    of objects.
+
+.. function:: grok.implementer(interface) 
+
+    Describes that a function that's used as an adapter
+    implements an interface or a number of interfaces.
+
+
+**Example 1: Adapt to an interface**
+
+.. code-block:: python
+
+	@grok.adapter(ICave)
+	@grok.implementer(IHome)
+	def home_for_cave(cave):
+	    return Home()
+
+**Example 2: Adapt a regular class instead of an interface**
+
+.. code-block:: python
+
+	@grok.adapter(Cave)
+	@grok.implementer(IHome)
+	def home_for_cave(cave):
+	    return Home()
+
+**Example 3: Declare a multi-adapter factory**
+
+.. code-block:: python
+
+	@grok.adapter(ICave, IFire)
+	@grok.implementer(ICozy)
+	def cozy_dwelling(cave, fire):
+	    return Dwelling()
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/reference/directives.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/reference/directives.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/reference/directives.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,657 @@
+
+**********
+Directives
+**********
+
+.. Here we document the generic behaviour of the module level and class level
+   directives. The context sensitive behaviour is described in the individual
+   component documentation. We do use specific example to illustrate the use
+   of the directives.
+
+The :mod:`grok` module defines a set of directives that allow you to configure
+and register your components. Most directives assume a default, based on the
+environment of a module. (For example, a view will be automatically associated
+with a model if the association can be made unambigously.)
+
+If no default can be assumed for a value, grok will explicitly tell you what
+is missing and how you can provide a default or explicit assignment for
+the value in question.
+
+Core directives
+~~~~~~~~~~~~~~~
+
+Core directives are applicable to any type of component.
+
+:func:`grok.name`
+=================
+
+Associate a component with a name.
+
+Name is a unique identifier in the form of a string. The names of
+Containers, Models and Views are used to compose the URLs of the application.
+
+.. function:: grok.name(name)
+
+    A class level directive used to associate a component with a single
+    name `name`.
+
+    Typically this directive is optional. The default behaviour when no
+    name is given depends on the component. The same applies to the
+    semantics of this directive: for what exactly a name is set when
+    using this directive, depends on the component.
+
+**Example: Specify the name of a View to make a more readable URL**
+
+A common use case is to have a URL for a view named differently than
+the name of the view class itself. In this example, the class is named
+`SomeView` but is accessible at an URL suffixed with `/index`.
+
+.. code-block:: python
+
+    import grok
+
+    class Mammoth(grok.Model):
+      pass
+
+    class SomeView(grok.View):
+       grok.name('index')
+
+
+.. seealso::
+
+    :class:`grok.Adapter`, :class:`grok.Annotation`,
+    :class:`grok.GlobalUtility`, :class:`grok.Indexes`,
+    :class:`grok.MultiAdapter`, :class:`grok.Role`,
+    :class:`grok.View`
+
+
+:func:`grok.title`
+==================
+
+Succint description.
+
+This directive is not commonly used, but along with :func:`grok.description`
+can help provide more information about a component.
+
+.. function:: grok.title(title)
+
+   A descriptive title for a component.
+
+
+:func:`grok.description`
+========================
+
+Longer description.
+
+This directive is not commonly used, but along with :func:`grok.title`
+can help provide more information about a component.
+
+.. function:: grok.description(description)
+
+  A longer description for a component.
+
+ 
+:func:`grok.implements`
+=======================
+
+Declare that a class implements an interface.
+
+.. function:: grok.implements(*interfaces)
+
+    A class level directive to declare one or more `interfaces`, as
+    implementers of the surrounding class.
+
+    This directive allows several parameters.
+
+    :func:`grok.implements` is currently an alias for
+    :func:`zope.interface.implements`.
+
+**Example: Create two Cave classes, one implements IPaintable the other does not**
+
+First we will create the IPaintable interface, which declares that objects
+which provide this interface will have a `paint()` method. We will make a
+plain `Cave` class as well:
+
+.. code-block:: python
+
+    import grok
+    from zope import interface
+    
+    class IPaintable(interface.Interface):
+        def paint(color):
+            "Paint with a color"
+
+    class Cave(object):
+        pass
+
+You can create a `Cave` object and query the `IPaintable` interface to see if
+an object provides that interface:
+
+.. code-block:: python
+
+    >>> cave = Cave()
+    >>> IPaintable.providedBy(cave)
+    False
+
+Next we will make a `PaintableCave` class which does implement the
+`IPaintable` interface:
+
+.. code-block:: python
+
+    class PaintableCave(object):
+        grok.implements(IPaintable)
+
+        def paint(color):
+            self._painted_color = color
+
+Now we can create a `PaintableCave` object and when we query the `IPaintable`
+interface it asserts that the object does provide the interface:
+    
+    >>> paintable_cave = PaintableCave()
+    >>> IPaintable.providedBy(paintable_cave)
+    True
+
+Note that interfaces, like all things in Python, are by nature of a 
+"gentleman's agreement". It's possible to declare that an object provides
+a certain interface when in reality it does not. It's also possible to
+provide magic methods such as `__getattr__` to allow an object to conform
+to a declared interface without that object needing to explicitly support
+the concrete methods and attributes declared in the interface. You can
+use the functions `zope.interface.verify.verifyClass(interface, class)`
+and `zope.interface.verify.verifyObject(interface, object)` to verify if
+a class or object actually implements or provides a specific interface.
+
+:func:`grok.provides`
+=====================
+
+Disambiguate which interface is registered.
+
+.. function:: grok.provides(interface)
+
+    Explicitly specify with which interface a component will be
+    looked up. If a class declares that it implements several interfaces,
+    :func:`grok.provides` can be used to disambiguate which interface will be
+    registered with the Zope Component Architecture.
+
+.. seealso::
+
+    :func:`grok.implements`
+
+
+:func:`grok.direct`
+===================
+
+Specify that the class should be the component.
+
+Typically a class implements an interface, and the class is used as a
+factory to construct objects that provide that interface. With this
+directive, the class object can by used to provide the interface
+directly without constructing additional instance objects.
+
+.. function:: grok.direct()
+
+    Specify whether the class should be used for the component
+    or whether it should be used to instantiate the component.
+
+    This directive can be used on GlobalUtility-based classes to
+    indicate whether the class itself should be registered as a
+    utility, or an instance of it.
+
+
+:func:`grok.baseclass`
+======================
+
+Declare a class as a base class.
+
+.. function:: grok.baseclass()
+
+    A class-level directive without argument to mark something as a base
+    class. Base classes are not grokked.
+
+    The baseclass mark is not inherited by subclasses, so those
+    subclasses will be grokked (except if they are also explicitly declared as
+    baseclasses as well).
+
+**Example: Mark a View class as a Base Class**
+
+Using this example, only the :class:`WorkingView` will serve as a
+view, while calling the :class:`AnotherView` will lead to a
+:exc:`ComponentLookupError`.
+
+.. code-block:: python
+
+    import grok
+
+    class ModelBase(grok.Model):
+        pass
+
+    class AnotherView(grok.View):
+        grok.baseclass()
+
+        def render(self):
+            return "hello world"
+
+    class WorkingView(grok.View):
+        pass
+
+
+Utility directives
+~~~~~~~~~~~~~~~~~~
+
+:func:`grok.global_utility`
+===========================
+
+Register a global utility.
+
+.. function:: grok.global_utility(factory[, provides=None[, name=u'']])
+
+    A module level directive to register a global utility.
+
+    `factory` - the factory that creates the utility.
+
+    `provides` - the interface the utility should be looked up with.
+
+    `name` - the name of the utility.
+
+    The latter two parameters are optional.
+
+    To register the utility correctly, Grok must be able to identify an
+    interface provided by the utility. If none is given, Grok checks
+    whether (exactly) one interface is implemented by the factory to be
+    registered (see example below). If more than one interface is
+    implemented by a class, use :func:`grok.provides` to specify which
+    one to use. If no interface is implemented by the instances
+    delivered by the factory, use :func:`grok.implements` to specify
+    one.
+
+    Another way to register global utilities with Grok is to subclass from
+    :class:`grok.GlobalUtility`.
+
+**Example: Register two GlobalUtilities and use them**
+
+Given the following module code:
+
+.. code-block:: python
+
+    import grok
+    from zope import interface
+
+    class IFireplace(interface.Interface):
+        pass
+
+    class Fireplace(object):
+        grok.implements(IFireplace)
+
+    grok.global_utility(Fireplace)
+    grok.global_utility(Fireplace, name='hot')
+
+Then the following works:
+
+.. code-block:: python
+
+    from zope import component
+    fireplace = component.getUtility(IFireplace)
+    hot_fireplace = component.getUtility(IFireplace, name='hot')
+
+.. seealso::
+
+    :class:`grok.GlobalUtility`, :func:`grok.provides`,
+    :func:`grok.implements`
+
+
+:func:`grok.local_utility`
+==========================
+
+Register a local utility.
+
+.. function:: grok.local_utility(factory[, provides=None[, name=u''[, setup=None[, public=False[, name_in_container=None]]]]])
+
+    A class level directive to register a local utility.
+
+    `factory` -- the factory that creates the utility.
+
+    `provides` -- the interface the utility should be looked up with.
+
+    `name` -- the name of the utility.
+
+    `setup` -- a callable that receives the utility as its single
+             argument, it is called after the utility has been created
+             and stored.
+
+    `public` -- if `False`, the utility will be stored below
+              `++etc++site`.  If `True`, the utility will be stored
+              directly in the site.  The site should in this case be a
+              container.
+
+    `name_in_container` -- the name to use for storing the utility.
+
+    All but the first parameter are optional.
+
+    To register a local utility correctly, Grok must know about the
+    interface, the utility should be looked up with. If none is given,
+    Grok looks up any interfaces implemented by instances delivered by
+    `factory` and if exactly one can be found, it is taken. See
+    :func:`grok.global_utility`.
+
+    Every single combination of interfaces and names can only be
+    registered once per module.
+
+    It is not possible to declare a local utility as public, if the site
+    is not a container. Grok will remind you of this. To store a utility
+    in a container, a `name_in_container` is needed. If none is given,
+    Grok will make up one automatically.
+
+    An alternative way to define a local utility is to subclass from
+    :class:`grok.LocalUtility`.
+
+**Example: Register a local utility**
+
+    The following code registers a local unnamed utility `fireplace` in
+    instances of :class:`Cave`
+
+    .. code-block:: python
+
+      import grok
+      from zope import interface
+
+      class IFireplace(interface.Interface):
+          pass
+
+      class Fireplace(grok.LocalUtility):
+          grok.implements(IFireplace)
+
+      class Cave(grok.Container, grok.Site):
+          grok.local_utility(Fireplace, public=True,
+                             name_in_container='fireplace')
+
+.. seealso::
+
+    :func:`grok.global_utility`, :class:`grok.LocalUtility`
+
+Adapter directives
+~~~~~~~~~~~~~~~~~~
+
+:func:`grok.context`
+====================
+
+Declare the context for views, adapters, etc.
+
+Adapters are composed from another object, this object is called the
+context object. This directive specifies the class or interface that
+this object must provide.
+
+If the context declaration is not supplied, then Grok will set the context
+to the an Application, Container or Model class in module, as long as there
+is only one class of that type in the module.
+
+.. function:: grok.context(*class_or_interface)
+
+    A class or module level directive to indicate the context for
+    something (class or module) in the same scope.
+
+    When used on module level, it will set the context for all views,
+    adapters, etc. in that module. When used on class level, it will set
+    the context for that particular class.
+
+    With Grok contexts are set automatically for some objects, if they are
+    unambigous. For example a :class:`grok.View` will get the only
+    :class:`grok.Application` or :class:`grok.Model` class as context,
+    iff there exists exactly one in the same module. If there are more
+    possible contexts or you want to set a type (class/interface) from
+    another module as context, than the one choosen by default, then you
+    have to call :func:`grok.context` explicitly.
+
+**Example: Declare a component depends upon a class or interface**
+
+Here the :func:`grok.context` directive indicates that the :class:`Index`
+View applies to the context of a :class:`Mammoth` instance, and not instances
+of :class:`Cave`. By declaring the class or interface with :func:`grok.context`
+for an object, you are stating that your object depends upon the methods
+and attributes of that context.
+
+.. code-block:: python
+
+    import grok
+
+    class Mammoth(grok.Model):
+        hair = 'Wooly'
+
+    class Cave(grok.Model):
+        texture = 'rough'
+
+    class Index(grok.View):
+        grok.context(Mammoth)
+
+        def render(self):
+            # self.context will always have the interface of a Mammoth object,
+            # since this view declares that it depends upon the context of a
+            # Mammoth class.
+            return "It feels %s" % self.context.hair
+
+.. seealso::
+
+    :class:`grok.View`, :class:`grok.Adapter`, :class:`grok.MultiAdapter`
+
+
+:func:`grok.adapts`
+===================
+
+Declare that a class adapts certain objects.
+
+In the case of a simple adapter which only requires a single object
+for adapation, the :func:`grok.context` directive is used to declare
+the interface or class the adapter is for. It is only necessary to use
+:func:`grok.adapts` to declare the adapation requirements for a multi adapter.
+
+.. function:: grok.adapts(*classes_or_interfaces)
+
+    A class-level directive to declare that a class adapts objects of
+    the classes or interfaces given in `\*classes_or_interfaces`.
+
+    This directive accepts several arguments.
+
+    It works much like the :mod:`zope.component.`:func:`adapts()`,
+    but you do not have to make a ZCML entry to register the adapter.
+
+
+Security directives
+~~~~~~~~~~~~~~~~~~~
+
+:func:`grok.require`
+====================
+
+Declare a permission.
+
+.. function:: grok.require(permission)
+
+A class level directive used to protect a View by requiring a
+certain permission.
+
+`permission` -- the class of the :class:`grok.Permission` subclass that
+                is required. Alternatively, the name of the permission that is
+                required
+
+
+**Example 1 Define a Permission and use it to protect a View, using permission class**
+
+.. code-block:: python
+
+    import grok
+    import zope.interface
+    
+    class Read(grok.Permission):
+        grok.name('mypackage.Read')
+
+    class Index(grok.View):
+        grok.context(zope.interface.Interface)
+        grok.require(Read)
+
+**Example 2: Define a Permission and use it to protect a View, using permission name**
+
+.. code-block:: python
+
+    import grok
+    import zope.interface
+    
+    class Read(grok.Permission):
+        grok.name('mypackage.Read')
+
+    class Index(grok.View):
+        grok.context(zope.interface.Interface)
+        grok.require('mypackage.Read')
+
+.. seealso::
+
+    :class:`grok.Permission` component, :func:`@grok.require` decorator
+
+
+Component registry directives
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:func:`grok.site`
+=================
+
+Specify the local component registry to use for indexes.
+
+A class level directive used in `grok.Indexes` sub-classes to define
+in which local component registry the indexes should be located.
+
+.. function:: grok.site(*arg)
+
+**Example**
+
+.. code-block:: python
+
+    class MammothIndexes(grok.Indexes):
+	grok.site(Herd)
+	grok.context(IMammoth)
+
+	name = index.Field()
+
+View directives
+~~~~~~~~~~~~~~~
+
+:func:`grok.layer`
+==================
+
+Declare the layer for the view.
+
+.. function:: grok.layer(layer)
+
+    Declare the layer for the view.
+
+    This directive acts as a contraint on the 'request' of
+    grok.View. This directive can only be used on class level.
+
+
+:func:`grok.skin`
+=================
+
+Declare this layer as a named skin.
+
+.. function:: grok.skin(skin)
+
+    Declare this layer as a named skin.
+
+    This directive can only be used on class level.
+
+
+:func:`grok.template`
+=====================
+
+Specify a template name.
+
+A class level directive used to specify the template to be rendered
+for the View when no render method is defined. This allows you to
+override the default convention of naming the template file with the same
+name as the view class itself, lowercased, in the templates directory
+for this module.
+
+.. function:: grok.template(template)
+
+    `template` -- name of the template file without file extension
+
+.. seealso::
+
+    :func:`grok.templatedir`
+
+
+:func:`grok.templatedir`
+========================
+
+Specify the templates directory.
+
+A module level directive used to specify the directory where Grok
+should look for template files.
+
+The default convention is to look for template files in a directory
+named `<module>_templates` where `<module>` is the name of the current
+module.
+
+.. function:: grok.templatedir(directory)
+
+    `directory` -- the name of the directory inside the same package
+                   as the module
+
+.. seealso::
+
+    :func:`grok.template`
+
+
+:func:`grok.order`
+==================
+
+Specify ordering of components.
+
+Ordering is typically used in Viewlets to determine the order in which 
+they are displayed.
+
+.. function:: grok.order(order)
+
+    Control the ordering of components.
+
+    If the value is specified, the order will be determined by sorting on it.
+    If no value is specified, the order will be determined by definition
+    order within the module. If the directive is absent, the order will be
+    determined by class name.
+
+    Inter-module order is by dotted name of the module the components are in,
+    unless an explicit argument is specified to ``grok.order()``, components are
+    grouped by module.
+
+The function grok.util.sort_components can be used to sort
+components according to these rules.
+
+
+URL Traversal directives
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+:func:`grok.traversable`
+========================
+
+Mark attributes or methods as traversable.
+
+A class level directive used to mark attributes or methods as traversable. An
+optional `name` argument can be used to give the attribute a different name in
+the URL.
+
+.. function:: grok.traversable(attr, name=None)
+
+**Example**
+
+.. code-block:: python
+
+  class Foo(grok.Model):
+      grok.traversable('bar')
+      grok.traversable('foo')
+      grok.traversable(attr='bar', name='namedbar')
+
+      def __init__(self, name):
+          self.name = name
+
+      foo = Bar('foo')
+      def bar(self):
+          return Bar('bar')
+
+The result is that you can now access http://localhost/foo/bar,
+http://localhost/foo/foo and http://localhost/foo/namedbar.

Added: groktoolkit/branches/jw-documentation-rearangement/doc/reference/events.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/reference/events.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/reference/events.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,412 @@
+
+******
+Events
+******
+
+Grok provides convenient access to a set of often-used events from
+Zope 3. Those events include object and containment events. All events
+are available as interface and implemented class.
+
+Subscription: Event interfaces
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+All events interfaces inherit from the base interface of IObjectEvent.
+
+.. class:: zope.component.interfaces.IObjectEvent
+
+    .. attribute:: object
+
+        The subject of the event taking place.
+
+:class:`IApplicationInitializedEvent`
+=====================================
+
+A Grok Application has been created with success and is now ready
+to be used.
+
+This event can be used to trigger the creation of contents or other tasks
+that require the application to be fully operational : utilities installed
+and indexes created in the catalog.
+
+.. class:: grok.IApplicationInitializedEvent
+
+    Interface to subscribe to application initialization.
+
+    .. attribute:: object
+
+        The application that has just been initialized.
+
+:class:`IObjectModifiedEvent`
+=============================
+
+An object has been modified. This is a general event that encompasses any
+change to a persistent object, such as adding, moving, copying, and removing
+of objects.
+
+.. class:: grok.IObjectModifiedEvent
+
+    Interface to subscribe to for object modifications.
+
+    .. attribute:: object
+
+        The subject of the event.
+
+    .. attribute:: descriptions
+
+        A list of descriptions of the modifications.
+
+:class:`IContainerModifiedEvent`
+================================
+
+The container has been modified. Container modifications is specific to
+addition, removal or reordering of sub-objects. Inherits from
+`grok.IObjectModifiedEvent`.
+
+.. class:: grok.IContainerModifiedEvent
+
+    Interface to subscribe to for container object modifications.
+
+    .. attribute:: object
+
+        The subject of the event.
+
+    .. attribute:: descriptions
+
+        A list of descriptions of the modifications.
+
+
+:class:`IObjectMovedEvent`
+==========================
+
+An object has been moved.
+
+.. class:: grok.IObjectMovedEvent
+
+   Interface to subscribe to for when an object is moved.
+
+   .. attribute:: object
+      
+      The subject of the event.
+   
+   .. attribute:: oldParent
+
+      The container stored in before moving.
+
+   .. attribute:: oldName
+
+      The name before moving.
+   
+   .. attribute:: newParent
+
+      The container stored in after moving.
+
+   .. attribute:: newName
+   
+      The name after moving.
+
+:class:`IObjectAddedEvent`
+==========================
+
+An object has been added to a container.
+
+.. class:: grok.IObjectAddedEvent
+
+   Interface to subscribe to for when an object is added to the database.
+   
+   Inherits from the `grok.IObjectMovedEvent` interface.
+
+   .. attribute:: object
+      
+      The subject of the event.
+   
+   .. attribute:: oldParent
+
+      The container stored in before moving.
+
+   .. attribute:: oldName
+
+      The name before moving.
+   
+   .. attribute:: newParent
+
+      The container stored in after moving.
+
+   .. attribute:: newName
+   
+      The name after moving.
+
+:class:`IObjectCopiedEvent`
+===========================
+
+An object has been copied.
+
+.. class:: grok.IObjectCopiedEvent
+
+   Interface to subscribe to for when an object is cloned.
+
+   Inherits from `grok.IObjectCreatedEvent` interface.
+
+   .. attribute:: object
+   
+      The subject of the event.
+
+   .. attribute:: original
+
+      The original object from which the copy was made.
+
+
+:class:`IObjectCreatedEvent`
+============================
+
+An object has been created. This event is intended to happen before an
+object has been made persistent, that is it's location attributes
+(__name__ and __parent__) will usually be None.
+
+.. class:: grok.IObjectCreatedEvent
+
+   Interface to subscribe to for when an object is created.
+
+   .. attribute:: object
+   
+      The subject of the event.
+
+
+:class:`IObjectRemovedEvent`
+============================
+
+An object has been removed from a container.
+
+.. class:: grok.IObjectRemovedEvent
+
+   Interface to subscribe to for object deletions.
+
+   Inherits from `grok.IObjectMovedEvent`.
+
+   .. attribute:: object
+      
+      The subject of the event.
+   
+   .. attribute:: oldParent
+
+      The container stored in before removal.
+
+   .. attribute:: oldName
+
+      The name of the removed object.
+
+:class:`IBeforeTraverseEvent`
+=============================
+
+The publisher is about to traverse into the object.
+
+.. class:: grok.IBeforeTraverseEvent
+
+   Interface to subscribe to for object traversal.
+ 
+   .. attribute:: object
+      
+      The object being traversed throguh.
+
+   .. attribute:: request
+
+      The current request.
+
+Notification: Event implementations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Event objects are notifications that are sent when need to "fire off" an event.
+
+All of these event objects share the same minimal implementation of an event.
+This class is defined at zope.component.interfaces.ObjectEvent and looks like
+this:
+
+.. code-block:: python
+
+    from zope import interface
+    
+    class ObjectEvent(object):
+        interface.implements(IObjectEvent)
+
+        def __init__(self, object):
+            self.object = object
+
+:class:`ApplicationInitializedEvent`
+=====================================
+
+Event object to send after an application has been created.
+
+.. class:: grok.ApplicationInitializedEvent
+
+    Default event implementation of the `grok.IApplicationInitializedEvent` interface.
+
+    .. attribute:: object
+
+        The application that has just been initialized.
+
+:class:`ObjectModifiedEvent`
+============================
+
+Event object to send as a notification when an object is modified.
+
+.. class:: grok.ObjectModifiedEvent(object, *descriptions)
+
+    Default event implementation of the `grok.IObjectMovedEvent` interface.
+
+    .. attribute:: object
+
+       The subject of the event.
+
+    .. attribute:: descriptions
+    
+        A list of descriptions of the modifications.
+
+**Example 1: Send an object modification event with a modified attribute
+named "field".**
+
+.. code-block:: python
+
+    import grok
+    import zope.event
+    import zope.lifecycleevent.Attributes
+    from zope.interface import Interface
+    
+    class ISample(Interface) :
+        field = Attribute("A test field")
+    
+    class Sample(object) :
+        grok.implements(ISample)
+
+    obj = Sample()
+    obj.field = 42
+    zope.event.notify(
+    	grok.ObjectModifiedEvent(obj,
+    	zope.lifecycleevent.Attributes(ISample, "field"))
+    )
+
+:class:`ContainerModifiedEvent`
+===============================
+
+Event object to send as a notification when a container object modified.
+
+.. class:: grok.ContainerModifiedEvent(object, *descriptions)
+
+    Default event implementation of the `grok.IContainerModifiedEvent`
+    interface.
+
+    .. attribute:: object
+
+       The subject of the event.
+
+    .. attribute:: descriptions
+
+        A list of descriptions of the modifications.
+
+
+:class:`ObjectMovedEvent`
+=========================
+
+Event object to send as a notification of when an object is moved.
+
+.. class:: grok.ObjectMovedEvent(object, oldParent, oldName, newParent, newName)
+
+    Default event implementation of the `grok.IObjectMovedEvent` interface.
+
+    .. attribute:: object
+
+       The subject of the event.
+
+    .. attribute:: oldParent
+
+       The container stored in before moving.
+
+    .. attribute:: oldName
+
+       The name before moving.
+
+    .. attribute:: newParent
+
+       The container stored in after moving.
+
+    .. attribute:: newName
+
+       The name after moving.
+
+
+:class:`ObjectAddedEvent`
+=========================
+
+Event object to send as a notification of when an object is added.
+
+.. class:: grok.ObjectAddedEvent(object, newParent, newName)
+
+    Default event implementation of the `grok.IObjectAddedEvent` interface.
+
+    .. attribute:: object
+
+       The subject of the event.
+
+    .. attribute:: newParent
+
+       The container stored in after moving.
+
+    .. attribute:: newName
+
+       The name after moving.
+
+
+:class:`ObjectCopiedEvent`
+==========================
+
+Event object to send as a notification of when an object is copied.
+
+.. class:: grok.ObjectCopiedEvent(object, original)
+
+    Default event implementation of the `grok.IObjectCopiedEvent` interface.
+
+    Initialize this event with the new copy and the original object as positional
+    arguments.
+    
+    .. attribute:: object
+
+       The subject of the event.
+
+    .. attribute:: original
+
+       The original object from which the copy was made.
+
+
+:class:`ObjectCreatedEvent`
+===========================
+
+Event object to send as a notification of when an object is created.
+
+.. class:: grok.ObjectCreatedEvent(object)
+
+    Default event implementation of the `grok.IObjectCreatedEvent` interface.
+
+    Initialize this event with the object created.
+
+    .. attribute:: object
+
+       The subject of the event.
+
+:class:`grok.ObjectRemovedEvent`
+================================
+
+Event object to send as a notification of when an object is removed.
+
+.. class:: grok.ObjectRemovedEvent*(object, oldParent, oldName)
+
+    Default event implementation of the `grok.IObjectRemovedEvent` interface.
+
+    .. attribute:: object
+    
+        The subject of the event.
+
+    .. attribute:: oldParent
+
+       The container stored in before removal.
+
+    .. attribute:: oldName
+
+       The name of the removed object.

Added: groktoolkit/branches/jw-documentation-rearangement/doc/reference/exceptions.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/reference/exceptions.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/reference/exceptions.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,61 @@
+
+**********
+Exceptions
+**********
+
+grok tries to inform you about errors early and with as much guidance
+as possible. grok can detect some errors already while importing a
+module, which will lead to the :class:`GrokImportError`.  Other errors
+require more context and can only be detected while executing the
+:func:`grok` function.
+
+
+:class:`grok.GrokImportError` -- errors while importing a module
+================================================================
+
+This exception is raised if a grok-specific problem was found while
+importing a module of your application. :class:`GrokImportError` means
+there was a problem in how you are using a part of grok. The error
+message tries to be as informative as possible tell you why something
+went wrong and how you can fix it.
+
+:class:`GrokImportError` is a subclass of Python's
+:class:`ImportError`.
+
+Examples of situations in which a GrokImportError occurs:
+
+  * Using a directive in the wrong context (e.g. grok.templatedir on
+    class-level instead of module-level.)
+
+  * Using a decorator with wrong arguments (e.g. grok.subscribe
+    without any argument)
+
+  * ...
+
+
+:class:`grok.GrokError` -- errors while grokking a module
+=========================================================
+
+This exception is raised if an error occurs while grokking a module.
+
+Typically a :class:`GrokError` will be raised if one of your modules
+uses a feature of grok that requires some sort of unambigous context
+to establish a reasonable default.
+
+For example, the :class:`grok.View` requires exactly one model to be
+defined locally in the module to assume a default module to be
+associated with. Having no model defined, or more than one model, will
+lead to an error because the context is either underspecified or
+ambigous.
+
+The error message of a :class:`GrokError` will include the reason for
+the error, the place in your code that triggered the error, and a
+hint, to help you fix the error.
+
+
+.. class:: GrokError(Exception)
+
+   .. attribute:: GrokError.component
+
+      The component that was grokked and triggered the error.
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/reference/functions.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/reference/functions.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/reference/functions.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,158 @@
+*********
+Functions
+*********
+
+The :mod:`grok` module provides a number of convenience functions to aid in
+common tasks.
+
+
+:func:`grok.AutoFields` -- deduce and return schema fields automatically
+========================================================================
+
+.. function:: grok.AutoFields(class_or_interface)
+
+    This function is used inside :class:`Form` classes to automatically
+    deduce the form fields from the schema of the `class_or_interface`.
+
+This function is used to create a sequence of form fields from an interface
+(schema) or from the interfaces (schemas) the context object provides.
+
+**Example: Generate fields from an interface**
+
+The :func:`grok.AutoFields` is used on the IMammoth interface, and all
+attributes that inherit from IField (such as the ones supplied in the
+zope.schema package) are concatenated into a list.
+
+.. code-block:: python
+
+     import grok
+     from zope import interface, schema
+
+     class IMammoth(interface.Interface):
+         name = schema.TextLine(title=u"Name")
+         size = schema.TextLine(title=u"Size", default=u"Quite normal")
+
+     class Mammoth(grok.Model):
+         interface.implements(IMammoth)
+
+     class Edit(grok.EditForm):
+         grok.context(Mammoth)
+
+         form_fields = grok.AutoFields(Mammoth).omit('size')
+
+In this example the ``size`` attribute will not show up in the resulting
+edit view.
+
+.. seealso::
+
+    :class:`grok.EditForm`, :func:`grok.Fields`
+
+
+:func:`grok.Fields` -- declare schema fields of a form
+======================================================
+
+.. function:: grok.Fields(*args, **kw)
+
+   This function is used inside a :class:`grok.Fields` to generate fields
+   (an object providing IFormFields) from positional and keyword arguments.
+   These should be available in the definition order.
+
+**Example: Generate form fields from schema objects**
+
+When the :class:`Edit` form is rendered, the :class:`Textlines` `b` and `a`
+will appear as input fields in that order.
+
+.. code-block:: python
+
+    import grok
+    from zope import schema
+
+    class Edit(grok.EditForm):
+        fields = grok.Fields(
+            b = schema.TextLine(title=u"Beta"),
+            a = schema.TextLine(title=u"Alpha"),
+        )
+
+.. seealso::
+
+    :func:`grok.AutoFields`, :class:`grok.Form`
+
+
+:func:`grok.getApplication`
+===========================
+
+.. autofunction:: grok.getApplication()
+
+
+:func:`grok.getSite`
+====================
+
+.. function:: grok.getSite()
+
+    Get the current site object.
+
+.. seealso::
+
+    Site objects are instances of :class:`grok.Site`. Typically this will
+    also be your main :class:`grok.Application` root object, which inherits
+    from :class:`grok.Site`. Normally you will want to use
+    `grok.getApplication` to get the application object, as `grok.getSite`
+    can return enclosed sub-sites in applications with more complex
+    configuration.
+
+.. seealso::
+
+    `Web Component Development With Zope 3, second edition <http://worldcookery.com/WhereToBuy>`_
+    By Philipp von Weitershausen; Chapter 18 describes the use of Site objects.
+
+
+:func:`grok.notify`
+===================
+
+.. function:: grok.notify(event)
+
+   Send `event` to event subscribers.
+
+**Example:**
+
+.. code-block:: python
+
+    import grok
+
+    class Mammoth(object):
+        def __init__(self, name):
+            self.name = name
+
+    manfred = Mammoth('manfred')
+
+    grok.notify(grok.ObjectCreatedEvent(manfred))
+
+.. seealso::
+
+      Grok events provide a selection of common event types.
+
+.. seealso::
+
+    `Web Component Development With Zope 3, second edition <http://worldcookery.com/WhereToBuy>`_
+    By Philipp von Weitershausen; Chapter 16 describes the Zope 3
+    event system.
+
+
+:func:`grok.url`
+================
+
+.. function:: grok.url(request, object, [, name])
+
+    Construct a URL for the given `request` and `object`.
+
+    `name` may be a string that gets appended to the object
+    URL. Commonly used to construct an URL to a particular view on the
+    object.
+
+    This function returns the constructed URL as a string.
+
+.. seealso::
+
+    View classes derived from :class:`grok.View` have a similar
+    :meth:`url` method for constructing URLs.
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/reference/index.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/reference/index.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/reference/index.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,24 @@
+.. _reference-index:
+
+#################################
+  The Grok Reference
+#################################
+(keep this under your pillow)
+
+:Reference for Grok version: |version|
+:Document last updated: |today|
+    
+This is the Grok reference documentation. It is organized by the Python
+artefacts that implement it's concepts.
+
+.. toctree::
+   :maxdepth: 2
+
+   components.rst
+   directives.rst
+   decorators.rst
+   functions.rst
+   utils.rst
+   events.rst
+   exceptions.rst
+   testing.rst

Added: groktoolkit/branches/jw-documentation-rearangement/doc/reference/testing.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/reference/testing.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/reference/testing.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,344 @@
+*******
+Testing
+*******
+
+Installing the testing tool
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Every Grok-based project will install a test runner that can find
+and run all test cases for your project. This test runner is installed
+using Buildout with the 
+`zc.recipe.testrunner <http://pypi.python.org/pypi/zc.recipe.testrunner>`_
+recipe. The default configuration is::
+
+    [test]
+    recipe = zc.recipe.testrunner
+    eggs = <my-grok-project-name>
+    defaults = ['--tests-pattern', '^f?tests$', '-v']
+
+Using the test runner
+~~~~~~~~~~~~~~~~~~~~~
+
+The test runner can be invoked by the `test` program in your projects
+`bin` directory.
+
+usage
+=====
+
+  Usage: test [options] [MODULE] [TEST]
+
+options: help
+=============
+
+  -h, --help
+    show this help message and exit
+
+options: searching and filtering
+================================
+
+    options in this group are used to define which tests to run.
+
+    -s PACKAGE, --package=PACKAGE, --dir=PACKAGE
+        Search the given package's directories for tests.
+        This can be specified more than once to run tests in
+        multiple parts of the source tree.  For example, if
+        refactoring interfaces, you don't want to see the way
+        you have broken setups for tests in other packages.
+        You *just* want to run the interface tests.  Packages
+        are supplied as dotted names.  For compatibility with
+        the old test runner, forward and backward slashed in
+        package names are converted to dots.  (In the special
+        case of packages spread over multiple directories,
+        only directories within the test search path are
+        searched. See the --path option.)
+    -m MODULE, --module=MODULE
+        Specify a test-module filter as a regular expression.
+        This is a case-sensitive regular expression, used in
+        search (not match) mode, to limit which test modules
+        are searched for tests.  The regular expressions are
+        checked against dotted module names.  In an extension
+        of Python regexp notation, a leading "!" is stripped
+        and causes the sense of the remaining regexp to be
+        negated (so "!bc" matches any string that does not
+        match "bc", and vice versa).  The option can be
+        specified multiple test-module filters.  Test modules
+        matching any of the test filters are searched.  If no
+        test-module filter is specified, then all test modules
+        are used.
+    -t TEST, --test=TEST
+        Specify a test filter as a regular expression.  This
+        is a case-sensitive regular expression, used in search
+        (not match) mode, to limit which tests are run.  In an
+        extension of Python regexp notation, a leading "!" is
+        stripped and causes the sense of the remaining regexp
+        to be negated (so "!bc" matches any string that does
+        not match "bc", and vice versa).  The option can be
+        specified multiple test filters. Tests matching any of
+        the test filters are included.  If no test filter is
+        specified, then all tests are run.
+    -u, --unit
+        Run only unit tests, ignoring any layer options.
+    -f, --non-unit
+        Run tests other than unit tests.
+    --layer=LAYER
+        Specify a test layer to run.  The option can be given
+        multiple times to specify more than one layer.  If not
+        specified, all layers are run. It is common for the
+        running script to provide default values for this
+        option.  Layers are specified regular expressions,
+        used in search mode, for dotted names of objects that
+        define a layer.  In an extension of Python regexp
+        notation, a leading "!" is stripped and causes the
+        sense of the remaining regexp to be negated (so "!bc"
+        matches any string that does not match "bc", and vice
+        versa).  The layer named 'unit' is reserved for unit
+        tests, however, take note of the --unit and non-unit
+        options.
+    -a AT_LEVEL, --at-level=AT_LEVEL
+        Run the tests at the given level.  Any test at a level
+        at or below this is run, any test at a level above
+        this is not run.  Level 0 runs all tests.
+    --all
+        Run tests at all levels.
+    --list-tests
+        List all tests that matched your filters.  Do not run
+        any tests.
+
+options: reporting
+==================
+
+    Reporting options control basic aspects of test-runner output
+
+    -v, --verbose
+        Make output more verbose. Increment the verbosity
+        level.
+    -q, --quiet
+        Make the output minimal, overriding any verbosity
+        options.
+    -p, --progress
+        Output progress status
+    --no-progress
+        Do not output progress status.  This is the default,
+        but can be used to counter a previous use of --progress or -p.
+    --auto-progress
+        Output progress status, but only when stdout is a terminal.
+    -c, --color
+        Colorize the output.
+    -C, --no-color
+        Do not colorize the output.  This is the default, but
+        can be used to counter a previous use of --color or -c.
+    --auto-color
+        Colorize the output, but only when stdout is a terminal.
+    --slow-test=N
+        With -c and -vvv, highlight tests that take longer
+        than N seconds (default: 10).
+    -1, --hide-secondary-failures
+        Report only the first failure in a doctest. (Examples
+        after the failure are still executed, in case they do
+        any cleanup.)
+    --show-secondary-failures
+        Report all failures in a doctest.  This is the
+        default, but can be used to counter a default use of
+        -1 or --hide-secondary-failures.
+    --ndiff
+        When there is a doctest failure, show it as a diff
+        using the ndiff.py utility.
+    --udiff
+        When there is a doctest failure, show it as a unified diff.
+    --cdiff
+        When there is a doctest failure, show it as a context diff.
+
+options: analysis
+=================
+
+    Analysis options provide tools for analysing test output.
+
+    -D, --post-mortem
+        Enable post-mortem debugging of test failures
+    -g GC, --gc=GC
+        Set the garbage collector generation threshold.  This
+        can be used to stress memory and gc correctness.  Some
+        crashes are only reproducible when the threshold is
+        set to 1 (aggressive garbage collection).  Do "--gc 0"
+        to disable garbage collection altogether.  The --gc
+        option can be used up to 3 times to specify up to 3 of
+        the 3 Python gc_threshold settings.
+    -G GC_OPTION, --gc-option=GC_OPTION
+        Set a Python gc-module debug flag.  This option can be
+        used more than once to set multiple flags.
+    -N REPEAT, --repeat=REPEAT
+        Repeat the tests the given number of times.  This
+        option is used to make sure that tests leave their
+        environment in the state they found it and, with the
+        --report-refcounts option to look for memory leaks.
+    -r, --report-refcounts
+        After each run of the tests, output a report
+        summarizing changes in refcounts by object type.  This
+        option that requires that Python was built with the
+        --with-pydebug option to configure.
+    --coverage=COVERAGE
+        Perform code-coverage analysis, saving trace data to
+        the directory with the given name.  A code coverage
+        summary is printed to standard out.
+    --profile=PROFILE
+        Run the tests under cProfiler or hotshot and display
+        the top 50 stats, sorted by cumulative time and number
+        of calls.
+    --pychecker
+        Run the tests under pychecker
+
+options: setup
+==============
+
+    Setup options are normally supplied by the testrunner script, although
+    they can be overridden by users.
+
+    --path=PATH
+        Specify a path to be added to Python's search path.
+        This option can be used multiple times to specify
+        multiple search paths.  The path is usually specified
+        by the test-runner script itself, rather than by users
+        of the script, although it can be overridden by users.
+        Only tests found in the path will be run.  This option
+        also specifies directories to be searched for tests.
+        See the search_directory.
+    --test-path=TEST_PATH
+        Specify a path to be searched for tests, but not added
+        to the Python search path.  This option can be used
+        multiple times to specify multiple search paths.  The
+        path is usually specified by the test-runner script
+        itself, rather than by users of the script, although
+        it can be overridden by users.  Only tests found in
+        the path will be run.
+    --package-path=PACKAGE_PATH
+        Specify a path to be searched for tests, but not added
+        to the Python search path.  Also specify a package for
+        files found in this path. This is used to deal with
+        directories that are stitched into packages that are
+        not otherwise searched for tests.  This option takes 2
+        arguments.  The first is a path name. The second is
+        the package name.  This option can be used multiple
+        times to specify multiple search paths.  The path is
+        usually specified by the test-runner script itself,
+        rather than by users of the script, although it can be
+        overridden by users.  Only tests found in the path
+        will be run.
+    --tests-pattern=TESTS_PATTERN
+        The test runner looks for modules containing tests.
+        It uses this pattern to identify these modules.  The
+        modules may be either packages or python files.  If a
+        test module is a package, it uses the value given by
+        the test-file-pattern to identify python files within
+        the package containing tests.
+    --suite-name=SUITE_NAME
+        Specify the name of the object in each test_module
+        that contains the module's test suite.
+    --test-file-pattern=TEST_FILE_PATTERN
+        Specify a pattern for identifying python files within
+        a tests package. See the documentation for the
+        --tests-pattern option.
+    --ignore_dir=IGNORE_DIR
+        Specifies the name of a directory to ignore when
+        looking for tests.
+
+options: other
+==============
+
+    Other options
+
+    -k, --keepbytecode
+        Normally, the test runner scans the test paths and the
+        test directories looking for and deleting pyc or pyo
+        files without corresponding py files.  This is to
+        prevent spurious test failures due to finding compiled
+        modules where source modules have been deleted. This
+        scan can be time consuming.  Using this option
+        disables this scan.  If you know you haven't removed
+        any modules since last running the tests, can make the
+        test run go much faster.
+    --usecompiled
+        Normally, a package must contain an __init__.py file,
+        and only .py files can contain test code.  When this
+        option is specified, compiled Python files (.pyc and
+        .pyo) can be used instead:  a directory containing
+        __init__.pyc or __init__.pyo is also considered to be
+        a package, and if file XYZ.py contains tests but is
+        absent while XYZ.pyc or XYZ.pyo exists then the
+        compiled files will be used.  This is necessary when
+        running tests against a tree where the .py files have
+        been removed after compilation to .pyc/.pyo.  Use of
+        this option implies --keepbytecode.
+    --exit-with-status
+        Return an error exit status if the tests failed.  This
+        can be useful for an invoking process that wants to
+        monitor the result of a test run.
+
+Discovering Test Cases
+~~~~~~~~~~~~~~~~~~~~~~
+
+The test runner looks for modules containing tests. It uses the default
+pattern of \'^f?tests$\' to identify these modules. The test runner will
+then use the name `test_suite` in all matching modules as the object to
+provide test suites.
+
+Test Supporting API
+~~~~~~~~~~~~~~~~~~~
+
+.. .. module:: grok.testing
+
+To support testing in Grok-based projects, Grok comes with a couple of
+helpers located in the :mod:`grok.testing` module.
+
+.. automodule:: grok.testing
+   :members:
+   :undoc-members:
+   :inherited-members:
+
+   .. autofunction:: grok.testing.grok_component
+
+      Grok a single component.
+
+      This function can be used to grok individual components within a
+      doctest, such as adapters. It sets up just enough context for
+      some grokking to work, though more complicated grokkers which
+      need module context (such as view grokkers) might not work.
+
+      Returns ``True`` or ``False`` depending on whether the grokking
+      worked or not.
+
+      A sample doctest could look as follows:
+
+        This defines the object we want to provide an adapter for:
+
+          >>> class Bar(object):
+          ...    pass
+
+        This is the interface that we want to adapt to:
+
+          >>> from zope.interface import Interface
+          >>> class IFoo(Interface):
+          ...    pass
+
+        This is the adapter itself:
+
+          >>> import grokcore.component as grok
+          >>> class MyAdapter(grok.Adapter):
+          ...    grok.provides(IFoo)
+          ...    grok.context(Bar)
+
+        Now we will register the adapter using grok_component():
+
+          >>> from grok.testing import grok, grok_component
+          >>> grok('grokcore.component.meta')
+          >>> grok_component('MyAdapter', MyAdapter)
+          True
+  
+        The adapter should now be available:
+
+          >>> adapted = IFoo(Bar())
+          >>> isinstance(adapted, MyAdapter)
+          True
+
+
+      .. deprecated:: 1.0
+         Use :func:`grokcore.component.testing.grok_component` instead.
\ No newline at end of file

Added: groktoolkit/branches/jw-documentation-rearangement/doc/reference/utils.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/reference/utils.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/reference/utils.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,42 @@
+.. module:: grok.util
+
+*********
+Utilities
+*********
+
+The :mod:`grok.util` module provides functions which are less commonly
+used, and so are not available for import directly from the :mod:`grok` module.
+
+:func:`grok.util.application_url`
+=================================
+
+This function is also available as a method on the :class:`grok.View` class.
+
+.. autofunction:: grok.util.application_url
+
+
+:func:`grok.util.applySkin`
+===========================
+
+.. autofunction:: grok.util.applySkin
+
+
+:func:`grok.util.create_application`
+====================================
+
+.. autofunction:: grok.util.create_application
+
+
+:func:`grok.util.getApplication`
+================================
+
+This function is also availbale in the main grok namespace and can be
+called as :func:`grok.getApplication`.
+
+.. autofunction:: grok.util.getApplication()
+
+
+:func:`grok.util.safely_locate_maybe`
+=====================================
+
+.. autofunction:: grok.util.safely_locate_maybe

Added: groktoolkit/branches/jw-documentation-rearangement/doc/resources/evencaveman.jpg
===================================================================
(Binary files differ)


Property changes on: groktoolkit/branches/jw-documentation-rearangement/doc/resources/evencaveman.jpg
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: groktoolkit/branches/jw-documentation-rearangement/doc/resources/grok-standing.jpg
===================================================================
(Binary files differ)


Property changes on: groktoolkit/branches/jw-documentation-rearangement/doc/resources/grok-standing.jpg
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: groktoolkit/branches/jw-documentation-rearangement/doc/style.tex
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/style.tex	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/style.tex	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,74 @@
+% 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}
+%}

Added: groktoolkit/branches/jw-documentation-rearangement/doc/template.pt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/template.pt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/template.pt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,68 @@
+<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>
+

Added: groktoolkit/branches/jw-documentation-rearangement/doc/tutorial.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/tutorial.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/tutorial.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,1343 @@
+=============
+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.

Added: groktoolkit/branches/jw-documentation-rearangement/doc/tutorial_outline.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/tutorial_outline.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/tutorial_outline.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,236 @@
+================
+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.

Added: groktoolkit/branches/jw-documentation-rearangement/doc/upgrade.rst
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/upgrade.rst	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/upgrade.rst	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1 @@
+.. include:: upgrade.txt

Added: groktoolkit/branches/jw-documentation-rearangement/doc/upgrade.txt
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/doc/upgrade.txt	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/doc/upgrade.txt	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,619 @@
+.. _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.

Copied: groktoolkit/branches/jw-documentation-rearangement/documentation.cfg (from rev 119533, grok/branches/jw-documentation-rearangement/documentation.cfg)
===================================================================
--- groktoolkit/branches/jw-documentation-rearangement/documentation.cfg	                        (rev 0)
+++ groktoolkit/branches/jw-documentation-rearangement/documentation.cfg	2011-01-12 16:38:04 UTC (rev 119545)
@@ -0,0 +1,18 @@
+[buildout]
+extends = grok.cfg
+develop = .
+parts =
+  grokpy
+  docs
+versions = versions
+
+[grokpy]
+recipe = z3c.recipe.scripts
+interpreter = grokpy
+eggs = grok
+
+[docs]
+recipe = collective.recipe.sphinxbuilder
+source = ${buildout:directory}/doc
+build = ${buildout:directory}/doc/_build
+interpreter = ${buildout:bin-directory}/grokpy



More information about the checkins mailing list