[Checkins] SVN: Sandbox/ulif/grok-adminui/doc/ Prepare for merge with trunk.

Uli Fouquet uli at gnufix.de
Wed Aug 8 08:58:31 EDT 2007


Log message for revision 78700:
  Prepare for merge with trunk.

Changed:
  U   Sandbox/ulif/grok-adminui/doc/grok2html.py
  D   Sandbox/ulif/grok-adminui/doc/groktut/building_forms_with_formlib/
  D   Sandbox/ulif/grok-adminui/doc/macros.txt
  D   Sandbox/ulif/grok-adminui/doc/minitutorials/testing.txt
  U   Sandbox/ulif/grok-adminui/doc/tutorial.txt

-=-
Modified: Sandbox/ulif/grok-adminui/doc/grok2html.py
===================================================================
--- Sandbox/ulif/grok-adminui/doc/grok2html.py	2007-08-08 12:57:17 UTC (rev 78699)
+++ Sandbox/ulif/grok-adminui/doc/grok2html.py	2007-08-08 12:58:31 UTC (rev 78700)
@@ -175,9 +175,6 @@
     rest_files.append(RestFile('macros', 
                               os.path.join(source_dir, 'minitutorials', 'macros.txt'),
                               os.path.join(www_dir, 'minitutorials', 'macros.html')))
-    rest_files.append(RestFile('testing', 
-                              os.path.join(source_dir, 'minitutorials', 'testing.txt'),
-                              os.path.join(www_dir, 'minitutorials', 'testing.html')))
     rest_files.append(RestFile('zc.buildout', 
                   'http://svn.zope.org/*checkout*/zc.buildout/trunk/doc/tutorial.txt',
                   os.path.join(www_dir, 'minitutorials', 'buildout.html')))

