[Checkins] SVN: zope3docs/source/ Copy current state of coding style documentation from wiki.

Christian Theune ct at gocept.com
Wed Feb 18 08:21:55 EST 2009


Log message for revision 96696:
  Copy current state of coding style documentation from wiki.
  
  ReST cleanup has been applied to the Python coding style document,
  others still have to be cleaned up.
  

Changed:
  A   zope3docs/source/codingstyle/
  A   zope3docs/source/codingstyle/checkin-guidelines.rst
  A   zope3docs/source/codingstyle/classesattributesmethods.rst
  A   zope3docs/source/codingstyle/file-structure.rst
  A   zope3docs/source/codingstyle/glossary.rst
  A   zope3docs/source/codingstyle/index.rst
  A   zope3docs/source/codingstyle/interface-style.rst
  A   zope3docs/source/codingstyle/nameskeysids.rst
  A   zope3docs/source/codingstyle/optimizations.rst
  A   zope3docs/source/codingstyle/python-naming.rst
  A   zope3docs/source/codingstyle/python-style.rst
  A   zope3docs/source/codingstyle/servicesevents.rst
  A   zope3docs/source/codingstyle/todocomments.rst
  A   zope3docs/source/codingstyle/writingtests.rst
  A   zope3docs/source/codingstyle/zcml-style.rst
  U   zope3docs/source/index.rst

-=-
Added: zope3docs/source/codingstyle/checkin-guidelines.rst
===================================================================
--- zope3docs/source/codingstyle/checkin-guidelines.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/checkin-guidelines.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,19 @@
+Please be careful before a check in to make sure:
+
+ - All the code you are about to check in has reasonable test coverage.
+   If you want to check in partial code in order to collaborate remotely,
+   do so in a branch.
+
+ - All the tests pass. Running individual tests for the code you are working on is fine
+   while developing, but immediately before a check in, all tests must be run.
+
+   Build environments based on buildout usually do so by running::
+
+      bin/test --all
+
+ - Use 'svn status' to make sure you have added any new files to the
+   repository.  Alternatively you could make a fresh checkout before running
+   the tests.
+
+ - Please be aware of the version of Python you use. The recommended and
+   supported versions of Python vary over time (also they do so slowly).

