[Checkins] SVN: grok/branches/ulif-reference/doc/reference/ Minimal reference changes.

Uli Fouquet uli at mediamorphose.org
Thu May 31 22:39:04 EDT 2007


Log message for revision 76067:
  Minimal reference changes.

Changed:
  U   grok/branches/ulif-reference/doc/reference/README.txt
  U   grok/branches/ulif-reference/doc/reference/components.tex
  D   grok/branches/ulif-reference/doc/reference/mkgrokref.py

-=-
Modified: grok/branches/ulif-reference/doc/reference/README.txt
===================================================================
--- grok/branches/ulif-reference/doc/reference/README.txt	2007-05-31 23:17:05 UTC (rev 76066)
+++ grok/branches/ulif-reference/doc/reference/README.txt	2007-06-01 02:39:01 UTC (rev 76067)
@@ -42,33 +42,3 @@
 
   /usr/lib/python2.4/doc/tools/mkhowto
 
-
-Generating the grok reference from grok source code
----------------------------------------------------
-
-.. warning:: This is work-in-progress and may lead to disappointing
-             results.
-
-The script mkgrokref.py is able to generate the sources for grok
-reference from the grok source code. It must be run with the
-appropriate PYTHONPATH set (i.e.: including the grok package to scan,
-all packages required by grok, namely the zope 3 packages, and the
-python standard packages). See the header of the script for further
-documentation. There are currently no commandline options supported by
-mkgrokref.py.
-
-To get a very plain reference::
-
-  $ python2.4 mkgrokref.py > myreference.txt
-
-This will produce a ReST formatted text file. Go on with::
-
-  $ rst2latex myreference.txt myreference.tex
-
-Transform the ReStructucturedText to LaTeX. Now we got a LaTeX source,
-which can be further processed as described above. For example::
-
-  $ mkhowto --pdf myreference.tex
-
-The rst2latex script is part of the python docutils package.
-

Modified: grok/branches/ulif-reference/doc/reference/components.tex
===================================================================
--- grok/branches/ulif-reference/doc/reference/components.tex	2007-05-31 23:17:05 UTC (rev 76066)
+++ grok/branches/ulif-reference/doc/reference/components.tex	2007-06-01 02:39:01 UTC (rev 76067)
@@ -4,6 +4,7 @@
 functionality in a convenient way.
 
 \section{\class{grok.Adapter}}
+\label{grok-adapter}
 
     Implementation, configuration, and registration of Zope 3 adapters.
 
@@ -15,21 +16,25 @@
             The adapted object.
         \end{memberdesc}
 
-    \begin{bf}Directives:\end{bf}
+        \emph{Directives:}
 
-    \begin{itemize}
-        \item[\function{grok.context(context_obj)}] required, identifies the required object for the
-        adaptation.
+        \begin{methoddesc}{grok.context}{context_obj}
+            required, identifies the required object for the
+            adaptation.
+        \end{methoddesc}
 
-        \item[\function{grok.implements(interface)}] required, identifies the interface the adapter implements.
+        \begin{methoddesc}{grok.implements}{interface}
+            required, identifies the interface the adapter implements.
+        \end{methoddesc}
 
-        \item[\function{grok.name(name)}] optional, identifies the name used for the adapter
-        registration. If ommitted, no name will be used.
-    \end{itemize}
+        \begin{methoddesc}{grok.name}{name}
+            optional, identifies the name used for the adapter
+            registration. If ommitted, no name will be used.
+        \end{methoddesc}
+
     \end{classdesc*}
 
