[Checkins] SVN: grok/trunk/doc/reference/directives.rst more editing to the directives page for the ref docs. brings things up to date for the 0.14 version

Kevin Teague kevin at bud.ca
Thu Sep 25 22:07:28 EDT 2008


Log message for revision 91496:
  more editing to the directives page for the ref docs. brings things up to date for the 0.14 version

Changed:
  U   grok/trunk/doc/reference/directives.rst

-=-
Modified: grok/trunk/doc/reference/directives.rst
===================================================================
--- grok/trunk/doc/reference/directives.rst	2008-09-26 01:24:42 UTC (rev 91495)
+++ grok/trunk/doc/reference/directives.rst	2008-09-26 02:07:28 UTC (rev 91496)
@@ -20,7 +20,7 @@
 Core directives
 ~~~~~~~~~~~~~~~
 
-:func:`grok.context` -- Declare the context for views, adapters, etc.
+:func:`grok.context` -- declare the context for views, adapters, etc.
 =====================================================================
 
 .. function:: grok.context(*class_or_interface)
@@ -40,7 +40,7 @@
     another module as context, than the one choosen by default, then you
     have to call :func:`grok.context` explicitly.
 
-**Example:**
+**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
@@ -85,8 +85,12 @@
     semantics of this directive: for what exactly a name is set when
     using this directive, depends on the component.
 
-**Example:**
+**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
@@ -94,8 +98,6 @@
     class Mammoth(grok.Model):
       pass
 
-    # a common use case is to have a URL for a view named differently than
-    # the name of the view class itself.
     class SomeView(grok.View):
        grok.name('index')
 
@@ -108,7 +110,7 @@
     :class:`grok.View`
 
 
-:func:`grok.title` -- Succincint description
+:func:`grok.title` -- succincint description
 ============================================
 
 .. function:: grok.title(*arg)
@@ -129,8 +131,12 @@
     :func:`grok.implements` is currently an alias for
     :func:`zope.interface.implements`.
 
-**Example:**
+**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
@@ -143,12 +149,18 @@
     class Cave(object):
         pass
 
-    cave = Cave()
-    IPaintable.providedBy(cave)
+You can create a `Cave` object and query the `IPaintable` interface to see if
+an object provides that interface:
 
-This would return `False` since Cave does not implement the IPaintable
-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):
@@ -156,16 +168,26 @@
 
         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:
     
-    cave = PaintableCave()
-    IPaintable.providedBy(cave)
-    
-This would return `True` since the PaintableCave class declares that it
-implements the IPaintable 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` -- Declare, that a component provides a certain interface
-===============================================================================
+:func:`grok.provides` -- declare that a component provides an interface
+=======================================================================
 
 .. function:: grok.provides(interface)
 
@@ -178,7 +200,7 @@
     :func:`grok.implements`
 
 
-:func:`grok.adapts` -- Declare that a class adapts certain objects
+:func:`grok.adapts` -- declare that a class adapts certain objects
 ==================================================================
 
 .. function:: grok.adapts(*classes_or_interfaces)
@@ -191,8 +213,11 @@
     It works much like the :mod:`zope.component`\ s :func:`adapts()`,
     but you do not have to make a ZCML entry to register the adapter.
 
-**Example:**
+**Example: Register a MammothSize adapter for Mammoths**
 
+Imagine you want to create an adapter that extends a Mammoth object
+with an ISized interface. Your code could look like this:
+
 .. code-block:: python
 
     import grok
@@ -219,18 +244,16 @@
         def sizeForDisplay(self):
             return ('1000 bytes')
 
-Having :class:`MammothSize` available, you can register it as an adapter,
-without a single line of ZCML:
+When this code is "grokked" that `MammothSize` class is registered as
+an adapter that provides ISized for IMammoth objects. You could then 
+perform adaptation elsewhere in your code with:
 
 .. code-block:: python
 
     manfred = Mammoth()
-    from zope.component import provideAdapter
-    provideAdapter(MammothSize)
     from zope.size.interfaces import ISized
     size = ISized(manfred)
-    size.sizeForDisplay()
-    # would return '1000 bytes'
+    return size.sizeForDisplay()
 
 .. seealso::
 
@@ -243,20 +266,17 @@
 .. function:: grok.baseclass()
 
     A class-level directive without argument to mark something as a base
-    class. Base classes are are not grokked.
+    class. Base classes are not grokked.
 
-    Another way to indicate that something is a base class, is by
-    postfixing the classname with ``'Base'``.
-
     The baseclass mark is not inherited by subclasses, so those
-    subclasses will be grokked (except they are explicitly declared as
+    subclasses will be grokked (except if they are also explicitly declared as
     baseclasses as well).
 
-**Example:**
+**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:`ViewBase` or :class:`AnotherView`
-will lead to a :exc:`ComponentLookupError`.
+view, while calling the :class:`AnotherView` will lead to a
+:exc:`ComponentLookupError`.
 
 .. code-block:: python
 
@@ -265,10 +285,6 @@
     class ModelBase(grok.Model):
         pass
 
-    class ViewBase(grok.View):
-        def render(self):
-            return "hello world"
-
     class AnotherView(grok.View):
         grok.baseclass()
 
@@ -309,7 +325,7 @@
     Another way to register global utilities with Grok is to subclass from
     :class:`grok.GlobalUtility`.
 
-**Example:**
+**Example: Register two GlobalUtilities and use them**
 
 Given the following module code:
 
@@ -384,7 +400,7 @@
     An alternative way to define a local utility is to subclass from
     :class:`grok.LocalUtility`.
 
-**Example:**
+**Example: Register a local utility**
 
     The following code registers a local unnamed utility `fireplace` in
     instances of :class:`Cave`
@@ -412,8 +428,8 @@
 Security directives
 ~~~~~~~~~~~~~~~~~~~
 
-:func:`grok.require`
-====================
+:func:`grok.require` -- declare a permission 
+============================================
 
 .. function:: grok.require(permission)
 
@@ -422,13 +438,20 @@
 
 `permission` -- the name of the permission that is required
 
-**Example**
+**Example 1: Define a Permission and use it to protect a View**
 
 .. code-block:: python
 
-    class ViewPainting(grok.Permission):
-    grok.name('grok.ViewPainting')
+    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
@@ -437,44 +460,39 @@
 Template directives
 ~~~~~~~~~~~~~~~~~~~
 
-:func:`grok.template`
-=====================
+:func:`grok.template` -- specify a template filename
+====================================================
 
 A class level directive used to specify the template to be rendered
-for the View when no render method is defined.
+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
 
-    **Convention**
-
-    When not specified, Grok will look for a template file with the same
-    name as the view class itself, lowercased, in the templates directory
-    for this module.
-
 .. seealso::
 
     :func:`grok.templatedir`
 
 
-: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
-
-    **Convention**
-
-    When not specified, Grok will look template files in a diretory
-    named `<module>_templates` where `<module>` is the name of the current
-    module.
-
+    
 .. seealso::
 
     :func:`grok.template`
@@ -483,8 +501,8 @@
 Component registry directives
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-:func:`grok.site`
-=================
+: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.
@@ -505,8 +523,8 @@
 URL Traversal directives
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
-:func:`grok.traversable`
-========================
+: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



More information about the Checkins mailing list