Added: zope3docs/source/codingstyle/classesattributesmethods.rst
===================================================================
--- zope3docs/source/codingstyle/classesattributesmethods.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/classesattributesmethods.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,78 @@
+1. General
+
+  For everything these pages are not mentioning, we are using the style
+  specified by the Python Style Guide. Most of the code I have seen in Zope 3
+  so far uses the "capatalize new words" instead of  "separate words by _" 
+  style. Also, in general long names are more descriptive than short ones. 
+  For example "speedOfLight" is much better than simply "c".
+
+
+2. Classes
+
+  Classes should *always* start with a capital letter. 
+  Examples::
+
+    Folder
+    HTTPRequest
+    HTTPViewRegistry
+    ThisIsAVeryLongClassName
+
+
+3. Attributes / Properties
+
+   Attributes always start with a lower case letter. Boolean-type attributes
+   should always form a true-false-question, typically using "has" or "is" 
+   as prefix.
+   Examples::
+     
+     title
+     cssClass
+     isRequired (boolean)
+
+4. Methods
+
+   Methods also should start with a lower case letter. The first word of a 
+   method should always be a verb that describes the action.
+   Examples::
+
+     executeCommand()
+     save()
+     convertValueToString()
+
+<hr solid id=comments_below>
+
+
+gvanrossum (Jan 28, 2002 12:25 pm; Comment #1)  --
+ An important guideline would be to explain when it is appropriate
+ for a method or instance variable name to start with an underscore.
+ 
+bwarsaw (May 24, 2002 11:10 am; Comment #2)  --
+ Guido's right, it would be helpful to understand Jim's recommendations regarding leading underscores.  Here's mine, FWIW:
+ 
+ - no leading underscores on public methods or attributes
+ 
+ - a double leading underscore for names which describe private methods or attributes.
+ 
+ - a single leading underscore for names which are not part of the public interface, but which might be of interest to subclasses.
+ 
+ Yes, this means you should design for inheritance!  At the very least you need to decide what the contract is between subclasses and superclasses, and I typically represent these decisions with single-underscore names.  However, when in doubt, use single underscores instead of double underscores, otherwise it's a real pain to subclass.
+ 
+klm (May 24, 2002 11:36 am; Comment #3)  --
+ <pre>
+ > bwarsaw (May 24, 2002 11:10 am; Comment #2)  --
+ > [...]
+ >  - a double leading underscore for names which describe private methods
+ >    or attributes.
+ >  
+ >  - a single leading underscore for names which are not part of the public
+ >    interface, but which might be of interest to subclasses.
+ </pre>
+ 
+ I do **not** think it's a good idea to use a name-mangling double underscore except when you actually *expect* that subclasses will need distinct but identically named methods (and ones which will not directly call the superclass versions, of course).  (Maybe double underscore is also useful to protect some critical class invariant that uninformed use of the method would betray, but even there a decent warning in the code should suffice.)
+ 
+ Why the emphatic tone?  I have had grief developing against code where the other developer had used double underscores because *they* weren't going to use the method in a subclass - preventing me when i legitimately needed to do so.  
+ 
+ Further, double underscores impede interactive debugging - arriving in a context where things are already going wrong, and needing to scramble to uncover the mangling rule so you can invoke an obscured method, compounds the pain of the moment - and breaks pdb-track, besides.
+ 
+ Please, avoid idealistic use of double-underscores - a single underscore is sufficient to signal intent, and does not present obstacles that are often unnecessary and sometimes counterproductive.
+ 

Added: zope3docs/source/codingstyle/file-structure.rst
===================================================================
--- zope3docs/source/codingstyle/file-structure.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/file-structure.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,283 @@
+Here I would just like to look at Python Source Files. These files should always contain the most actual license comment at the top followed by the
+module documentation string. The doc string will contain a reference about 
+its CVS status in the first line; then the documentation follows. 
+Here is the template::
+
+  ##############################################################################
+  #
+  # Copyright (c) 2002 Zope Corporation and Contributors. 
+  # All Rights Reserved.
+  # 
+  # This software is subject to the provisions of the Zope Public License,
+  # Version 2.0 (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
+  # 
+  ##############################################################################
+  """One-line summary goes here.
+
+  Module documentation goes here.
+
+  $Id$
+  """
+
+Notes:
+
+  - Doc strings:
+
+    o The first line of the doc string should include a one-line
+      description of the module (or class or function).
+
+    o The first line may be followed by additional documentation
+      paragraphs, if needed. The additional paragraphs must be separated
+      from surrounding text and from each other by blank lines.
+    
+    o The revision id should come last.
+
+    Here's an example::
+
+      """Implement foo interfaces
+
+      Blah blah
+
+      blah some more
+
+      $Id$
+      """
+
+  - Imports
+
+    o All imports should be at the top of the module, after the module
+      docstring and/or comments, but before module globals.
+
+      It is sometimes necessary to violate this to address circular
+      import pronlems. If this is the case, add a comment to the
+      import section at the top of the file to flag that this was done.
+
+    o Ordering
+
+      - Start with imports for standard Python library modules
+
+      - Next come imports from other parts of the Zope library
+
+      - Next come imports from other parts of the current superpackage
+
+      - Last come imports from the current package
+
+      Leave a blank line between each group of imports
+
+
+<hr>
+
+Some questions and suggestions (Guido):
+
+Should the copyright years be exactly those years where this specific
+module is changed?  Or should they always be 2001, 2002?  In a few years,
+should we write 2001, 2002, 2003, 2004, 2005, or should we write
+2001-2005?
+
+  JimFulton -- I have no idea. Do *you* know the rules for this? If
+    so, please add another note.
+
+    I snipped your comments that I think I covered.
+
+Here are my preferences for import order (partly gleaned from
+Barry's preferences):
+
+- Use this::
+
+    import os
+    import sys
+
+  rather than this::
+
+    import os, sys
+
+  JimFulton -- Gulp. I dunno about this. Do you feel strongly about
+    this? Do you think this represents concensus in the Python community?
+
+- Refrain from using relative imports.  Instead of::
+
+    import foo # from same package
+
+  you can write::
+
+    from Zope.App.ThisPackage import foo
+
+  JimFulton -- Why is this a good thing?  This makes moving packages a
+    bit harder than it already is.
+
+    I **really** wish Python's import had a mechanism to reference
+    modules in containing packages without resorting to full paths.
+
+ 
+
+
+<hr solid id=comments_below>
+
+
+gvanrossum (May 24, 2002 11:44 am; Comment #2)  --
+ On how to write multiple copyright years: someone should ask a lawyer.
+ I know the FSF insists that you list each year separately, but I'm
+ not sure all lawyers agree with them; I find the long form overly verbose.
+ 
+ Om multiple imports per line: I don't feel strongly about this at all;
+ it seems right since the Zope imports are generally so long that you
+ do one module per line anyway, so why not do this for the Python modules.
+ 
+ On relative imports: if you move a package, you have to do a global edit
+ on all its *users* anyway, so why not include the package itself among
+ those users.  I think Tim came up with this rule, after years of experience
+ at Dragon.  I believe his reasoning was: a global edit is easy; figuring
+ out which imports are relative and which aren't (and what happens when
+ there's both a local and a global module with the same name) is hard.
+ 
+klm (May 24, 2002 11:48 am; Comment #3)  --
+ <pre>
+ > Some questions and suggestions (Guido):
+ > - Refrain from using relative imports.  Instead of::
+ > 
+ >     import foo # from same package
+ > 
+ >   you can write::
+ > 
+ >     from Zope.App.ThisPackage import foo
+ > 
+ >   JimFulton -- Why is this a good thing?  This makes moving packages a
+ >     bit harder than it already is.
+ > 
+ >     I **really** wish Python's import had a mechanism to reference
+ >     modules in containing packages without resorting to full paths.
+ </pre>
+ 
+ I *really* wish Python's import had a mechanism to explicitly signal relative imports, and supported them in a more thorough way.  Guido, i know you don't accept punctuation shorthand like 'import ..sibling_module' for relative imports, but i think *some* explicit signification would reduce or eliminate the  drawbacks to relative imports.  And face it, the tension has persisted over this issue - legitimately, i would surmise - through the life of package imports.
+ 
+efge (May 24, 2002 11:49 am; Comment #4)  --
+ <pre>
+ > Should the copyright years be exactly those years where this specific
+ > module is changed?  Or should they always be 2001, 2002?  In a few years,
+ > should we write 2001, 2002, 2003, 2004, 2005, or should we write
+ > 2001-2005?
+ </pre>
+ 
+ Apparently (see "here":http://www.loc.gov/copyright/circs/circ03.html )
+ only the year of first publication is required. Maybe this is US-specific though.
+ 
+klm (May 24, 2002 11:55 am; Comment #6)  --
+ I was writing my last comment while guido committed his.  One piece is actually addressed by what i was trying to say:
+ 
+ <pre>
+ > gvanrossum (May 24, 2002 11:44 am; Comment #2)  --
+ >  at Dragon.  I believe his reasoning was: a global edit is easy; figuring
+ >  out which imports are relative and which aren't (and what happens when
+ >  there's both a local and a global module with the same name) is hard.
+ </pre>
+ 
+ If relative imports were signalled explicitly, then figuring out which imports are relative and which aren't would *not* be hard.  (Even just an extra leading '.' would make the distinction obvious!)
+ 
+gvanrossum (May 24, 2002 12:02 pm; Comment #7)  --
+ Yeah, but following Tim's advice, it would be even better if relative
+ imports weren't possible at all.
+ 
+ Java doesn't have them AFAIK.
+ 
+bwarsaw (May 24, 2002 12:04 pm; Comment #8)  --
+ On copyright years: the FSF's convention is to spell out all the years, but to only include years in which the file is actually "published" with "existing in cvs" not included in "published".
+ 
+ I.e. Foo.py was created in 2001 and was part of a tarball release in 2001 and 2002.  It should by copyright 2001,2002
+ 
+ Bar.py was created in 2001 but not published in a tarball until 2002.  It should be copyright 2002.
+ 
+bwarsaw (May 24, 2002 12:07 pm; Comment #9)  --
+ All imports on a separate line: I strongly prefer them because I find them easier to edit (kill a line is easier than highlight some word -- plus the comma! -- in the middle of a line).  More importantly, a file should contain *only* the imports it needs.  If the thing being imported isn't used anywhere (assuming no import side effects <wink>), then it shouldn't be imported.
+ 
+ -1 on relative imports
+ 
+hathawsh (May 24, 2002 12:53 pm; Comment #10)  --
+ I've been experimenting with a convention that clarifies imports for the reader: imports from the standard library come first, imports from other packages second, and imports within the package last.  Each group is separated by a blank line.
+ 
+ OTOH I've seen others do the reverse. :-)
+ 
+ I agree with the assessment that relative imports make it harder to find dependencies using grep, but on the other hand, it's harder to write new code when you are required to use absolute imports.  I usually don't know what I want to call a package until it's nearly finished.  Ken, I'm sure there are other reasons relative imports are helpful; can you think of any?
+ 
+klm (May 24, 2002 1:42 pm; Comment #11)  --
+ <pre>
+ > hathawsh (May 24, 2002 12:53 pm; Comment #10)  --
+ > ![...]
+ >  usually don't know what I want to call a package until it's nearly
+ >  finished.  Ken, I'm sure there are other reasons relative imports
+ >  are helpful; can you think of any?
+ </pre>
+ 
+ Well, off the top of my head:
+ 
+ - It certainly shortens import lines when your, eg, package has nesting
+   and long names::
+ 
+     from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+ 
+   vs, eg::
+ 
+     import .PageTemplateFile
+ 
+ - It simplifies packaging an application with custom versions of
+   standard items::
+ 
+     from .lib import email, mimetypes
+ 
+   That *can* be done using mangling of os.path manipulation - but
+   mangling of os.path seems to me to be fatally flawed.  It affects all
+   other modules in the python process, including potentially other
+   applications with their own libraries.  Pshaw.  What this approach
+   begs for, to work, is a package-specific path - which is what the
+   relative import is all about.
+ 
+ - Of course, sometimes you want to be able incorporate functionality
+   from other packages in yours, without exposing or even using the
+   whole application.  With hard-coded full paths, you can't just move
+   it, or pieces of it, into your application.
+ 
+ Addressing another message:
+ 
+ <pre>
+ > gvanrossum (May 24, 2002 12:02 pm; Comment #7)  --
+ >  Yeah, but following Tim's advice, it would be even better if relative
+ >  imports weren't possible at all.
+ </pre>
+ 
+ I was reading your excerpt as saying relative imports are bad because
+ they're hard to recognize, and arguing that's a valid criticism of the
+ current implementation that should be fixed - thus mitigating that
+ drawback of relative imports.
+ 
+ <pre>
+ >  Java doesn't have them AFAIK.
+ </pre>
+ 
+ Java is a much more rigid language than python, in general.  It makes
+ some sense that (1) it expects to have every package occupy its own
+ top-level namespace ("com.sun"), and (2) it seems to inherently have
+ more obstacles to mixing things together, what with static typing, no
+ mixins, less genericity overall.  Python is quite different in these
+ aspects.  I wouldn't assume that rigidity in java's import approach
+ applies to python.  (Java takes a quite different approach to
+ polymorphism, for example, based on static typing of method
+ parameters, which doesn't apply in the context of python classes...)
+ 
+hathawsh (May 24, 2002 2:17 pm; Comment #12)  --
+ Let me clarify Java's approach: imports from other packages are all absolute, but imports within a package are *implicit*.  That is to say, every other public class in your package is automatically in your namespace.  Java can do this because it also requires a file to define only one public class, the class name must match the filename, and there is no visible distinction between modules and public classes.
+ 
+ Also, Java makes imports a little clearer since there is no need for the "from" keyword and names don't tend to get duplicated like they do in Python ("from Products.ExternalMethod.ExternalMethod import ExternalMethod")
+ 
+ We don't want Java's limitations, of course.  This is only something to think about.
+ 
+rdmurray (May 24, 2002 2:28 pm; Comment #13)  --
+ In a lot of python files I've seen::
+ 
+     __version__ = "$Id$"
+ 
+ and while I've never actually *used* the __version__ variable for anything, it has
+ a rather pythonic feel to it that pleases me <grin>.
+ 

Added: zope3docs/source/codingstyle/glossary.rst
===================================================================
--- zope3docs/source/codingstyle/glossary.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/glossary.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,13 @@
+This is a list of some common words that should have the same meaning throughout Zope.  It is not exhaustive.
+
+  'key' -- See NamesKeysAndIds
+
+  'id' -- See NamesKeysAndIds
+
+  'manager' --
+    1. A user that configures components, such as a SiteManager.  2. An object that performs through the web configuration, such as a ServiceManager (which allows site managers to configure services.)
+
+    Generally, the word 'manager' is inappropriate for objects that don't perform through-the-web configuration.  For example, global "service services" are not configurable through the web, but they were once called "service managers", and have now been renamed, since the name caused confusion with through-the-web configurable service managers.
+
+  'name' -- See NamesKeysAndIds
+

Added: zope3docs/source/codingstyle/index.rst
===================================================================
--- zope3docs/source/codingstyle/index.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/index.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,27 @@
+Zope 3 coding style
+===================
+
+This area explains certain style elements (how to layout code written in
+Zope 3 projects, naming conventions) that are intended to help with
+achieving and maintaining a consistent code base.
+
+.. note::
+    TODO This area includes code from the original Zope 3 wiki and needs
+    gardening work.
+
+.. toctree::
+    :maxdepth: 1
+
+    checkin-guidelines
+    classesattributesmethods
+    file-structure
+    glossary
+    interface-style
+    nameskeysids
+    optimizations
+    python-naming
+    python-style
+    servicesevents
+    todocomments
+    writingtests
+    zcml-style

Added: zope3docs/source/codingstyle/interface-style.rst
===================================================================
--- zope3docs/source/codingstyle/interface-style.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/interface-style.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,146 @@
+Defining Interfaces
+
+  Status: IsDraft
+
+  1. All public interfaces should go into a file called 'interfaces.py'. 
+     By "public" I mean interfaces that you expect to be implemented more
+     than once. Interfaces that are likely to be implemented only once,
+     like 'IGlobalAdapterService', should live in the same module as their
+     implementation.
+
+  2. The interface name should always start with an "I", for example 
+     "ITranslationDomain".
+
+  3. One function of interfaces is to document functionality, so be very 
+     verbose with the documentation strings.
+
+  4. You should always derive from the Interface "class" somewhere in your inheritance 
+     tree.
+
+
+  Example::
+
+    from Interface import Interface
+
+    class IDublinCoreTitle(Interface):
+         """This interface will provide a title handler for common 
+            content objects.
+         """
+
+         def getTitle():
+             """Get the title from the object."""
+ 
+         def setTitle(title):
+             """Set the title of the object."""
+     
+
+Using Interfaces
+
+  1. Declare that a class or module implements an interface by 
+     using 'zope.interface.implements'::
+
+       from zope.interface import Interface, implements
+
+       class IFoo(Interface):
+            pass
+
+       class Foo(object):
+            implements(IFoo)
+
+  2. To directly declare that an object provides an interface, use 
+     'zope.interface.directlyProvides' or 'zope.interface.alsoProvides'::
+
+       from zope.interface import Interface, directlyProvides
+
+       class IFoo(Interface):
+            pass
+
+       class Foo(object):
+            pass
+
+       foo = Foo()
+       directlyProvides(foo, IFoo)
+
+     But be careful, 'direclyProvides()' can only be used once and does not 
+     accumulate provided interfaces.   'alsoProvides()' is often preferable
+     since it strictly augments the set of provided interfaces.
+
+
+<hr solid id=comments_below>
+
+
+hathawsh (Jan 26, 2002 10:15 pm; Comment #1)  --
+ I try to use a convention for interface documentation that I first noticed in Java interfaces.  I write in the present tense rather than the imperative tense.
+ 
+ An example of imperative tense: "Write the message to stdout and return".
+ 
+ An example of present tense: "Writes the message to stdout and returns".
+ 
+ The distinction seems very subtle at first.  But the distinction is meaningful and, at least for me, quite helpful.  When I saw this pattern in the documentation for the Java standard library and started applying it, I chipped away a lot of my "interface writer's block" and finally knew what to write.
+ 
+ When you write in the imperative tense you are effectively giving instructions to the computer.  Choose the imperative tense when you are describing what a block of code is supposed to do in a more human-readable form.
+ 
+ But interfaces specify a contract, not an implementation.  So the interface documentation should describe what each method does, not how.  The present tense encourages you to do this.
+ 
+ One minor drawback is that you end up with incomplete sentences since you usually drop off the subject.  But don't prepend "This method..." or "This class..." to all of your interface documentation strings since that is just redundant.  Incomplete sentences are appropriate in certain contexts.
+ 
+ So I would change the example above to read::
+ 
+   class IDublinCoreTitle(Interface):
+        """Provides access to the Dublin Core title property.
+        """
+ 
+        def getTitle():
+            """Gets the title from the object."""
+  
+        def setTitle(title):
+            """Sets the title of the object."""
+ 
+ 
+ Note that converting to present tense uncovered a minor problem with the interface: there is no reason (currently) that the interface can only be applied to "common content objects", so I took that part out.  That docstring was actually in the future tense, which unconsciously puts you in the mindset of planning for the future.
+ 
+ This is only a suggestion based on my own experience.  Your choice of tense and person (1st, 2nd, or 3rd person) has unconscious effects on you as a writer.  If you choose the right tense and person, you're more likely to communicate effectively.
+ 
+ 
+fdrake (May 24, 2002 10:08 am; Comment #2)  --
+ I definately agree with Shane on this one.  Much of the older content in the Python documentation was written in the imperative style because that's what Guido likes (or did at the time, at least), and it always feels very tedious to read.
+ 
+ The imperative style is properly used when telling the **reader** to do something, not when describing what something else will do.  It makes a lot more sense to use present tense to describe an interface and the imperative to tell the user they must do something.
+ 
+gvanrossum (May 24, 2002 12:49 pm; Comment #3)  --
+ I've always liked the imperative style better, but I will see if I can
+ get used to the present tense.
+ 
+Caseman (May 24, 2002 2:53 pm; Comment #4)  --
+ Funny, I always used to write comments in present tense, but after seeing a bunch of code commented
+ in imperial tense, I've changed. Although, I still find myself going back to present tense every once
+ in a while.
+ 
+ I would argue that either is OK, so long as the whole module uses one or the other. It reads really strange
+ to me when some comments are in imperial tense and others are in present tense.
+ 
+rdmurray (Aug 30, 2002 4:12 pm; Comment #5)  --
+ <pre>
+ > fdrake (May 24, 2002 10:08 am; Comment #2)  --
+ >  The imperative style is properly used when telling the **reader** to do
+ >    something, not when describing what something else will do.  It makes a
+ >    lot more sense to use present tense to describe an interface and the
+ >    imperative to tell the user they must do something.
+ </pre>
+ 
+ I've always used imperitive tense, because I figured I *was*
+ telling the reader what to do: what they needed to code their method
+ to do if they were going to implement this particular interface.
+ I can see it both ways.  But I can see that I can equally think of the
+ Interface as documentation of what the implemented methods do, which
+ is surely the more common reader case.
+ 
+
+
+From zagy Wed Feb 18 05:12:35 -0500 2009
+From: zagy
+Date: Wed, 18 Feb 2009 05:12:35 -0500
+Subject: 
+Message-ID: <20090218051235-0500 at wiki.zope.org>
+
+I see more and more transition to pep8 in regard to method names, like get_title() instead of getTitle(). Shouldn't we update guides accordingly?

Added: zope3docs/source/codingstyle/nameskeysids.rst
===================================================================
--- zope3docs/source/codingstyle/nameskeysids.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/nameskeysids.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,112 @@
+Names, Keys and Ids
+
+Author
+
+  "Steve Alexander":mailto:steve at cat-box.net
+
+Obligatory quotation::
+
+  Everybody has a name, but names are only words
+
+                          "I'm not built for this"
+                                The Nilon Bombers
+
+Problem
+
+  Sometimes we say 'key', sometimes 'name', and sometimes 'id'. This
+  could get confusing, and we should try to be consistent. Here's a 
+  summary of how these terms are used.
+  
+  Key
+  
+    The IContainerPythonification proposal has been implemented, and
+    components that are containers have methods to get at contained
+    objects that look like '__getitem__(key)', 'get(key, default=None)',
+    and 'setObject(key, object)'.
+
+  Name
+  
+    We also have the notion that objects have names. For example the
+    code below will give the name we used to traverse from someObject's
+    container to 'someObject'::
+
+      from Zope.App.Traversing import objectName
+      print "someObject's name is ", objectName(someObject)
+
+    There's also a view that works similarly to the 'absolute_url' view
+    called 'object_name'. This can be used in Page Templates::
+
+      <h3>Job #<span tal:replace="context/@@object_name">NN</span></h3>
+
+    In this example, '@@object_name' gets you the 'object_name' view, which
+    gets the same result as 'getAdapter(someObject, IObjectName)()'.
+  
+    Various documentation talks about "named objects". We talk informally 
+    about Services being identified by "name", even though they are really
+    identified by an id.
+    
+  Id
+
+    In Zope 2, content objects have a method 'getId()', and containers 
+    have methods 'objectIds()', '_setId()', and so on.
+    
+
+Proposal
+
+  This is my explanation, or rationalisation, of when to use the terms 'id', 
+  'name', and 'key'.
+
+  Id
+
+    The term 'id' should only be used when we are talking about an identifier
+    that is unique in the context of some particular id scheme. Examples include
+
+    * A social security number, unique within a country's social secuity 
+      bureaucracy
+
+    * A user id consisting of an NT Domain and a username, unique within
+      a Windows NT network
+
+    * A user id, unique within a Windows NT Domain
+
+    * A Windows NT domain, unique within a Windows network
+
+    We could consider the name of an object within a container to be an id within
+    the id scheme of that container, but this is not a particularly useful
+    way of thinking. One reason is that to identify the container, we need to
+    consider it as having an id within the id scheme of *its* container.
+
+    Id schemes should really be well-known points of reference within a system.
+    So, the model of Services in Zope 3 fits; you look up a service by its
+    id within the service manager id scheme.
+  
+  Name
+  
+    Objects are given names to help us find them. An object may be found
+    via more than one name. In Zope 3, we use names to guide the process
+    of traversing from a container to a contained object.
+    
+  Key
+  
+    We use an object's name to get it from within a container.
+    The container sees these names as 'keys', so from a container's point
+    of view, a name functions as a key to look up an object.
+    
+    When we use the term 'key', we really mean "a name functioning as a
+    key in the context of a container".
+    
+    
+References
+
+  Martin Fowler, "Analysis Patterns: reusable object models", Addison Wesley
+  1997. Chapter 5 "Referring to Objects" has a good discussion of names, ids
+  and id schemes.
+  
+
+
+<hr solid id=comments_below>
+
+
+bwarsaw (Jun 17, 2002 9:27 am; Comment #1)  --
+ We also have *message ids* which are unique identifiers for translatable messages within a particular application/product domain.
+ 

Added: zope3docs/source/codingstyle/optimizations.rst
===================================================================
--- zope3docs/source/codingstyle/optimizations.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/optimizations.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,46 @@
+Although code optimization is not the primary goal in the current development
+cycle of Zope3, here are some rules that should make further optimizations and the possible use of unicode less painful.
+
+string module
+
+  - Avoid to use the 'string' module. Instead use string methods. They are
+    always much faster and share the same API with unicode strings !
+
+  - Avoid slicing for checking if a string has a special prefix or suffix::
+
+       NO:  if foo[:3]=='bar'...
+       YES: if foo.startswith('bar'):
+
+       NO:  if foo[-5:]=='.html'...
+       YES: if foo.endswith('.html'):
+
+    Using startwith()/endswith() is faster, cleaner and less error-prone.
+
+usage of type()
+
+  - constructs likes 'if type(obj) is type("")' should be replaced
+    using isinstance()::
+
+      NO:  if type(obj) is type(""):
+      YES: if isinstance(obj, str):...
+
+    When checking if a string is a string, keep in mind that
+    it might be a unicode string too! The types module has
+    the StringTypes type defined for that purpose. So a check
+    for string or unicode string would look like that::
+
+      from types import StringTypes  
+      if isinstance(obj, StringTypes):...
+
+    
+
+
+<hr solid id=comments_below>
+
+
+tim_one (May 24, 2002 10:14 am; Comment #1)  --
+ Just noting that Python (probably 2.3) will introduce a common base class for str and unicode, so that isinstance will work without need of types.!StringTypes.
+ 
+stevea (Jul 8, 2002 1:55 pm; Comment #2)  --
+ Here or perhaps elsewhere, write something about not using '[]' as a marker object to detect default values when passed to queryNNNN functions. Instead, use an object(), as these don't get wrapped in security proxies.
+ 

Added: zope3docs/source/codingstyle/python-naming.rst
===================================================================
--- zope3docs/source/codingstyle/python-naming.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/python-naming.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,41 @@
+Naming convention Python objects in Zope
+
+  by JimFulton
+
+  I've resisted establishing naming conventions, but enough people
+  have asked that conventions be established (and that I follow them ;)
+  that I've decided to write down some. So, here they are:
+
+  1. Use leading underscores as described in the "Python Style Guide",
+     http://www.python.org/peps/pep-0008.html
+
+  2. Public global variables names are spelled with CapitalizedWords, 
+     as in 'Folder' or 'RoleService'.
+
+     Interface names always start with a capital 'I', followed by a
+     capital letter, as in 'IFactory'.
+
+     An exception is made for global non-factory functions, which are
+     typically spelled with [mixedCase].
+
+  3. Public attribute names are [mixedCase], as in "getService" or 'register'.
+
+  4. Local variables, including argument names
+     LowercaseWithUnderscores, as in 'permission_id', or 'service'.
+
+  5. Single-letter variable names should be avoided unless:
+
+     - Their meaning is extremly obvious from the context, and
+
+     - Brevity is desireable
+
+     The most obviouse case for single-letter variables is for
+     iteration variables.
+
+  Be tolerant of code that doesn't follow these conventions. We want
+  to reuse lots of software written for other projects, which may not
+  follow these conventions.
+
+  A reasonable goal is that code covered by the ZPL should follow
+  these conventions.
+

Added: zope3docs/source/codingstyle/python-style.rst
===================================================================
--- zope3docs/source/codingstyle/python-style.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/python-style.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,48 @@
+Writing Python code
+===================
+
+Use PEP 8
+---------
+
+In general any Python code should be written accordingly to PEP 8.
+
+.. note::
+    Please be aware that PEP 8 recommends module-level consistency over blind
+    rule-following. Zope 3 has been around for a while and earlier coding style of
+    modules might not match thec current rules. In that case, please make a
+    conscious decision about a reasonable level of consistency.
+
+Additional rules
+----------------
+
+Attribute names
+~~~~~~~~~~~~~~~
+
+The naming of attributes as recommended by PEP 8 is controversial. PEP 8
+prefers `attribute_name` over `attributeName`. Zope 3 has been built originally
+with the latter rule and many APIs still use this meme. 
+
+Newer packages usually prefer to use underscores instead of camel case.
+
+Import ordering
+~~~~~~~~~~~~~~~
+
+XXX Jim recommended ordering imports not as PEP 8 does (by creating blocks) 
+but by simply using the output of `sort` on the block.
+
+This rule has not been officially agreed upon.
+
+
+Catch specific errors, keep try blocks minimal
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you are converting a value to an `int`, and you want to catch conversion
+errors, you need only catch `ValueError`. Be sure to do the minimum possible
+between your `try:` and `except ValueError:` statements.
+
+
+No trailing whitespace
+~~~~~~~~~~~~~~~~~~~~~~
+
+Trailing whitespace should not occur, nor should blank lines at the end of
+files.

Added: zope3docs/source/codingstyle/servicesevents.rst
===================================================================
--- zope3docs/source/codingstyle/servicesevents.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/servicesevents.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,36 @@
+Services and Events
+
+  A common pattern is where you have a persistent Service that uses
+  subobjects as plugins.
+
+  An example of this is the CachingService which contains Caches.
+  The CachingService does not need to subscribe to events.
+  The Caches need to subscribe to ObjectModifiedEvents.
+  (They don't subscribe to moves or deletions, because the cache will
+  time-out anyway before too long.)
+  
+  The Caches should not be subscribed directly to the EventService because
+  the CachingService they are within may or may not be bound as a service.
+  They should only be subscribed to the EventService when the CachingService
+  is an active service.
+
+  One way around this is to make the CachingService binding-aware, and also
+  make the Caches binding-aware, and have the CachingService pass on such
+  binding change notifications to the Caches.
+
+  Another solution is to make the CachingService binding-aware, and also
+  make it an EventChannel. There is a base-class that can be mixed into the
+  CachingService implementation to make it a binding-aware EventChannel that
+  subscribes to and unsubscribes from the EventService as required.
+
+  In this case, a Cache can simply subscribe to its CachingService when it
+  is added, and unsubscribe if it is removed.
+
+
+
+<hr solid id=comments_below>
+
+
+stevea (Nov 22, 2002 12:53 pm; Comment #1)  --
+ A note from the pope: services such as this on generally shouldn't have subobjects that do work. The subobjects should be added to a persistent package, and the service should be configured to use them from there. This page will be refactored to take this into account soon.
+ 

Added: zope3docs/source/codingstyle/todocomments.rst
===================================================================
--- zope3docs/source/codingstyle/todocomments.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/todocomments.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,44 @@
+TO-DO Comments
+
+  Occassionally you may need to note places in code that need to be
+  revisited later. There are three standard codes used in Python
+  comments used to designate such code:
+
+  o XXX
+
+  o TODO
+
+  o BBB
+
+  XXX
+
+    XXX comments should only be used during development to note
+    things that need to be taken care of before a final (trunk) commit.
+
+    One should not expect to see !XXXs in released software.
+
+    It should be extremely rare to check in an XXX on a trunk. If an
+    XXX is checked in on a trunk:
+
+    o The intention and expectation will be that someone will resolve
+      the XXX before someone releases the code.
+
+    o The XXX must fully describe an issue, so that someone else can
+      read the comment and know what it's about. 
+
+    XXX shall not be used to record new features, non-critical
+    optimization, design changes, etc.
+
+  TODO
+
+    If you want to record things like new features, non-critical
+    optimizations, design changes, or other long term changes, use
+    TODO comments. People making a release shouldn't care about !TODOs, 
+    but they ought to be annoyed to find !XXXs.
+
+  BBB
+
+    When adding code to preserve backward compatibility, use a BBB
+    comment with a date. For example::
+
+      # BBB 2004-07-08, preserves use of 'get_foo' function

Added: zope3docs/source/codingstyle/writingtests.rst
===================================================================
--- zope3docs/source/codingstyle/writingtests.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/writingtests.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,73 @@
+For any module 'somepkg.somemod' there should be a corresponding
+unit test module 'somepkg.somemod.tests.testSomemod'.  Or if more than one
+set of unit tests is desired, multiple test modules of the form
+'somepkg.somemod.tests.testSomemodYYYY'.  Note that this means
+that your 'somemod' directory needs to have a 'tests' subdirectory,
+and that that subdirectory must have a (normally empty) '__init__.py'
+file in it.
+
+The file 'ut.py' in the root directory of the Z3 tree contains
+a skeleton file appropriate for using in building unit test
+modules.  If you use ut.py and follow the guidelines above,
+then your unit tests will automatically be run when 'test.py'
+is run.
+
+In your unit test class, begin all unit test methods with the string 
+'test'.
+If you use the !CleanUp class support (see the comments in 'ut.py'),
+make sure that your 'setUp' and 'tearDown' methods call the
+!CleanUp class's 'setUp' and 'tearDown' methods::
+
+    class TestSomething(CleanUp):
+        def setUp(self):
+            CleanUp.setUp(self)
+            #your setup here
+
+        def tearDown(self):
+            #your teardown here
+            CleanUp.tearDown(self)
+
+**Never** give your test methods a docstring!  Doing so makes it very difficult
+to find your test method when using the verbose output.  Use a comment instead.
+
+Call your test class TestSomething, never just Test.
+
+Call your test methods test_something(), not testSomething()
+
+The typical approach to structuring the tests themselves is
+to write test methods that exercise each individual method of
+the class.  It is a good idea to organize these tests according to
+the Interfaces implemented by the class under test.  In fact, it
+is often best to implement such tests in separate mixin classes,
+one class per Interface.  WritingInterfaceTests expands
+on this concept in more detail.
+
+Within the unit tests themselves, the Zope3 style is to use
+the positive rather than the double negative assertions.
+Thus, use 'assertEqual' rather than 'failUnlessEqual', 
+'assertRaises' rather than 'failUnlessRaises', and 'assert_'
+rather than 'failUnless'.  (Yes, 'assert_' is an ugly name,
+but it is still preferred.)
+
+There are certain other "Best Practices" the following of which
+leads to more robust and general unit tests:
+
+  * If at all possible, avoid writing to the file system.  It should
+    be possible to run the tests with only read-only access to
+    the test directories.  If you do have to create files,
+    create them using the python tempfile module.  Be sure to clean up
+    after yourselves in your tearDown method.
+
+  * It has been suggested that doing import of the module
+    under test in the global section of the test module is bad,
+    because in some uses of unittest test modules that generate
+    import errors outside the tests themselves are ignored silently.
+    It has also been suggested that if so this is a bug in unittest.
+    I'm not aware of a definitive answer to this question.  If you
+    wish to avoid globally importing the module under test, you
+    can write a "helper function" to do the import and create and
+    return instance(s) of the objects needed for testing,
+    and call it from the start of each unit test.
+
+Other Best Practices suggestions welcome!
+

Added: zope3docs/source/codingstyle/zcml-style.rst
===================================================================
--- zope3docs/source/codingstyle/zcml-style.rst	                        (rev 0)
+++ zope3docs/source/codingstyle/zcml-style.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -0,0 +1,429 @@
+ZCML file naming conventions
+
+  zcml configuration for a package should, in general, be placed in a
+  file named 'configure.zcml'.  If a package performs meta
+  configuration (defines new configuration directives), the
+  metaconfiguration should go in a file named meta.zcml.  The code
+  that implements the metaconfiguration directives should (again, in
+  general) go in a file named metaconfiguration.py.
+
+ZCML file placement conventions
+
+  Anything outside of zope.app needs to be usable outside of the
+  application server. This means it should have no dependencies on
+  zope.app.  In addition, anything outside of zope.app should have
+  mimimal dependencies on other zope packages.
+
+  Therefore, there should be no zcml in packages outside of zope.app and 
+  zope.configure.
+
+ZCML style guide
+
+  Status: first draft
+
+  Contact: "Steve Alexander":mailto:steve at cat-box.net
+
+Problem
+
+  ZCML in Zope 3 will be easier to maintain if it all follows the same
+  style.
+  
+  In this page, I propose such a style. I've considered the following
+  qualities:
+  
+  * Lines under 80 characters wherever possible
+  
+  * Indentation to reflect nesting
+  
+  * Ease of maintenance
+  
+  * Easy visual scanning through zcml
+  
+Proposal
+
+  Tabs and spaces
+  
+    * All whitespace to be made up of space characters. No chr(9) hard tabs.
+    
+    * Indentation of 2 characters to show nesting, 4 characters to list
+      attributes on separate lines. This distinction makes it easier to
+      see the difference between attributes and nested elements.
+      
+    * Skip the first indentation level. That is, don't indent the 
+      tags that are immediately inside the 'configure' element.
+
+      If a configuration file has many logical sections, then mark
+      the sections with comments and indent the sections relative to
+      the comments. For example::
+
+        <configure xmlns='http://namespaces.zope.org/zope'>
+
+        <!-- Configuration registries -->
+
+        <content 
+            class="zope.app.services.configuration.ConfigurationRegistry"
+            >
+          <require
+               permission="zope.ManageServices"
+               interface="zope.app.interfaces.services.configuration.IConfigurationRegistry"
+               />
+        </content>
+
+        <!-- Adapter Service -->
+
+        <content class="zope.app.services.adapter.AdapterService">
+          <implements
+
+
+      
+  Namespaces
+  
+    * Always use the "usual" names for namespaces in the document
+    
+      * default (no qualification needed) for http://namespaces.zope.org/zope
+      
+      * browser for http://namespaces.zope.org/browser
+      
+      * zmi for http://namespaces.zope.org/zmi
+      
+      * security for http://namespaces.zope.org/security
+
+      * xmlrpc for http://namespaces.zope.org/xmlrpc
+      
+      * whatevername for http://namespaces.zope.org/whatevername
+      
+    * Only define those namespaces used in the document. This is a similar
+      rule to what imports to use in a Python module.
+      
+  Tags
+   
+    * Opening tags
+  
+      * Close a one-line tag on the same line
+
+      * Close a multi-line tag on a new line, at the same level of
+        indentation as the tags attributes.
+  
+    * Empty tags
+    
+      * Close a one-line tag on the same line
+      
+      * Close a multi-line tag using " /&gt;" on a new line  at the
+        same level of indentation as the tag's attributes,
+     
+    * Elements
+    
+      * Indent closing tags at the same level of indentation as the 
+        opening tags.
+      
+    * Attributes
+    
+      * If all the attributes fit on one line with the tag name, do that
+      
+      * If all the attribute fit on one line without the tag name, do
+        that on the line after the tag, indented 4 spaces along from
+        the tag.
+      
+      * Otherwise, put the first attribute on a new line, and use one
+        line per attribute.
+
+      * Use double quotes for attributes unless single quotes are
+        needed to enclose double quotes.
+      
+  * Comments
+  
+    * Comments should be placed immediately above the declarations they
+      apply to. Keep comments to one line where possible, and open and
+      close the comment on the same line.
+    
+    * using XXX in comments to mark the unfinished, broken or crufty
+      
+Examples
+
+  Example one, good style::
+  
+    <configure
+        xmlns='http://namespaces.zope.org/zope'
+        >
+
+    <adapter
+        factory=".AttributeAnnotations."
+        provides=".IAnnotations."
+        for=".IAttributeAnnotatable." 
+        />
+
+    </configure>
+
+
+  Example two, could be better::
+  
+    <configure
+       xmlns='http://namespaces.zope.org/zope'
+       xmlns:security='http://namespaces.zope.org/security'
+       xmlns:zmi='http://namespaces.zope.org/zmi'
+       xmlns:browser='http://namespaces.zope.org/browser'
+       >
+
+    <!-- Standard configuration directives -->
+    <include package=".Configuration" file="configuration-meta.zcml" />
+    <include package=".App" file="app-meta.zcml" />
+    <include package=".I18n" file="i18n-meta.zcml" />
+    <include package=".Publisher" file="publisher-meta.zcml" />
+    <include package=".Event" file="event-meta.zcml" />
+    <include package=".StartUp" file="startup-meta.zcml" />
+
+
+    <!-- Standard Permissions -->
+
+    <security:permission id="zope.View"
+                         title="View"
+                         />
+
+    <security:permission id="zope.Security"
+                         title="Change security settings"
+                         />
+
+    <security:permission id="zope.ManageContent" 
+                         title="Manage Content"
+                         />
+
+    <security:permission id="zope.ManageBindings" 
+                         title="Manage Service Bindings"
+                         />
+
+    <security:permission id="zope.ManageServices" 
+                         title="Manage Services"
+                          />
+
+    <security:permission id="zope.ManageApplication" 
+                         title="Manage Application"
+                         />
+
+    <!-- XXX What is this for? -->
+    <security:permission id="zope.I18n" 
+                         title="Manage Application"
+                         />
+
+    <!-- Configuration -->
+    <include package=".App" file="app.zcml" />
+    <include package=".I18n" file="i18n.zcml" />
+    <include package=".Publisher" file="publisher.zcml" />
+    <include package=".Event" file="event.zcml" />
+    <include package=".StartUp" file="startup-registry.zcml" />
+
+
+    </configure>
+
+  This example could be rewritten taking into account
+  
+  * Only defining the namespaces that are used
+    
+  * Better formatting of security permission declarations
+        
+  * Using 2 space and 4 space indents, not 3 space.
+    
+  Example two rewritten::
+  
+    <configure
+        xmlns='http://namespaces.zope.org/zope'
+        xmlns:security='http://namespaces.zope.org/security'
+        >
+
+    <!-- Standard configuration directives -->    
+    <include package=".Configuration" file="configuration-meta.zcml" />
+    <include package=".App" file="app-meta.zcml" />
+    <include package=".I18n" file="i18n-meta.zcml" />
+    <include package=".Publisher" file="publisher-meta.zcml" />
+    <include package=".Event" file="event-meta.zcml" />
+    <include package=".StartUp" file="startup-meta.zcml" />
+
+    <!-- Standard Permissions -->
+    <security:permission id="zope.View" title="View" />
+    <security:permission id="zope.Security" title="Change security settings" />
+    <security:permission id="zope.ManageContent" title="Manage Content" />
+    <security:permission 
+        id="zope.ManageBindings" title="Manage Service Bindings" 
+        />
+    <security:permission id="zope.ManageServices" title="Manage Services" />
+    <security:permission
+       id="zope.ManageApplication" title="Manage Application" 
+       />
+
+    <!-- XXX What is this for? -->
+    <security:permission
+        id="zope.I18n" title="Manage Application" 
+        />
+
+    <!-- Configuration -->
+    <include package=".App" file="app.zcml" />
+    <include package=".I18n" file="i18n.zcml" />
+    <include package=".Publisher" file="publisher.zcml" />
+    <include package=".Event" file="event.zcml" />
+    <include package=".StartUp" file="startup-registry.zcml" />
+
+    </configure>
+    
+  Example three, could be better::
+  
+    <configure
+       xmlns='http://namespaces.zope.org/zope'
+       xmlns:security='http://namespaces.zope.org/security'
+       xmlns:zmi='http://namespaces.zope.org/zmi'
+       xmlns:browser='http://namespaces.zope.org/browser'
+       >
+
+      <browser:defaultView 
+         for="zope.i18n.interfaces.ITranslationService."
+         name="index.html"
+         />
+
+      <browser:view 
+         permission="zope.ManageServices" 
+         for="zope.i18n.interfaces.ITranslationService."
+         factory="zope.app.browser.i18n.translate.">
+
+         <browser:page name="index.html" attribute="index" />
+
+         <browser:page name="editMessages.html" attribute="editMessages" />
+
+         <browser:page name="deleteMessages.html"
+                       attribute="deleteMessages" 
+                       />
+
+         <browser:page name="addLanguage.html" attribute="addLanguage" />
+         <browser:page name="addDomain.html" attribute="addDomain" />
+
+         <browser:page name="changeEditLanguages.html" 
+                       attribute="changeEditLanguages" />
+         <browser:page name="changeEditDomains.html" 
+                       attribute="changeEditDomains" />
+         <browser:page name="changeFilter.html" 
+                       attribute="changeFilter" />
+
+         <browser:page name="deleteLanguages.html"
+                       attribute="deleteLanguages" />
+         <browser:page name="deleteDomains.html" attribute="deleteDomains" />
+
+      </browser:view>
+
+      <zmi:tabs for="zope.i18n.interfaces.itranslationservice">
+        <zmi:tab label="Translate" action="@@index.html"/>
+      </zmi:tabs>
+
+    </configure>
+
+  Example three reformatted::
+  
+    <configure
+        xmlns='http://namespaces.zope.org/zope'
+        xmlns:zmi='http://namespaces.zope.org/zmi'
+        xmlns:browser='http://namespaces.zope.org/browser'
+        >
+
+    <browser:defaultView 
+        for="zope.i18n.interfaces.ITranslationService" name="index.html" />
+
+    <browser:view 
+        permission="zope.ManageServices" 
+        for="zope.i18n.interfaces.ITranslationService"
+        factory="zope.app.browser.i18n.Translate"
+        >
+
+      <browser:page name="index.html" attribute="index" />
+
+      <browser:page name="editMessages.html" attribute="editMessages" />
+
+      <browser:page name="deleteMessages.html" attribute="deleteMessages" />
+
+      <browser:page name="addLanguage.html" attribute="addLanguage" />
+      <browser:page name="addDomain.html" attribute="addDomain" />
+
+      <browser:page
+          name="changeEditLanguages.html" attribute="changeEditLanguages" 
+          />
+      <browser:page
+          name="changeEditDomains.html" attribute="changeEditDomains"
+          />
+      <browser:page
+          name="changeFilter.html" attribute="changeFilter" 
+          />
+
+      <browser:page name="deleteLanguages.html" attribute="deleteLanguages" />
+      <browser:page name="deleteDomains.html" attribute="deleteDomains" />
+
+    </browser:view>
+
+    <zmi:tabs for="zope.i18n.interfaces.ITranslationService">
+      <zmi:tab label="Translate" action="@@index.html"/>
+    </zmi:tabs>
+
+    </configure>
+
+  Example three reformatted again. Note how putting the attributes of
+  'browser:page' declarations on a separate line visually separates
+  them, so we don't need so much vertical whitespace::
+  
+    <configure
+        xmlns='http://namespaces.zope.org/zope'
+        xmlns:zmi='http://namespaces.zope.org/zmi'
+        xmlns:browser='http://namespaces.zope.org/browser'
+        >
+
+    <browser:defaultView 
+        for="zope.i18n.interfaces.ITranslationService" name="index.html" />
+
+    <browser:view 
+        permission="zope.ManageServices" 
+        for="zope.i18n.interfaces.ITranslationService"
+        factory="Zope.I18n.Views.Browser.Translate."
+        >
+        
+      <browser:page
+          name="index.html"
+          attribute="index" 
+          />
+      <browser:page
+          name="editMessages.html"
+          attribute="editMessages" 
+          />
+      <browser:page
+          name="deleteMessages.html"
+          attribute="deleteMessages" 
+          />
+      <browser:page
+          name="addLanguage.html"
+          attribute="addLanguage" 
+          />
+      <browser:page
+          name="addDomain.html"
+          attribute="addDomain" 
+          />
+      <browser:page
+          name="changeEditLanguages.html"
+          attribute="changeEditLanguages" 
+          />
+      <browser:page
+          name="changeEditDomains.html"
+          attribute="changeEditDomains" 
+          />
+      <browser:page
+          name="changeFilter.html" 
+          attribute="changeFilter" 
+          />
+      <browser:page
+          name="deleteLanguages.html" 
+          attribute="deleteLanguages" 
+          />
+      <browser:page
+          name="deleteDomains.html" 
+          attribute="deleteDomains" 
+          />
+  
+    </browser:view>
+
+    <zmi:tabs for="zope.i18n.interfaces.ITranslationService">
+      <zmi:tab label="Translate" action="@@index.html"/>
+    </zmi:tabs>
+
+    </configure>
+

Modified: zope3docs/source/index.rst
===================================================================
--- zope3docs/source/index.rst	2009-02-18 13:18:54 UTC (rev 96695)
+++ zope3docs/source/index.rst	2009-02-18 13:21:54 UTC (rev 96696)
@@ -11,6 +11,7 @@
    :maxdepth: 2
 
    process/index
+   codingstyle/index
    migration/index
 
 Indices and tables



More information about the Checkins mailing list