Deleted: Sandbox/ulif/grok-adminui/doc/macros.txt
===================================================================
--- Sandbox/ulif/grok-adminui/doc/macros.txt	2007-08-08 12:57:17 UTC (rev 78699)
+++ Sandbox/ulif/grok-adminui/doc/macros.txt	2007-08-08 12:58:31 UTC (rev 78700)
@@ -1,247 +0,0 @@
-============================
-Mini-Howto: Macros with Grok
-============================
-
-Intended Audience:
-
-  * Python Developers
-
-  * Zope 2 Developers
-
-  * Zope 3 Developers
-
-
-
-Introduction
-------------
-
-Macros are a way to define a chunk of presentation in one template,
-and share it in others. Changes to the macro are immediately reflected
-in all of the places, that share it.
-
-Such, a developer can easily write some sort of 'page-skeleton' (the
-macro), which can be reused in other pages to take care, for instance,
-for a certain and consistent look-and-feel of a whole site with less
-maintenance.
-
-Technically, macros are made available by ``METAL``, a Macro Expansion
-for TAL, which ships with nearly every Zope installation. They can be
-used in Zope Page Templates. See the `TAL`_ and `METAL`_ pages for
-details.
-
-.. _`TAL`: http://wiki.zope.org/ZPT/TAL
-
-.. _`METAL`: http://wiki.zope.org/ZPT/METAL
-
-
-
-Defining a simple macro
------------------------
-
-In Grok macros are defined in usual views, where the associated page
-templates contain `metal`-statements to define the desired
-macros. Macros generally are attributes of the page template wherein they
-are defined, but to get them rendered, we usually use views.
-
-We define a view ``MyMacros`` the usual way in ``app.py``::
-
-   import grok
-
-   class Sample(grok.Application, grok.Container):
-       pass
-
-   class Index(grok.View):
-       pass # see app_templates/index.pt
-
-   class MyMacros(grok.View):
-       """The macro holder"""
-       grok.context(Sample) # The default model this view is bound to.
-
-In the associated page template ``app_templates/mymacros.pt`` we
-define the macros we like to have available. You define macros with
-the ``METAL`` attribute::
-
-    metal:define-macro="<macro-name>"
-
-and the slots therein with::
-
-    metal:define-slots=<slot-name> 
-
-Let's define a very plain page macro::
-
-   <html metal:define-macro="mypage">
-     <head></head>
-     <body>
-       The content:
-       <div metal:define-slot="mycontent">
-         Put your content here...
-       </div>
-     </body>
-   </html>
-
-Here we defined a single macro ``mypage`` with only one slot
-``mycontent``. 
-
-If we restart our Zope instance (don't forget to put some ``index.pt``
-into ``app_templates/``) and have created our application as ``test``,
-we now can go to the following URL::
-
-    http://localhost:8080/test/mymacros
-
-and see the output::
-
-    The content:
-    Put your content here...
-
-Allright.
-
-
-Referencing a simple macro
---------------------------
-
-In ``index.pt`` we now want to *use* the macro defined in
-``mymacros.pt``. Using a macro means to let it render a part of
-another page template, especially, filling the slots defined in
-``mymacros.pt`` with content defined in ``index.pt``. You call macros
-with the ``METAL`` attribute::
-
-     metal:use-macro="<macro-location>" 
-
-Our ``app_templates/index.pt`` can be that simple::
-
-    <html metal:use-macro="context/@@mymacros/mypage">
-    </html>
-
-Watching::
-
-	http://localhost:8080/test/index
-
-should now give the same result as above, although we didn't call
-``mymacros`` in browser, but ``index``. That's what macros are made
-for.
-
-When we fill the slots, we get different content rendered within
-the same macro. You can fill slots using
-
-    metal:fill-slot="<slot-name>"
-
-where the slot-name must be defined in the macro. Now, change
-``indext.pt`` to::
-
-    <html metal:use-macro="context/@@mymacros/mypage">
-      <body>
-        <div metal:fill-slot="body">
-          My content from index.pt
-        </div>
-      </body>
-    </html>
-
-and you will get the output::
-
-    The content:
-    My content from index.pt
-
-The pattern of the macro reference (the <macro-location>) used here
-is::
-
-    context/<view-name>/<macro-name>
-
-whereas ``context`` references the object being viewed, which in our
-case is the ``Sample`` application. In plain English we want Zope to
-look for a view for a ``Sample`` application object (``test``) which
-is called ``mymacros`` and contains a macro called ``mypage``.
-
-The logic behind this is, that views are always registered for certain
-object types. Registering a view with some kind of object (using
-``grok.context()`` for example), means, that we promise, that this
-view can render objects of that type. (It is up to you to make sure,
-that the view can handle rendering of that object type).
-
-It is not a bad idea to register views for interfaces (instead of
-implementing classes), because it means, that a view will remain
-usable, while an implementation of an interface can change. [FIXME: Is
-this a lie?] This is done in the section `Defining 'all-purpose'
-macros`_ below.
-
-
-Background: how ``grok.View`` and macros interact
--------------------------------------------------
-
-In case of ``grok.View`` views are in fact ``BrowserPage`` objects
-with an attribute ``template``, which is the associated page
-template. The associated page template in turn has got an attribute
-``macros``, which is a dictionary containing all the macros defined in
-the page template with their names as keys (or ``None``). 
-
-This means, that you can also reference a macro of a ``grok.View``
-using::
-
-     context/<view-name>/template/macros/<macro-name>
-
-Grok shortens this path for you by mapping the ``macros`` dictionary
-keys to the associated ``grok.View``. If you define a macro
-``mymacro`` in a template associated with a ``grok.View`` called
-``myview``, this view will map ``mymacro`` as an own attribute, so
-that you can ask for the attribute ``mymacro`` of the *view*, wheras
-it is in fact an attribute of the associated template.
-
-Such, you can write in short for the above pattern::
-
-      context/<view-name>/<macro-name>
-
-View names always start with the 'eyes' (``@@``) which is a shortcut
-for ``++view++<view-name>``.
-
-
-Defining 'all-purpose' macros
-------------------------------
-
-To define an 'all-purpose' macro, i.e. a macro, that can render
-objects of (nearly) any type and thus be accessed from any
-other page template, just set a very general context for your macro
-view::
-
-    from zope.interface import Interface
-    import grok
-
-    class Master(grok.View):
-        grok.context(Interface)
-
-and reference the macros of the associated pagetemplate like this::
-
-    context/@@master/<macro-name>
-
-Because the macros in ``Master`` now are 'bound' (in fact their view
-is bound) to ``Interface`` and every Grok application, model or
-container implements some interface, the ``Master`` macros will be
-accessible from nearly every other context. ``Master`` promises to be
-a view for every object, which implements ``Interface``.
-
-
-Accessing Zope3 standard macros
--------------------------------
-
-The standard macros of Zope 3, which render also the default ZMI
-pages, are accessible under the view-name ``standard_macros`` and usually
-provide slots ``title``, ``headers`` and ``body``. It is
-good style to provide this slots with your homegrown views as well.
-
-To give your pages standard Zope3 look, you can do something like
-this in your page template::
-
-        <html metal:use-macro="context/@@standard_macros/page">
-          <head>
-            <title metal:fill-slot="title">
-              Document Title
-            </title>
-            <metal:headers fill-slot="headers">
-              <!-- Additional headers here... -->
-            </metal:headers>
-          </head>
-          <body>
-            <div metal:fill-slot="body">
-              Your content here...
-            </div>
-          </body>
-        </html>
-