-    \begin{bf}Example:\end{bf}
-
+    \emph{Example:}
     \begin{verbatim}
 class EuropeanToUS(grok.Adapter):
     """A travel-version of a power adapter that adapts european sockets to
@@ -45,13 +50,54 @@
     \end{verbatim}
 
 \section{\class{grok.AddForm}}
+\label{grok-addform}
 
+    Make \module{zope.formlib} forms accessible in \module{grok}.
+
+    \begin{classdesc*}{grok.AddForm}
+      Form for adding content.
+
+        \begin{memberdesc}{template}
+            The associated template to render.
+        \end{memberdesc}
+
+        \begin{memberdesc}[grok.Fields]{form_fields}
+            Fields to render. 
+        \end{memberdesc}
+
+        \emph{Directives:}
+
+        \begin{methoddesc}{grok.context}{context_obj}
+          required, identifies the required object for the adaptation
+          (forms are views and views are adapters).
+        \end{methoddesc}
+
+
+    \end{classdesc*}
+
+    A \class{grok.AddForm} is a \class{grok.Form}. See
+    \ref{grok-form} (\class{grok.Form}) for deeper insights.
+
+    
+    \emph{Example:}
+\begin{verbatim}
+import grok
+from zope import schema
+
+class Mammoth(grok.Model):
+    class fields:
+        name = schema.TextLine(title=u"Name")
+        size = schema.TextLine(title=u"Size", default=u"Quite normal")
+        somethingelse = None
+
+class Add(grok.AddForm):
+    grok.context(Mammoth)
+\end{verbatim}
+
 \section{\class{grok.Annotation}}
 
 \section{\class{grok.Application}}
 
-\section{grok.ClassGrokker}
-
 \section{\class{grok.Container}}
 
     Mixin base class to define a container object. The container supports the
@@ -60,18 +106,211 @@
 
     Typically used together with \class{grok.Model}.
 
+\section{grok.ClassGrokker}
+
+    Grokker for particular classes in a module.
+
+    Subclasses should have a \var{component_class} available.
+
+    This is a base grokker. It exists in \module{grok.components}
+    because it is meant to be subclassed by code that extends grok.
+    Thus it is like \class{grok.Model}, \class{grok.View}, etc. in
+    that they should not be grokked themselves but subclasses of them.
+  
+
 \section{\class{grok.DisplayForm}}
+\label{grok-displayform}
 
+    See \ref{grok-form} (\class{grok.Form}) for deeper insights.
+
 \section{\class{grok.EditForm}}
+\label{grok-editform}
 
+    \begin{classdesc*}{grok.EditForm}
+        Form for editing content.
+
+        \begin{memberdesc}{template}
+            The associated page template to render. If no template is
+            explicitly set, a default page template will be used.
+        \end{memberdesc}
+
+        \begin{memberdesc}[grok.Fields]{form_fields}
+            Fields to render. 
+        \end{memberdesc}
+
+        \emph{Directives:}
+
+        \begin{methoddesc}{grok.context}{context_obj}
+          required, identifies the required object for the adaptation
+          (forms are views and views are adapters).
+        \end{methoddesc}
+
+
+    \end{classdesc*}
+
+    See \ref{grok-form} (\class{grok.Form}) for deeper insights.
+
+    \emph{Example:}
+\begin{verbatim}
+import grok
+from zope import schema
+
+class Mammoth(grok.Model):
+    class fields:
+        name = schema.TextLine(title=u"Name")
+        size = schema.TextLine(title=u"Size", default=u"Quite normal")
+        somethingelse = None
+
+class Add(grok.EditForm):
+    grok.context(Mammoth)
+\end{verbatim}
+
 \section{\class{grok.Form}}
+\label{grok-form}
 
+    Base class for forms, bringing \class{grok.View} and
+    \module{zope.formlib} together.
+
+    \begin{classdesc*}{grok.Form}
+        Grok forms are \module{zope.formlib} forms and
+        \class{grok.View}s.
+
+        Needed, because \module{zope.formlib}'s
+        Forms have \code{update}/\code{render} methods which have
+        different meanings than \class{grok.View}'s
+        \code{update}/\code{render} methods.  We deal with this issue
+        by 'renaming' \module{zope.formlib}'s \function{update()} to
+        update_form() and by disallowing subclasses to have custom
+        render() methods. 
+
+        Usually, you will only use \class{grok.AddForm}
+        (\ref{grok-addform}), \class{grok.EditForm}
+        (\ref{grok-editform}) or \class{grokDisplayForm}
+        (\ref{grok-displayform}).
+
+
+        \begin{memberdesc}[grok.Fields]{form_fields}
+          It is a \class{grok.Fields} representing the fields to
+          render.
+        \end{memberdesc}
+
+        \begin{memberdesc}{template}
+            The associated template. If no template is explicitly
+            given, a default template will be used.
+        \end{memberdesc}
+
+        \begin{methoddesc}{update}{}
+          Subclasses can override this method just like on regular
+          \class{grok.View}s. It will be called before any form
+          processing happens.
+        \end{methoddesc}
+
+        \begin{methoddesc}{update_form}{}
+          Update the form, i.e. process form input using widgets.
+
+          On zope.formlib forms, this is what the update() method is.
+          In grok views, the update() method has a different meaning.
+          That's why this method is called update_form() in grok
+          forms.
+        \end{methoddesc}
+
+        \begin{methoddesc}{render}{}
+          Render the form, either using the form template or whatever
+          the actions returned in form_result.
+        \end{methoddesc}
+
+        \emph{Directives:}
+
+        \begin{methoddesc}{grok.context}{context_obj}
+            required, identifies the required object for the
+            adaptation (forms are adapters).
+        \end{methoddesc}
+
+    \end{classdesc*}
+
+    \emph{Examples:}
+
+    \subsection{Create grok.Fields with keyword parameters and schema fields}
+
+    A \class{grok.Fields} can receive keyword parameters with schema
+    fields.  These should be avaible in the definition order.
+
+\begin{verbatim}
+import grok
+from zope import schema
+
+class Mammoth(grok.Model):
+    pass
+
+class Edit(grok.EditForm):
+    form_fields = grok.Fields(
+        a = schema.TextLine(title=u"Alpha"),
+        b = schema.TextLine(title=u"Beta"),
+        g = schema.TextLine(title=u"Gamma"),
+        d = schema.TextLine(title=u"Delta"))
+\end{verbatim}
+Now we get the fields in right order:
+\begin{verbatim}
+  >>> grok.grok(__name__)
+
+  >>> from zope import component
+  >>> from zope.publisher.browser import TestRequest
+  >>> request = TestRequest()
+  >>> view = component.getMultiAdapter((Mammoth(), request), name='edit')
+  >>> len(view.form_fields)
+  4
+  >>> [w.__name__ for w in view.form_fields]
+  ['a', 'b', 'g', 'd']
+\end{verbatim}
+    
+    \subsection{Forms cannot define a render method}
+
+    \emph{Forms cannot define a render method.} Here we show the case
+    where the EditForm has an explicit template associate with it. 
+
+\begin{verbatim}
+  import grok
+
+  class Mammoth(grok.Model):
+    pass
+
+  class Edit(grok.EditForm):
+    # not allowed to have a render method
+    def render(self):
+        return "this cannot be"
+
+  edit = grok.PageTemplate('Foo!')
+\end{verbatim}
+Leads to:
+\begin{verbatim}
+  >>> grok.grok(__name__)
+  Traceback (most recent call last):
+  ...
+  GrokError: It is not allowed to specify a custom 'render' method for
+  form <class 'grok.tests.form.norender.Edit'>. Forms either use the default
+  template or a custom-supplied one.
+\end{verbatim}
+
+
+
+
+
 \section{\class{grok.GlobalUtility}}
 
 \section{\class{grok.Indexes}}
 
 \section{grok.InstanceGrokker}
 
+    Grokker for particular instances in a module.
+
+    Subclasses should have a \var{component_class} available.
+
+    This is a base grokker. It exists in \module{grok.components}
+    because it is meant to be subclassed by code that extends grok.
+    Thus it is like \class{grok.Model}, \class{grok.View}, etc. in
+    that they should not be grokked themselves but subclasses of them.
+
+
 \section{\class{grok.JSON}}
 
 \section{\class{grok.LocalUtility}}

Deleted: grok/branches/ulif-reference/doc/reference/mkgrokref.py
===================================================================
--- grok/branches/ulif-reference/doc/reference/mkgrokref.py	2007-05-31 23:17:05 UTC (rev 76066)
+++ grok/branches/ulif-reference/doc/reference/mkgrokref.py	2007-06-01 02:39:01 UTC (rev 76067)
@@ -1,374 +0,0 @@
-"""Create grok reference introspecting the grok package.
-
-This script is able to generate reference docs for grok. It consists
-of three classes:
-
- - DocMetaData:
-
-    Pure data collector to collect als configuration drivers.
-
- - APIParser:
-
-    The introspector. Examines the grok package and delivers the
-    elements found as a nested dictionary.
-
- - APIFormatter:
-
-    Formats api-dicts as generated by APIParser in a manner suitable
-    for further processing. Supported formats:
-    
-      - LaTeX
-
-      - ReStructured Text
-
-      - Plain text
-
-The generated output must be processed further to get end-user
-documents, for example by using rst2latex or mkhowto.
-
-To make this script working, the PYTHONPATH environment variable must
-be set properly. It must include the grok sources that should be
-documented.
-
-    
-"""
-
-import grok
-import types
-from zope.app.apidoc import utilities, component, interface
-from zope.app.apidoc.classregistry import ClassRegistry
-from grok.interfaces import *
-
-class DocMetaData:
-    """Meta data for API-doc generation.
-
-    """
-
-    complete = True
-    """Generate docs with title and header or only the chapters."""
-
-    pedantic = False
-    """Generate warnings if missing docstrings are found"""
-    
-    latex_optimized = False
-    """Generate output more suitable for LaTeX """
-
-    sections={"Components":IGrokBaseClasses,
-              "Grok Errors":IGrokErrors,
-              "Directives":IGrokDirectives,
-              "Decorators":IGrokDecorators,
-              "Events":IGrokEvents,
-              "View":IGrokView,
-              "Form":IGrokForm,
-              "Application":IApplication
-              }
-    """Sections we want to see in the reference."""
-    
-    doc_data = { 
-        'title' : "grok reference",
-        'authoraddress' : ("The grok team","<grok-dev at zope.org>"),
-        'release' : "unreleased",
-        'motto' : """``Grok means to understand so thoroughly that the observer becomes a part of the observed -- merge, blend, intermarry, lose identity in group experience. It means almost everything that we mean by religion, philosophy, and science -- it means as little to us (because we are from Earth) as color means to a blind man.'' - Robert A. Heinlein, Stranger in a Strange Land """,
-        'abstract' : """This is the grok reference documentation. It is organized by the Python artefacts that implement the concepts.
-        
-        Grok makes Zope 3 concepts more accessible for application developers. This reference is not intended as introductory material for those concepts. Please refer to the original Zope 3 documentation and the grok tutorial for introductory material."""}
-    """Meta data to incorporate into the reference."""
-
-
-class APIParser:
-    """Create a nested dict of API elements.
-    """
-
-    meta = DocMetaData()
-    
-    def getAttrDocAsDict(self, cls, attrname ):
-        """Examine attribute.
-        """
-        result = {'name':attrname,
-                  'type':None,
-                  'sig':None,
-                  'doc':None}
-        obj = getattr(cls,attrname)
-        typeofobj = type(obj)
-        sig = ""
-        if isinstance(obj, (types.FunctionType, types.MethodType)):
-            sig = utilities.getFunctionSignature(obj)
-        result['type'] = typeofobj
-        result['sig'] = sig
-            
-        doc = ""
-        if (not hasattr(obj, '__doc__')) or (obj.__doc__ is None):
-            if self.meta.pedantic:
-                doc = "\nXXX docstring documentation of attribute missing.\n"
-        else:
-            doc = utilities.dedentString( obj.__doc__ )
-        #doc = replaceEvilChars(doc,self.meta.latex_optimized)
-        result = {'name':attrname,
-                  'type':typeofobj,
-                  'sig':sig,
-                  'doc':doc }
-        return result
-                
-    def getClassDocAsDict(self, clsname):
-        """Examine class of classname.
-        """
-        result = {"name":"grok."+clsname}
-                    
-        if clsname[0] == "_":
-            return None
-                    
-        if clsname in grok.__dict__.keys():
-            cls = grok.__dict__[clsname]
-            reg[clsname] = cls
-        else:
-            # Not a real class, but it might help to keep
-            # informed...
-            return None
-
-        cls_path = "Could not get path"
-        try:
-            cls_path = utilities.getPythonPath(cls)
-        except:
-            pass
-        result['path'] = cls_path
-    
-        doc = ""
-        if not hasattr(cls, '__doc__') or cls.__doc__ is None:
-            if self.meta.pedantic:
-                doc = "\nXXX docstring documentation of class missing.\n"
-        else:
-            doc = utilities.dedentString( cls.__doc__ )
-
-        result['doc'] = doc
-
-        apidoc_parse = ""
-        if hasattr( cls, 'factory'):
-            apidoc_parse = component.getAdapterInfoDictionary(cls)
-        if hasattr( cls, 'component'):
-            apidoc_parse = component.getUtilityInfoDictionary(cls)
-    
-        result['elems'] = []
-        elemlist = utilities.getPublicAttributes(cls)
-        result['elems'] = [self.getAttrDocAsDict(cls,x) for x in elemlist]
-        result['elems'].sort()
-        return result
-        
-
-    def getAPIDict(self,groups_dict):
-        """Get a nested directory containing the grok API
-
-        """
-        result_groups = []
-        for (key,group) in groups_dict.items():
-            result = {'group':key}
-            classes = [x for x in group]
-            classes.sort()
-            result['classes'] = []
-            for clsname in classes:
-                class_api = self.getClassDocAsDict(clsname)
-                if class_api is not None:
-                    result['classes'].append( class_api )
-            result_groups.append( result )
-        return result_groups
-
-
-class APIFormatter:
-    """Helpers to generate readable API doc in various formats.
-    """
-
-    meta = DocMetaData()
-    api_data = None
-
-    def indentText(self,text,num):
-        """Indent long strings.
-
-        XXX broken
-        """
-        result = ""
-        for line in text.split("\n"):
-            result += "%s%s\n" % (" "*num,line)
-        return result
-
-    def replaceEvilChars(self,text):
-        """ Replace evil characters.
-        """
-        replace_tuples = [('$','\$')]
-        for subst in replace_tuples:
-            text = text.replace( subst[0], subst[1] )
-        if self.meta.latex_optimized:
-            replace_tuples = ( (
-                ("\n", "\n\n"),
-                ('\\$\\rightarrow\\$','$\\rightarrow$'),
-                ('->', '$\\rightarrow$'),
-                ('\$>\$', '>'),('\$<\$', '<'),
-                ('>','$>$'), ('<','$<$')) )
-            for subst in replace_tuples:
-                text = text.replace( subst[0], subst[1] )
-        return text
-
-
-    def prepareDocString(self,doc,num):
-        """Indent text lines and split headline from body.
-        """
-        doc = self.indentText(doc,num)
-        doc = self.replaceEvilChars(doc)
-        lines = doc.split('\n')
-        head = doc
-        body = doc
-        if len(lines):
-            head = lines[0]
-            body = '\n'.join(lines[1:])
-        if len(head) > 1:
-            head = " -- %s" % head
-        return (head,body)
-
-    def getTexOutput(self,api_dict):
-        """Transfom api_dict to TeX compatible output.
-        """
-        result = ""
-        if self.meta.complete:
-            result = '''
-\documentclass{manual}
-\RequirePackage[latin9]{inputenc}
-\usepackage{graphicx}
-\\title{%s}
-\\authoraddress{
-  %s
-  Email: %s
-}
-\\date{\\today}
-\\release{%s}
-\makeindex
-\\begin{document}
-\maketitle
-
-%s
-
-\\begin{abstract}
-
-%s
-
-\end{abstract}
-
-\\tableofcontents
-
-\include{core}
-
-''' % (self.meta.doc_data['title'],
-       self.meta.doc_data['authoraddress'][0],
-       self.replaceEvilChars(self.meta.doc_data['authoraddress'][1]),
-       self.meta.doc_data['release'],
-       self.meta.doc_data['motto'],
-       self.meta.doc_data['abstract'],
-       )
-            for group in api_dict:
-                result += "\chapter{%s}\n\n" % group['group']
-                for cls in group['classes']:
-                    (head,body) = self.prepareDocString(
-                        cls['doc'], 6)
-                    body = "\ "+body
-                    result += "  \section{\class{%s%s}}\n\n" % (
-                        cls['name'],head)
-                    result += "    \\begin{classdesc*}{%s%s}\n\n" % (
-                        cls['name'],head)
-                    result += "%s\n"%body
-                    for elem in cls['elems']:
-                        result += "      \\begin{memberdesc}{%s%s}\n"% (
-                            elem['name'], elem['sig'] )
-                        result += self.replaceEvilChars(elem['doc']) + "\n\n"
-                        result += "      \end{memberdesc}\n\n"
-                    result += "    \end{classdesc*}\n\n"
-
-        if self.meta.complete:
-            result += "\n\end{document}"
-        return result
-
-
-    def getPlainOutput(self,api_dict):
-        """Grok API as plain text
-        
-        Returns a long string representing the api_dict given.
-        """
-        result = ""
-        for section in api_dict:
-            print section['group']
-            for cls in section['classes']:
-                print "  " + cls['name']
-                doc = self.indentText( cls['doc'], 6)
-                print "%s" % doc
-                for elem in cls['elems']:
-                    print "    " + elem['name'] + elem['sig']
-                    doc = self.indentText( elem['doc'], 10)
-                    print doc
-        return result
-
-    def getReSTOutput(self,api_dict):
-        """Grok API as ReStructuredText.
-        
-        Returns a long string representing the api_dict given.
-        """
-        result = ""
-        doc_data = self.meta.doc_data
-
-        if self.meta.complete:
-            # Generate header...
-            result += "\n%s %s\n\n%s\n\n%s\n\n%s\n%s\n%s\n\n" % (
-                ".. title ", doc_data['title'],
-                ".. sectnum::",
-                ".. |date| date::",
-                "="*len(doc_data['title']),
-                doc_data['title'],
-                "="*len(doc_data['title']))
-
-            # Add table of contents...
-            result += "%s\n\n" % (
-                ".. contents:: Table of Contents",
-                )
-        
-        for section in api_dict:
-            result += "%s\n%s\n\n" % (
-                section['group'],
-                "=" * len(section['group']))
-            for cls in section['classes']:
-                result += "\n%s\n%s\n\n" % (
-                    cls['name'],
-                    "-" * len(cls['name']))
-                doc = self.indentText( cls['doc'], 0)
-                result += "%s\n\nMethods and Attributes:\n\n" % (doc,)
-                for elem in cls['elems']:
-                    result += "   - %s%s:\n\n" %( elem['name'], elem['sig'] )
-                    doc = self.indentText( elem['doc'], 10)
-                    result += "%s\n" % (doc,)
-        return result
-
-# Fill class registry with all grok elements...
-reg = ClassRegistry()
-for name in grok.__dict__.keys():
-    if name[0] == "_":
-        continue
-    reg[name] = grok.__dict__[name]
-
-
-if __name__ == "__main__":
-    meta = DocMetaData()
-    parser = APIParser()
-    parser.meta = meta
-    api_dict = parser.getAPIDict(meta.sections)
-
-
-    #for section in result:
-    #    print section['group']
-    #    for cls in section['classes']:
-    #        print "  " + cls['name']
-    #        for elem in cls['elems']:
-    #            print "    " + elem['name'] + elem['sig']
-
-    formatter = APIFormatter()
-    formatter.meta = meta
-    tex_output = formatter.getTexOutput( api_dict )
-    #print tex_output
-
-    #formatter.getPlainOutput( api_dict )
-    
-    rest_output = formatter.getReSTOutput( api_dict )
-    print rest_output



More information about the Checkins mailing list