Difference between pages "Creating Python-related Ebuilds" and "Zope HOWTO"

(Difference between pages)
(Links)
 
(First Steps)
 
Line 1: Line 1:
== Summary ==
+
This page documents how to use Zope with Funtoo Experimental, which currently has good Zope support thanks to [[Progress Overlay Python]] integration.
  
Funtoo Linux incorporates Progress Overlay into the main Portage tree, which currently contains 400+ updated Python-related packages that implement next-generation Python support for ebuilds.
+
== About Zope ==
  
== Building Python Modules with Portage ==
+
Zope is an Open Source application server framework written in Python. It has an interesting history which you should familiarize yourself with before starting Zope development, as it contains several interesting twists and turns.
  
== Conceptual Overview ==
+
=== Zope History ===
  
Portage supports the ability to build python modules and extensions for all installed versions of python. This functionality has been implemented by <tt>python.eclass</tt>.
+
There are two versions of Zope, Zope 2 and Zope 3. One might assume that Zope 3 is the version that people should use for new software development projects by default, but this is not the case. Most Zope-based projects continue to use Zope 2. Zope 3 was an attempt to redesign Zope 2 from scratch, and is completely different from Zope 2, but it was not adopted by the community.
  
To use <tt>python.eclass</tt>, you first want to investigate how python module building is integrated into any included <tt>Makefile</tt> or build script. Since we want <tt>python.eclass</tt> to build these modules for us, typically the first step is to tweak the <tt>Makefile</tt> or <tt>configure</tt> script to explicitly *not* build python modules. We will be handling that process using <tt>python.eclass</tt>.
+
There is also something called [http://codespeak.net/z3/five/ Five] (named because it is "2 + 3") that backports many of the new features of Zope 3 into the Zope 2 framework. Several projects will use Zope 2 plus Five in order to use some of the newer features in Zope. Five was merged into mainline Zope 2 in early 2010, and first appeared in Zope 2.8.
  
Another option, for those Python packages with a <tt>setup.py</tt> in the root source directory, is to use the <tt>distutils</tt> eclass. In this case, you generally do not need custom <tt>src_compile</tt> or <tt>src_install</tt> stages, as the eclass takes care of everything for you. However, you will still need to set the proper environment variables described below, as they are needed by <tt>python.eclass</tt> which is used by <tt>distutils.eclass</tt>. You will also want to set dependencies in <tt>DEPEND</tt> and <tt>RDEPEND</tt> as described in this article.
+
You can learn more about the history of Zope 2, 3 and Five in the [http://svn.zope.org/Zope/trunk/src/Products/Five/README.txt?view=markup Five README].
  
== Progress Improvements ==
+
To make things even more interesting, work on [http://docs.zope.org/zope2/releases/4.0/ Zope 4] is underway, and it will be based on 2.13 rather than 3.x. It includes a number of [http://docs.zope.org/zope2/releases/4.0/CHANGES.html#restructuring incompatible changes] with prior versions.
  
This section describes the differences in approach between the old (classic) way of handling Python-related ebuilds, and the new way, which uses the updated eclass. Also note that the <tt>distutils</tt> eclass benefits from these updates as well, as it uses <tt>python.eclass</tt> behind-the-scenes.
+
{{fancynote|This HOWTO targets Zope 2.13, which includes Five. It is typically the version you should be using for new Zope projects.}}
  
=== The old way: python-updater ===
+
=== Zope Resources ===
  
With the older <tt>python.eclass</tt> in Gentoo (and that used to be in Funtoo Linux,) python modules are built for all installed versions of Python. However, no usable accounting information was stored by Portage so that it could "know" what versions of python the module was built for. This created a problem when new versions of Python are installed, as the new module would not be available for the new python, and Portage would not be aware of what needed to be done to fix this, if anything. This resulted in the creation of a tool called <tt>python-updater</tt> to rebuild all necessary python-related ebuilds so that they reflected the currently-installed versions of Python.
+
Now that you understand what version of Zope you should be targeting (2.13), we can point you towards the correct documentation :)
  
Note that python-updater-0.10 and later are aware of the new Python eclass, and will not unnecessarily reinstall any packages which set <tt>PYTHON_MULTIPLE_ABIS</tt> and <tt>EAPI="4-python"</tt>, as manual rebuilding is not necessary.
+
; [http://docs.zope.org/zope2/zope2book/ The Zope 2 Book]: This book provides a general introduction to Zope concepts and ZMI. It is a good place to start, but doesn't provide a direct introduction to Zope development. It's recommended that you skim through this book to familiarize yourself with Zope. It generally does not assume much prior knowledge about Web development or Python.
 +
; [http://docs.zope.org/zope2/zdgbook/ Zope Developer's Guide]: This guide will give you a better introduction to Zope development. It assumes you already know Python. Skip chapters 1 and 2 and start in [http://docs.zope.org/zope2/zdgbook/ComponentsAndInterfaces.html chapter 3], which covers components and interfaces. [http://docs.zope.org/zope2/zdgbook/Products.html Chapter 5] covers the creation of your first product.
 +
; Five: We're not done yet. There is a bunch of stuff in Zope 2.13 that is not in the official documentation. Namely, the stuff in Five. Check out [http://codespeak.net/z3/five/manual.html The Five Manual].
 +
; ZTK: [http://docs.zope.org/ztkpackages.html ZTK Documentation]
 +
; ZCA: [http://www.muthukadan.net/docs/zca.html A Comprehensive Guide to Zope Component Architecture] offers a good introduction to the programming concepts of ZCA. We also have a new page on [[Zope Component Architecture]] which will help you to understand the big picture of ZCA and why it is useful. ZCML ("Z-camel") is a part of ZCA and  was introduced in Zope 3, so typically you will find ZCML documented within Zope 3 documentation and book.
 +
; Content Components: Views and Viewlets: [http://docs.zope.org/zope.viewlet/index.html This tutorial on viewlets] also contains some viewlet-related ZCML examples near the end. The "Content Component way" of developing in Zope seems to be a Zope 3 thing and tied to ZCML. Chapter 13+ of Stephan Richter's ''Zope 3 Developer's Handbook'' (book) seems to cover this quite well. You will probably also want to check out Philipp Weitershausen's ''Web Component Development with Zope 3'' (book).
 +
; [http://wiki.zope.org/zope2/Zope2Wiki Zope 2 Wiki]: Main wiki page for all things related to Zope 2.
 +
; [http://docs.zope.org docs.zope.org]: This is the main site for Zope documentation.
  
'''TODO: add python-updater example'''
+
== First Steps ==
  
=== The new way: new python eclass ===
+
First, you will need to emerge Zope:
  
The new <tt>python.eclass</tt> from Arfrever has a new API that can be used to write Python ebuilds. When this API is used, Portage can track and resolve missing builds of Python modules internally, so <tt>python-updater</tt> is not needed to be used for these ebuilds. However, until all ebuilds are converted to the new API, <tt>python-updater</tt> will need to be used to update these old-style ebuilds. Fortunately for us, over 400 Python-related ebuilds have been converted to take advantage of the new eclass, with more added weekly.
+
<console>
 
+
# ##i## emerge --jobs=10 zope
== Setting up progress overlay ==
+
</console>
 
+
{{fancynote|Progess overlay is now merged in Funtoo current and stable - No manual steps are needed to benefit from it!}}
+
 
+
Notice, that progress overlay including an updated packages that also available in main portage tree!
+
<pre># python-updater</pre> this still required to rebuild old-fashion python-related ebuilds
+
 
+
 
+
== Updating the packages from progress overlay ==
+
Package updates are done the same way than before:
+
<pre>emerge -avuDN @world</pre>
+
 
+
Several python-related packages should be updated to progress versions, with the new PYTHON_ABIS flags.
+
 
+
== Developer Docs ==
+
  
=== Ebuild Converstion to new Python eclass ===
+
Zope is now installed.
  
Conversion from previous EAPIs and eclasses to the new progress python eclass is fairly straightforward. This section tries to explain the steps.
+
== Project Skeleton ==
  
==== 4-python EAPI ====
+
{{fancynote|Zope should be used by a regular user account, not as the root user.}}
  
First, set EAPI to 4-python:
+
The first step in using Zope is to ensure that you are using a regular user account. Create a new directory called <tt>zope_test</tt>:
  
 
<pre>
 
<pre>
EAPI=4-python
+
$ cd
 +
$ mkdir zope_test
 
</pre>
 
</pre>
  
Next, you will need to understand the type of Python application or module you are trying to install. The primary determining factor in how to proceed is to see whether the Python application installs anything into Python's <tt>site-packages</tt> directory.  Essentially all Python modules do this, and some applications do this as well. If a package installs stuff into <tt>site-packages</tt>, then you should have its ebuild take advantage of the Python eclass "multiple ABI" support.
+
Now, enter the directory, and create an "instance", which is a set of files and directories that are used to contain a Zope project:
 
+
In this context, "multiple ABI" refers to potentially multiple versions of Python that may be installed on your system. Each installed major.minor version of Python, plus Python derivatives like Jython and pypy, will have their own <tt>site-packages</tt> directory and the Python eclass can take care of installing a version of the Python modules for each version of Python on your system. If the application has binaries, a Python wrapper will also be installed that will hand off control to the proper version of Python automatically.
+
 
+
==== Non-Multiple-ABI Support ====
+
 
+
If you are not supporting multiple ABIs, which is the least common option, you will generally just set <tt>PYTHON_DEPEND</tt> to refer to the version(s) of Python you require. Documentation for <tt>PYTHON_DEPEND</tt> syntax (which has been changed in the new python eclass) is available [http://people.apache.org/~Arfrever/Gentoo_Python_Supplementary_Guide_for_Developers here].
+
 
+
==== Multiple ABI Support ====
+
 
+
So, if you are using multiple ABI support, which will be the case for all Python modules, proceed as follows. Set <tt>PYTHON_MULTIPLE_ABIS</tt> prior to any inherit lines:
+
  
 
<pre>
 
<pre>
PYTHON_MULTIPLE_ABIS=1
+
$ cd zope_test
 +
$ /usr/lib/zope-2.13/bin/mkzopeinstance
 
</pre>
 
</pre>
  
Note the new variable names. <tt>PYTHON_MULTIPLE_ABIS</tt> turns on the functionality to build multiple versions of python modules for each version of python defined in the user's <tt>PYTHON_ABIS</tt> setting. Note that <tt>PYTHON_ABIS</tt> defaults to "<tt>2.7 3.2</tt>" in Funtoo Linux profiles and can be overridden in <tt>/etc/make.conf</tt> if you would like the python eclass to target other Python ABIs (like jython, for example, or 2.6) that you might be interested in.
+
You will see the following output, and will be prompted to answer a few questions:
  
When <tt>PYTHON_MULTIPLE_ABIS</tt> is set and <tt>EAPI</tt> is set to <tt>4-python</tt>, then new USE flags will be automatically added to the <tt>IUSE</tt> with the <tt>python_abis_</tt> prefix.
+
<pre>
If you want to see what ABIs are supported, see the <tt>_PYTHON_GLOBALLY_SUPPORTED_ABIS</tt> variable defined in <tt>python.eclass</tt>.
+
Please choose a directory in which you'd like to install
 +
Zope "instance home" files such as database files, configuration
 +
files, etc.
  
Also note that for multiple ABI support, <tt>PYTHON_DEPEND</tt> is set to a reasonable default value so you should almost always never need to set it yourself.
+
Directory: instance
 +
Please choose a username and password for the initial user.
 +
These will be the credentials you use to initially manage
 +
your new Zope instance.
  
==== PYTHON_RESTRICTED_ABIS ====
+
Username: admin
 +
Password: ****
 +
Verify password: ****
  
<tt>PYTHON_RESTRICTED_ABIS</tt> variable set in the ebuild specifies a space-separated list of patterns of Python ABIs ''not'' supported by the current package. The settings in <tt>PYTHON_RESTRICTED_ABIS</tt> will remove certain ABIs from the auto-<tt>IUSE</tt> expansion that happens when <tt>EAPI</tt> is set to <tt>4-python</tt> and <tt>PYTHON_MULTIPLE_ABIS</tt> is set to <tt>1</tt> (This behavior is described above.) It will also limit the behavior of the <tt>python_abi_depend()</tt> function, described below. And of course, it will tell the python eclass to not build any python modules for these python versions, even if they happen to be installed on the system.
 
 
Use it like this, before the eclasses are inherited:
 
 
<pre>
 
PYTHON_RESTRICTED_ABIS="3.*"
 
 
</pre>
 
</pre>
  
Note that <tt>PYTHON_RESTRICTED_ABIS</tt> is a glob-style pattern. If you want to have it build with everything ''except'' 3.2 and above and jython, use this pattern:
+
Now, we will start our Zope instance:
  
 
<pre>
 
<pre>
PYTHON_RESTRICTED_ABIS="3.[2-9] *-jython"
+
$ cd instance
 +
$ bin/runzope
 
</pre>
 
</pre>
  
Note that the wildcard you should use to disable Jython is <tt>*-jython</tt>, while the wildcard you should use to disable PyPy is <tt>*-pypy-*</tt>.
+
Now that Zope is running, you can visit <tt>localhost:8080</tt> in your Web browser. You will see a nice introductory page to Zope.
  
==== python_abi_depend() ====
+
If you now go to the <tt>localhost:8080/manage</tt> URL, you will be prompted to log in. Enter the username and password you specified. You are now logged in to the ZMI (Zope Management Interface.)
  
One of the cool things about the new Python eclass is the "cascading" dependency functionality which is implemented via USE variables. Basically, if your new-style python module ebuild was built for python-2.7, and it has dependencies, then it can depend on the module it needs being built ''for'' the installed version of python-2.7 specifically. This happens by having your ebuild depend upon the <tt>python_abis_2.7</tt> <tt>USE</tt> flag being set in the installed ebuild it depends upon.
+
You can stop your application by pressing Control-C. In the future, you can start and stop your Zope instance using the following commands:
 
+
For this functionality to work, the ebuild you depend on must be a new-style (<tt>EAPI 4-python</tt>) ebuild too, and must be enabled to support multiple python ABIS via the <tt>PYTHON_MULTIPLE_ABIS=1</tt> setting. When these requirements are met, you will want to covert an old-style dependency that looks like this:
+
  
 
<pre>
 
<pre>
RDEPEND="foo >=dev-python/mydep-2 bar"
+
$ zopectl start
 +
$ zopectl stop
 
</pre>
 
</pre>
  
...to this new format:
+
<tt>zopectl start</tt> will cause your instance to run in the background rather than consuming a shell console.
  
<pre>
+
== First Project ==
RDEPEND="foo $(python_abi_depend ">=dev-python/mydep-2" ) bar"
+
</pre>
+
  
The <tt>python_abi_depend</tt> function will expand to conditionally depend on the proper USE flags being set in <tt>dev-python/mydep-2</tt> based on what USE flags are currently set for ''this'' ebuild when it builds. This is how the cascading functionality works. Use it in <tt>DEPEND</tt>, <tt>RDEPEND</tt> and <tt>PDEPEND</tt> as appropriate. You can include multiple ebuilds as arguments to <tt>python_abi_depend</tt>.
+
We will create a single very primitive Zope package, consisting of an Interface for a TODO class, and a TODO class.
  
Please note that due to the fact that <tt>python_abi_depend</tt> is implemented as a shell function, the shell can be a bit picky about parsing its arguments. Follow these guidelines:
+
Create the following files and directories relative to your project root:
  
* All arguments to <tt>python_abi_depend</tt> should be on the same line, or -
+
* Create the directory <tt>lib/python/example</tt>.
* Additional lines should have a <tt>\</tt> line continuation character as the last line, and -
+
* Create the file <tt>lib/python/example/__init__.py</tt> by typing <tt>touch lib/python/example/__init__.py</tt>.
* Any atoms with > or < characters should be enclosed in double-quotes to avoid being interpreted as output/input redirection
+
* Create these files:
  
==== python_abi_depend() gotchas ====
+
=== <tt>etc/package-includes/example-configure.zcml</tt> ===
  
Occasionally, you may encounter emerge errors like this when developing new Python ebuilds:
+
This file registers the <tt>example</tt> directory you created in <tt>lib/python</tt> as a ''package'', so that it is seen by Zope:
  
<console>
+
<pre>
xdev nova # ##i##emerge -p nova
+
<include package="example" />
 +
</pre>
  
These are the packages that would be merged, in order:
+
=== <tt>lib/python/example/interfaces.py</tt> ===
  
Calculating dependencies... done!
+
The following file defines the <tt>ITODO</tt> interface, and also uses some Zope Schema functions to define what kind of data we expect to store in objects that implement <tt>ITODO</tt>:
  
emerge: there are no ebuilds built with USE flags to satisfy "dev-python/lxml[python_abis_2.6?,python_abis_2.7?,python_abis_2.6-jython?,python_abis_2.7-pypy-1.7?,python_abis_2.7-pypy-1.8?]".
+
<pre>
!!! One of the following packages is required to complete your request:
+
from zope.interface import Interface
- dev-python/lxml-2.3.3::gentoo (Missing IUSE: python_abis_2.6-jython python_abis_2.7-pypy-1.7 python_abis_2.7-pypy-1.8)
+
from zope.schema import List, Text, TextLine, Int
(dependency required by "sys-cluster/nova-9999" [ebuild])
+
(dependency required by "nova" [argument])
+
</console>
+
  
Here's an explanation for why an error like this occurs. In this case, the <tt>lxml</tt> package has <tt>*-jython *-pypy-*</tt> in <tt>PYTHON_RESTRICTED_ABIS</tt>. Since <tt>nova</tt> depends on <tt>lxml</tt>, it should also be restricted so that it doesn't support Jython or PyPy. This makes sense, because if a dependency of <tt>nova</tt> can't run on a particular Python implementation, then neither can <tt>nova</tt> itself.
+
class ITODO(Interface):
 +
    name = TextLine(title=u'Name', required=True)
 +
    todo = List(title=u"TODO Items", required=True, value_type=TextLine(title=u'TODO'))
 +
    daysleft = Int(title=u'Days left to complete', required=True)
 +
    description = Text(title=u'Description', required=True)
 +
</pre>
  
This emerge error can be fixed by adding <tt>*-jython *-pypy-*</tt> to <tt>nova</tt>'s <tt>PYTHON_RESTRICTED_ABIS</tt>. The lesson here is that any Python-based application can only support the subset of all platforms supported by all its dependencies, and <tt>PYTHON_RESTRICTED_ABIS</tt> must reflect this.
+
=== <tt>lib/python/example/TODO.py</tt> ===
  
On an unrelated note, <tt>nova</tt> is configured with <tt>PYTHON_MULTIPLE_ABIS=1</tt> because it installs a ton of Python modules into <tt>site-packages</tt>.
+
Now, we define <tt>TODO</tt> to be a ''persistent'' object, meaning it can be stored in the ZODB. We specify that it implements our previously-defined <tt>ITODO</tt> interface, and provide reasonable defaults for all values when we create a new TODO object:
  
==== common python_abi_depend() dependencies ====
+
<pre>
 +
from persistent import Persistent
 +
from zope.interface import implements
 +
from example.interfaces import ITODO
  
This section is dedicated to providing examples on how to handle common dependencies that are found in Python-related packages:
+
class TODO(Persistent):
 +
    implements(ITODO)
 +
    name = u''
 +
    todo = []
 +
    daysleft = 0
 +
    description = u''
 +
</pre>
  
===== argparse =====
+
=== <tt>lib/python/example/configure.zcml</tt> ===
  
If the Python package's <tt>setup.py</tt> contains something like this:
+
Create an empty <tt>configure.zcml</tt> configuration file:
  
 
<pre>
 
<pre>
if sys.version_info < (2, 7):
+
<configure xmlns="http://namespaces.zope.org/zope"
    requirements.append('argparse')
+
    xmlns:five="http://namespaces.zope.org/five"
 +
    xmlns:browser="http://namespaces.zope.org/browser">
 +
</configure>
 
</pre>
 
</pre>
  
...then use the following dependency syntax:
+
== Debug Mode ==
  
<pre>
+
We can test our first project by entering debug mode:
(R)DEPEND="$(python_abi_depend virtual/python-argparse)"
+
</pre>
+
 
+
==== python_abi_depend() with -i and -e ====
+
 
+
<tt>python_abi_depend()</tt> has some advanced capabilities that you may need to take advantage of related to Python dependencies. Sometimes, your ebuild will only need a python module if certain versions of Python are installed. This functionality is typically needed in the following cases:
+
 
+
;module rolled into standard library: A module is needed, but in newer versions of python it is part of the standard library (so there is no need to depend on it for these newer python versions)
+
;module required for fixes: A module is needed, but only for newer versions of python, such as 3.x, where it implements compatibility features.
+
;optional module, not 100% compatible: A module can be used, but the dependencies are not supported with certain versions of Python.
+
 
+
Let's look at the first case, a module your ebuild needs that was rolled into the standard library starting with Python version 3.1. In this case, we only need to depend on this module for Python ABIs 3.0 or less. We would use the <tt>-e</tt> option to exclude the versions we are not interested in:
+
  
 
<pre>
 
<pre>
RDEPEND="$(python_abi_depend -e "3.[1-9]" dev-python/mydep)"
+
$ bin/zopectl debug
 +
Starting debugger (the name "app" is bound to the top-level Zope object)
 
</pre>
 
</pre>
  
In the second case, we depend on a module only for Python ABIs 3 and up, since it implements fixes for python3. In this case, we will use the <tt>-i</tt> option to include only those versions for which we want to depend:
+
Now, let's try creating a new TODO object and writing it out to a ZODB database:
  
 
<pre>
 
<pre>
RDEPEND="$(python_abi_depend -i "3.*" dev-python/mydep)"
+
>>> from ZODB import FileStorage, DB
 +
>>> storage = FileStorage.FileStorage('mydatabase.fs')
 +
>>> db = DB(storage)
 +
>>> connection = db.open()
 +
>>> import transaction
 +
>>> root = connection.root()
 +
>>> from example.TODO import TODO
 +
>>> a = TODO
 +
>>> a.name = u'My TODOs'
 +
>>> a.TODOS = [ u'Do Laundry', u'Wash Dishes' ]
 +
>>> a.daysleft = 1
 +
>>> a.description = u'Things I need to do today.'
 +
>>> root[u'today'] = a
 +
>>> transaction.commit()
 
</pre>
 
</pre>
  
Third case: something doesn't make sense in the context with pypy:
+
[[Category:HOWTO]]
 
+
[[Category:Python]]
<pre>
+
[[Category:Web]]
RDEPEND=">=sys-fs/udev-151
+
[[Category:Zope]]
pygobject? ( $(python_abi_depend -e "*-pypy-*" dev-python/pygobject:2) )
+
[[Category:Developer]]
pyqt4? ( $(python_abi_depend -e "*-pypy-*" dev-python/PyQt4) )
+
pyside? ( dev-python/pyside )
+
wxwidgets? ( $(python_abi_depend -e "3.* *-pypy-*" dev-python/wxpython) )"
+
</pre>
+
 
+
=== Links ===
+
 
+
* http://people.apache.org/~Arfrever/Gentoo_Python_Guide_for_Users
+
* http://people.apache.org/~Arfrever/Gentoo_Python_Supplementary_Guide_for_Developers
+
* http://people.apache.org/~Arfrever/EAPI_4-python_Specification
+
 
+
 
[[Category:Featured]]
 
[[Category:Featured]]
[[Category:Portage]]
 
[[Category:OpenStack]]
 

Revision as of 19:06, 11 January 2014

This page documents how to use Zope with Funtoo Experimental, which currently has good Zope support thanks to Progress Overlay Python integration.

About Zope

Zope is an Open Source application server framework written in Python. It has an interesting history which you should familiarize yourself with before starting Zope development, as it contains several interesting twists and turns.

Zope History

There are two versions of Zope, Zope 2 and Zope 3. One might assume that Zope 3 is the version that people should use for new software development projects by default, but this is not the case. Most Zope-based projects continue to use Zope 2. Zope 3 was an attempt to redesign Zope 2 from scratch, and is completely different from Zope 2, but it was not adopted by the community.

There is also something called Five (named because it is "2 + 3") that backports many of the new features of Zope 3 into the Zope 2 framework. Several projects will use Zope 2 plus Five in order to use some of the newer features in Zope. Five was merged into mainline Zope 2 in early 2010, and first appeared in Zope 2.8.

You can learn more about the history of Zope 2, 3 and Five in the Five README.

To make things even more interesting, work on Zope 4 is underway, and it will be based on 2.13 rather than 3.x. It includes a number of incompatible changes with prior versions.

Note

This HOWTO targets Zope 2.13, which includes Five. It is typically the version you should be using for new Zope projects.

Zope Resources

Now that you understand what version of Zope you should be targeting (2.13), we can point you towards the correct documentation :)

The Zope 2 Book
This book provides a general introduction to Zope concepts and ZMI. It is a good place to start, but doesn't provide a direct introduction to Zope development. It's recommended that you skim through this book to familiarize yourself with Zope. It generally does not assume much prior knowledge about Web development or Python.
Zope Developer's Guide
This guide will give you a better introduction to Zope development. It assumes you already know Python. Skip chapters 1 and 2 and start in chapter 3, which covers components and interfaces. Chapter 5 covers the creation of your first product.
Five
We're not done yet. There is a bunch of stuff in Zope 2.13 that is not in the official documentation. Namely, the stuff in Five. Check out The Five Manual.
ZTK
ZTK Documentation
ZCA
A Comprehensive Guide to Zope Component Architecture offers a good introduction to the programming concepts of ZCA. We also have a new page on Zope Component Architecture which will help you to understand the big picture of ZCA and why it is useful. ZCML ("Z-camel") is a part of ZCA and was introduced in Zope 3, so typically you will find ZCML documented within Zope 3 documentation and book.
Content Components
Views and Viewlets: This tutorial on viewlets also contains some viewlet-related ZCML examples near the end. The "Content Component way" of developing in Zope seems to be a Zope 3 thing and tied to ZCML. Chapter 13+ of Stephan Richter's Zope 3 Developer's Handbook (book) seems to cover this quite well. You will probably also want to check out Philipp Weitershausen's Web Component Development with Zope 3 (book).
Zope 2 Wiki
Main wiki page for all things related to Zope 2.
docs.zope.org
This is the main site for Zope documentation.

First Steps

First, you will need to emerge Zope:

#  emerge --jobs=10 zope

Zope is now installed.

Project Skeleton

Note

Zope should be used by a regular user account, not as the root user.

The first step in using Zope is to ensure that you are using a regular user account. Create a new directory called zope_test:

$ cd
$ mkdir zope_test

Now, enter the directory, and create an "instance", which is a set of files and directories that are used to contain a Zope project:

$ cd zope_test
$ /usr/lib/zope-2.13/bin/mkzopeinstance

You will see the following output, and will be prompted to answer a few questions:

Please choose a directory in which you'd like to install
Zope "instance home" files such as database files, configuration
files, etc.

Directory: instance
Please choose a username and password for the initial user.
These will be the credentials you use to initially manage
your new Zope instance.

Username: admin
Password: ****
Verify password: **** 

Now, we will start our Zope instance:

$ cd instance
$ bin/runzope

Now that Zope is running, you can visit localhost:8080 in your Web browser. You will see a nice introductory page to Zope.

If you now go to the localhost:8080/manage URL, you will be prompted to log in. Enter the username and password you specified. You are now logged in to the ZMI (Zope Management Interface.)

You can stop your application by pressing Control-C. In the future, you can start and stop your Zope instance using the following commands:

$ zopectl start
$ zopectl stop

zopectl start will cause your instance to run in the background rather than consuming a shell console.

First Project

We will create a single very primitive Zope package, consisting of an Interface for a TODO class, and a TODO class.

Create the following files and directories relative to your project root:

  • Create the directory lib/python/example.
  • Create the file lib/python/example/__init__.py by typing touch lib/python/example/__init__.py.
  • Create these files:

etc/package-includes/example-configure.zcml

This file registers the example directory you created in lib/python as a package, so that it is seen by Zope:

<include package="example" />

lib/python/example/interfaces.py

The following file defines the ITODO interface, and also uses some Zope Schema functions to define what kind of data we expect to store in objects that implement ITODO:

from zope.interface import Interface
from zope.schema import List, Text, TextLine, Int

class ITODO(Interface):
    name = TextLine(title=u'Name', required=True)
    todo = List(title=u"TODO Items", required=True, value_type=TextLine(title=u'TODO'))
    daysleft = Int(title=u'Days left to complete', required=True)
    description = Text(title=u'Description', required=True)

lib/python/example/TODO.py

Now, we define TODO to be a persistent object, meaning it can be stored in the ZODB. We specify that it implements our previously-defined ITODO interface, and provide reasonable defaults for all values when we create a new TODO object:

from persistent import Persistent
from zope.interface import implements
from example.interfaces import ITODO

class TODO(Persistent):
    implements(ITODO)
    name = u''
    todo = []
    daysleft = 0
    description = u''

lib/python/example/configure.zcml

Create an empty configure.zcml configuration file:

<configure xmlns="http://namespaces.zope.org/zope"
     xmlns:five="http://namespaces.zope.org/five"
     xmlns:browser="http://namespaces.zope.org/browser">
</configure>

Debug Mode

We can test our first project by entering debug mode:

$ bin/zopectl debug
Starting debugger (the name "app" is bound to the top-level Zope object)

Now, let's try creating a new TODO object and writing it out to a ZODB database:

>>> from ZODB import FileStorage, DB
>>> storage = FileStorage.FileStorage('mydatabase.fs')
>>> db = DB(storage)
>>> connection = db.open()
>>> import transaction
>>> root = connection.root()
>>> from example.TODO import TODO
>>> a = TODO
>>> a.name = u'My TODOs'
>>> a.TODOS = [ u'Do Laundry', u'Wash Dishes' ]
>>> a.daysleft = 1
>>> a.description = u'Things I need to do today.'
>>> root[u'today'] = a
>>> transaction.commit()