Deleted: Sandbox/ulif/grok-adminui/doc/minitutorials/testing.txt
===================================================================
--- Sandbox/ulif/grok-adminui/doc/minitutorials/testing.txt	2007-08-08 12:57:17 UTC (rev 78699)
+++ Sandbox/ulif/grok-adminui/doc/minitutorials/testing.txt	2007-08-08 12:58:31 UTC (rev 78700)
@@ -1,363 +0,0 @@
-=======================================
-Mini-Howto: Automated Testing with Grok
-=======================================
-
-:Author: Uli Fouquet
-
-Intended Audience:
-
-  * Python Developers
-
-  * Zope 2 Developers
-
-.. contents::
-
-Introduction
-------------
-
-Testing is a major topic in Zope 3 and its support for several kinds
-of tests is remarkable. Even for developers, that are already familiar
-with functional tests, unittests and doctests, there might remain some
-questions, for example, where to put what tests and similar.
-
-This mini tutorial gives a very short overview over the different
-kinds of tests supported by Zope 3 and then shows some basic ways how
-to use them within a typical Grok project.
-
-This is *not* a general introduction to testing with Python, the
-concepts of unit testing or similar. It is just a sketch to get you
-started, when you want to create tests for your Grok project (and you
-*want* to create tests).
-
-What we will show here, is a way, to create and run your tests using
-``bin/test`` from your project root.
-
-For experienced Zope 3 developers there should be nothing new herein.
-
-Types of Tests
---------------
-
-There are several kinds of tests, you can use with Zope 3
-out-of-the-box:
-
-- unit tests
-
-  Are tests for testing discrete units of your code, say a class or a
-  function. Support for unit tests comes with your Python
-  installation's ``unittest`` package. See the `Python reference`_ of
-  the unittest package for details.
-
-  You will use unit tests most probably for non-view related testing.
-
-.. _`Python reference`: http://docs.python.org/lib/module-unittest.html
-
-- functional tests
-
-  or integration tests in Zope 3 treat the whole Zope machinery as a
-  black box and provide the possibility to 'send' requests to
-  it. However, in fact no real requests happen, but the testing
-  environment only creates suitable objects to simulate browser
-  requests.
-
-  You will use functional tests most probably for the mere
-  view-related testing.
-
-- doc tests
-
-  are not a special kind of tests, but a special (and very convenient)
-  method to notate tests. They can be used to write unit tests as well
-  as functional tests. Their advantage is, that in many cases (but not
-  all) they are better readable and can be integrated into documenting
-  code. Often they improve chances of others to understand your code
-  better.
-
-
-Preparing the Project
----------------------
-
-For the following we expect to have a typical Grok project already
-created, as it is done by::
-
-  $ grokproject Sample
-
-Afterwards we have a newly created directory ``Sample/`` which contains
-a ``bin/`` and in ``src/sample`` your application. In the following
-``app.py`` should contain a class ``Sample`` which will be generated
-automatically if you enter the above commandline.
-
-We will now create tests, that can be run using::
-
-  $ bin/test
-
-which at the beginning should result in the following output::
-
-  Running tests at level 1
-  Total: 0 tests, 0 failures, 0 errors in 0.000 seconds.
-
-
-Writing Unittests
------------------
-
-Now we want to do some unit testing for the classes in ``app.py``. 
-
-
-Defining unit tests in ``tests.py``
-+++++++++++++++++++++++++++++++++++
-
-If you have a look at the ``bin/test`` script, that runs all the
-tests, you will find the definition of a Zope test runner. The test
-runner is configured to look for modules and packages named ``tests``
-or ``ftests``. See the ``zope.testing`` package to learn more about
-testrunners.
-
-This means, we can create a file ``src/sample/tests.py`` which will be
-executed by the testrunner automatically.
-
-Create a file ``tests.py`` in the root of your application.
-
-
-.. code-block:: python
-
-  """File: src/sample/tests.py
-  """
-  import unittest
-  from sample.app import Sample
-
-  class SampleTestCase(unittest.TestCase):
-
-      def test_fake(self):
-          self.assertEqual(0,0)
-
-  def test_suite():
-      suite = unittest.TestSuite()
-      suite.addTest(unittest.makeSuite(SampleTestCase))
-      return suite
-
-  if __name__ == '__main__':
-      unittest.main()
-
-As you can see, we define a test case ``SampleTestCase`` here with a
-plain and senseless test ``test_fake`` as part of the test case and
-a test suite.
-
-When we run the ``test`` programme again, we get::
-
-  $ ./bin/test
-  Running tests at level 1
-  Running unit tests:
-    Running:
-  .
-    Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
-
-Ooh, we performed one test as indicated by the dot below
-'Running:'.
-
-
-Defining unit tests in a ``tests`` package
-++++++++++++++++++++++++++++++++++++++++++
-
-This is all very well, but normally you want more than only one module
-for unit testing. It is part of the unit testing concept to test
-different elements in different files. 
-
-So the generally more recommended way is, to create a ``tests``
-package, where all unit tests for your application can be put in.
-
-So let's remove ``tests.py``::
-
-  $ rm tests.py
-
-Now create a ``tests/`` directory where we create an (empty) file
-``__init__.py``::
-
-  $ mkdir tests
-  $ touch tests/__init__.py # make this directory a package
-
-Such, we have an empty package ``tests`` wherein we will create a
-slightly modified unit tests suite.
-
-In ``src/sample/tests/`` create a file ``test_sample.py``.
-
-.. code-block:: python
-
-  """File: src/sample/tests/test_sample.py"""
-
-  import unittest
-  from sample.app import Sample
-
-  class SampleTestCase(unittest.TestCase):
-
-      def setUp(self):
-          # Put here anything to be done before a test is run.
-          pass
-
-      def test_fake(self):
-          self.assertEqual(0,0)
-
-  def test_suite():
-      suite = unittest.TestSuite()
-      suite.addTest(unittest.makeSuite(SampleTestCase))
-      return suite
-
-  if __name__ == '__main__':
-      unittest.main()
-
-The file could in fact be exactly the same as above. We only added a
-``setUp()`` method in the test case, which is very usual.
-
-When we run the tests afterwards, we will get exactly the same results
-as above::
-
-  $ ./bin/test
-  Running tests at level 1
-  Running unit tests:
-    Running:
-  .
-    Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
-
-You can add as many test modules (files) to the ``tests`` package as
-you like. The only requirement for the testrunner to handle them is,
-that their filename starts with ``test``. So you can create a module
-``simpletest.py`` and another ``testsomethingelse.py``, but only the
-latter will be run by the testrunner.
-
-
-Defining unit tests in subpackages
-++++++++++++++++++++++++++++++++++
-
-When your project starts to grow, even many modules in the ``tests``
-package might not be sufficient. Especially if the number of tests
-starts to be confusing, it is a good idea to create subpackages, where
-you can aggregate the tests related to certain elements.
-
-The problem with it is, that the testrunner does not automatically
-scan all subpackages for test suites. We have to register them
-manually, which can be done as follows.
-
-1. create packages inside the ``tests`` directory:
-
-   For our demonstration purposes we only create one package, called
-   ``sampletests``::
-
-     $ mkdir src/tests/sampletests
-     $ touch src/tests/sampletests/__init__.py
-
-   Note: don't name a subpackage in ``tests`` as your
-   application. This will lead to import problems.
-
-2. create a new ``test_sample.py`` which will 'drive' the tests,
-   i.e. find the packages, that contain tests.
-
-   .. code-block:: python
-
-    """File: src/sample/tests/test_sample.py
-    """
-    import unittest
-    from pkg_resources import resource_listdir
-    from sample.app import Sample
-
-    test_packages = ['sampletests']
-    test_root = 'sample.tests'
-
-    def suiteFromPackage(name):
-        files = resource_listdir(__name__,name)
-        testloader = unittest.TestLoader()
-        suite = unittest.TestSuite()
-        for filename in files:
-            if not filename.endswith('.py'):
-                continue
-            if filename == '__init__.py':
-                continue
-
-            dottedname = '%s.%s.%s' % (test_root, name, filename[:-3])
-            test = testloader.loadTestsFromName(dottedname)
-            suite.addTest(test)
-        return suite
-
-    def test_suite():
-        suite = unittest.TestSuite()
-        for name in test_packages:
-            suite.addTest(suiteFromPackage(name))
-        return suite
-
-    if __name__ == '__main__':
-        unittest.main()
-  
-
-
-   In this little script the ``suiteFromPackage()`` function looks for
-   a package called ``sample.tests.<name>``, loads all modules therein
-   and adds their tests to a test suite which is returned.
-
-   You have eventually to modify the variables 
-
-   - ``test_root``, which sets the dotted name of the package, where
-     the subpackages reside, and the list
-
-   - ``test_modules``, which gives the names of the subpackages, where
-     the real tests can be found.
-
-
-3. Now fill the new ``sampletests`` package with tests. We can use the
-   module we have already written above, but this time give it another
-   name, not beginning with 'test'.
-
-   Create a file ``samplefake.py`` in the ``sampletests`` package:
-
-   .. code-block:: python
-
-    """File: src/sample/tests/sampletests/samplefake.py"""
-
-    import unittest
-    from sample.app import Sample
-
-    class SampleTestCase(unittest.TestCase):
-
-        def setUp(self):
-            # Put here anything to be done before a test is run.
-            pass
-
-        def test_fake(self):
-            self.assertEqual(0,0)
-
-    def test_suite():
-        suite = unittest.TestSuite()
-        suite.addTest(unittest.makeSuite(SampleTestCase))
-        return suite
-
-    if __name__ == '__main__':
-        unittest.main()
-
-
-When we run the tests afterwards, we will get exactly the same results
-as above::
-
-  $ ./bin/test
-  Running tests at level 1
-  Running unit tests:
-    Running:
-  .
-    Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
-
-
-
-Doing Unit Tests Using Doctests
--------------------------------
-
-
-Doctests in Separate Test Files
-+++++++++++++++++++++++++++++++
-
-
-Doctests in the Source Code
-+++++++++++++++++++++++++++
-
-
-Doctests as Part of Documentation
-+++++++++++++++++++++++++++++++++
-
-
-
-Functional Tests
-----------------
-

Modified: Sandbox/ulif/grok-adminui/doc/tutorial.txt
===================================================================
--- Sandbox/ulif/grok-adminui/doc/tutorial.txt	2007-08-08 12:57:17 UTC (rev 78699)
+++ Sandbox/ulif/grok-adminui/doc/tutorial.txt	2007-08-08 12:58:31 UTC (rev 78700)
@@ -78,15 +78,14 @@
 
   .. _`ez_setup.py`: http://peak.telecommunity.com/dist/ez_setup.py
 
-  This will make ``easy_install-2.4`` available to you.
+  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 automatically upgrade setuptools this by doing::
 
-    $ sudo easy_install-2.4 -U setuptools
+    $ sudo easy_install -U setuptools
 
-
 Setting up grok on a Unix-like (Linux, Mac OS X) environment is
 easy. 
 
@@ -117,7 +116,6 @@
 
   $ 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 Zope 3 and Grok into the project area.
@@ -125,39 +123,6 @@
 .. XXX when grokproject gains a switch for pointing to a shared egg
        directory, mention this here.
 
-.. sidebar:: Problems running ``grokproject``
-
-  During the run of ``grokproject`` many things can go wrong. Problems
-  that happen easily:
-
-  * No subversion installed
-
-    If you don't have a Zope 3 installation already installed, you need
-    ``Subversion`` installed on the computer, where you want to run
-    ``grokproject``, because the sources of Zope 3 are fetched from a
-    subversion repository during install. Visit the `Subversion site`_
-    to get an appropriate ``Subversion`` client.
-
-    .. _`Subversion site`: http://subversion.tigris.org/
-
-  * Missing ``mkzopeinstance``
-
-    The install of Grok might fail, complaining about a missing file
-    ``mkzopeinstance``. If this happens, it is likely, that you have a
-    configuration file ``.pydistutils.cfg`` in your home directory
-    containing a directive for where to install binaries. Disable this
-    directive putting a comment char (``#``) at the beginning of the
-    line which contains ``install_scripts``. Especially users of MacOS
-    X might encounter this problem. This can also happen, if you use
-    an already installed Zope 3.
-
-    For background information concerning this issue, have a look at
-    the `EasyInstall Custom Installation Locations`_ on the
-    EasyInstall site.
-
-    .. _`EasyInstall Custom Installation Locations`: http://peak.telecommunity.com/DevCenter/EasyInstall#mac-os-x-user-installation
-
-
 grokproject will tell you what it will be creating::
 
   Selected and implied templates:
@@ -1337,37 +1302,7 @@
 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()``. 
-
-.. sidebar:: Containers are not dictionaries
-
-	     Although containers mainly behave like dictionaries, they
-	     are in fact ``BTrees``, balanced trees, which makes them
-	     (beside other advantages) capable of maintaining really
-	     large amounts of objects in an efficient manner. The
-	     difference to ordinary dictionaries counts, where you
-	     want to do something like this::
-
-	        for key in mycontainer.keys(): 
-		     do_something(mycontainer[key])
-
-	     The thing returned by the call to ``keys()`` is *not* a
-	     list (as it is, when you call a dictionarys ``keys()``
-	     method), but an iterable. On each loop the mycontainers
-	     ``next()`` method is called to get the next key. So, if
-	     you, for example, change the number of elements stored in
-	     the container while calling ``do_something()``, you
-	     easily run into trouble. Especially calling
-	     ``del(mycontainer[key])`` will not do, what you might
-	     expect. Instead do the following::
-
-	        for key in list(mycontainer.keys()):
-		     del(mycontainer[key])
-
-             Such, using the ``list()`` function, you get a list of
-             keys instead of an iterable.
-
-Containers do a lot more than Python dictionaries
+``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
@@ -1439,95 +1374,3 @@
 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.
-
-
-Building forms with formlib
-===========================
-
-Up to now, we created forms using basically plain HTML and
-implementing every apect of 'logic' using Python code. This is fine
-for some cases but often you would like to have a more automatic way
-to create forms. There is still a lot of repetition in the code. For
-instance we tell several times what values we would like to
-edit/display and what kind of data we would like to have stored
-therein. Furthermore, when the model we use changes slightly, we have
-to maintain a lot of associated logic. Every piece of validation code
-has to be reviewed and eventually rewritten. Last not least you cannot
-easily reuse your existing validation for other models, where you have
-a similar kind of data. 
-
-It would be nice, if we could just tell what kind of data we
-have and get appropriate forms without too much hassle. This is
-possible with grok and it is easy.
-
-.. sidebar:: `zope.formlib`: the name of the magic behind forms.
-
-
-  Grok does nearly nothing to provide the magic of forms as discussed
-  here. Instead it makes use of a package quite popular in Zope 3, the
-  `zope.formlib` package.
-
-  You can learn more about ``formlib`` in the documentation, which
-  comes with the package itself:
-
-    http://svn.zope.org/zope.formlib/trunk/src/zope/formlib/form.txt
-
-
-In Grok the creation of forms is supported by special form objects:
-``grok.EditForm``, ``grok.DisplayForm`` and ``grok.AddForm``. These
-are in fact ``grok.Views`` as well, but offer in addition a special
-machinery, which helps you to generate forms (in extreme) without even
-a single line of HTML code.
-
-
-Let's create a simple Form using ``grok.EditForm``. For that purpose
-we start with the application as coded above in section `Storing
-data`_ but we turn the ``Edit`` class in ``app.py``, which is a
-``grok.View`` into a ``grok.EditForm`` and import a ``schema`` called
-``TextLine`` at the beginning:
-
-.. include:: groktut/building_forms_with_formlib/src/sample/app.py
-  :literal:
-
-When you view the edit form of this application going to
-
-  http://localhost:8080/test/edit
-
-you will see an input field labeled `Text to store:` and a button
-entitled `Store`. This is nothing new. Ugh? What happened? The reason
-is, that there is still a template ``edit.pt`` associated with our new
-form, which renders the form the good old fashioned way and makes no
-use at all from our new class. You *can* specify page templates to
-render the output of forms, just as you can do with ordinary
-``grok.View``, but you don't have to. Now remove the page template
-``edit.pt``.
-
-  $ rm app_templates/edit.pt
-
-and restart your Zope instance.
-
-When you look again at
-
-  http://localhost:8080/test/edit
-
-you should be able to notice some changes: There will be an asterisk
-(`*`) in front of the field label, indicating that this field is a
-required one. The text of the submit button should have turned to
-`Apply`. This is the look of a form that was completely
-autogenerated. Note, that we didn't write one line of HTML to get a
-complete form. And it works.
-
-If you leave the text in the field untouched and click the `Apply`
-button, you will get a message on top, telling you that there were no
-changes.
-
-If you change the text and apply a new value, the form will display a
-timestamp instead, telling that the data was
-updated. Congratulations. You created your first *real* form with
-Grok. Looking back to the first forms created above, they appear
-nowmere as some conglomeration of Python code and HTML wich just
-accidently happens to be a HTML form.
-
-Defining field types using schemas
-----------------------------------
-



More information about the Checkins mailing list