Commit 000c143e authored by Hanno Schlichting's avatar Hanno Schlichting

More documentation updates

parent c1ad1be2
......@@ -47,8 +47,8 @@ class ViewPageTemplateFile(TrustedAppPT, PageTemplateFile):
def __call__(self, __instance, *args, **keywords):
# Work around BBB foul. Before Zope 2.12 there was no first argument
# but the Zope 3 version has one called instance. Some people used
# instance as an additional keyword argument.
# but the zope.pagetemplate version has one called instance. Some
# people used instance as an additional keyword argument.
instance = __instance
namespace = self.pt_getContext(
request=instance.request,
......
......@@ -35,7 +35,7 @@ _marker = object()
class Resource(object):
"""A mixin that changes the URL-rendering of resources (__call__).
In Zope 3, resource URLs are of the form
In zope.browserresource, resource URLs are of the form
nearest_site/@@/resource_name. Since Zope 2 didn't have support
for sites from the beginning of the Five integration, resource
URLs in Zope 2 are of the form context/++resource++resource_name.
......
......@@ -19,7 +19,7 @@ from zope.interface import Interface, implements
from Products.Five import BrowserView
class IOne(Interface):
"""This is a Zope 3 interface.
"""This is an interface.
"""
class One(object):
......
......@@ -19,7 +19,7 @@ Docstrings
----------
In Zope 2, objects normally have to have a docstring in order to be
published. This crazy requirement luckily isn't true for Zope 3, so
published. This crazy requirement luckily isn't true for zope.publisher, so
it should be possible to write docstring-less view classes that are
still published through ZPublisher.
......
......@@ -18,9 +18,9 @@ Content Providers
Content Provider is a term from the Java world that refers to components that
can provide HTML content. It means nothing more! How the content is found and
returned is totally up to the implementation. The Zope 3 touch to the concept
is that content providers are multi-adapters that are looked up by the
context, request (and thus the layer/skin), and view they are displayed in.
returned is totally up to the implementation. The Zope touch to the concept is
that content providers are multi-adapters that are looked up by the context,
request (and thus the layer/skin), and view they are displayed in.
So let's create a simple content provider:
......
......@@ -43,7 +43,7 @@ def findSite(obj, iface=ISite):
@zope.interface.implementer(IComponentLookup)
def siteManagerAdapter(ob):
"""Look-up a site manager/component registry for local component
lookup. This is registered in place of the one in Zope 3 so that
lookup. This is registered in place of the one in zope.site so that
we lookup using acquisition in addition to the ``ILocation`` API.
"""
site = findSite(ob)
......
......@@ -5,7 +5,7 @@ Local component look-up
-----------------------------
In order to do context-based component look-up, the Component
Architecture adapts the context to ``IComponentLookup``. Zope 3's
Architecture adapts the context to ``IComponentLookup``. zope.site's
default adapter uses the ``ILocation`` API to walk up the object tree
and find a site that way. Five provides its own adapter that also
supports acquisitional parents.
......
Five, the Zope 3 in Zope 2 project
==================================
Five, a Zope Integration project
================================
What is Five?
-------------
Five is a Zope 2 product that allows you to integrate Zope 3
technologies into Zope 2, today. Among others, it allows you to use
Zope 3 interfaces, ZCML-based configuration, adapters, browser pages
(including skins, layers, and resources), automated add and edit forms
based on schemas, object events, as well as Zope 3-style i18n message
catalogs.
We've tried to keep the Five experience as close to Zope 3 as
possible, so this means that what you learn while using Five should
also be applicable to Zope 3, and viceversa. We're in the process of
evaluating lots more Zope 3 technologies for integration into Zope 2.
This is the right moment for interested Zope 2 and Zope 3 developers
to jump in. We're looking for cooperation between different Zope 2
projects so that this can be a foundational system for us all.
Download
--------
We have released Five 1.2.6 on 13 August 2006. You may download it
here:
http://codespeak.net/z3/five/release/Five-1.2.6.tgz
We have released Five 1.3.8 on 4 November 2006. This is a bugfix
release for Five 1.3 and will be included in the next Zope 2.9 bugfix
release. You may download it here:
http://codespeak.net/z3/five/release/Five-1.3.8.tgz
We have also released Five 1.4.2. This is a feature release and is
compatible with Zope 2.9. You may download it here:
http://codespeak.net/z3/five/release/Five-1.4.2.tgz
We have also released Five 1.5.1. It will be included with the next
Zope 2.10 bugfix release. You may download it here:
http://codespeak.net/z3/five/release/Five-1.5.1.tgz
To check which version of Five is compatible with which version of
Zope, please refer to the `compatibility matrix
<http://codespeak.net/z3/five/INSTALL.html>`_.
Joining the project
-------------------
Five is kindly hosted on codespeak.net, and is part of the larger
*Zope 3 Base* project that offers an approachable area for
developers of Zope 3 related software.
Five has a mailing list:
http://codespeak.net/mailman/listinfo/z3-five
We're also active on IRC, at ``#z3-base`` on freenode.
Five is hosted in a subversion repository on codespeak.net. You can
browse this on the web here:
http://codespeak.net/svn/z3/Five/
You can check out Five using the following subversion command::
svn co svn://svn.zope.org/repos/main/Products.Five/trunk Five
There's also a checkins mailing list for the Z3 project, here:
http://codespeak.net/mailman/listinfo/z3-checkins
If you want checkin access, please join the z3-five mailing list or
the ``#z3-base`` IRC channel, and ask us there.
We hope to hear from you!
A couple of years back an attempt was made to rewrite Zope 2 from scratch and
provide an upgrade path from current Zope 2 to the new version. This project
used the name Zope 3. The attempt of writing a newer version of a full blown
application server similar to Zope 2 failed. Instead the project generated a
whole lot of underlying technologies and new concepts packaged up in reusable
libraries.
Five is the project that integrates those technologies and packages into
Zope 2. It's name is a pun on the original naming of Zope 2 + Zope 3 = Zope 5.
Among others, it allows you to use zope.interface, ZCML-based configuration,
adapters, browser pages (including layers, and resources), zope.schemas,
object events, as well as zope.i18n message catalogs.
We've tried to keep the Five experience as close to that of the integrated
Zope packages as possible, so this means that what you learn while using Five
should also be applicable to the Zope packages directly.
......@@ -2,35 +2,8 @@
Five Manual
===========
Introduction
------------
Five's goal is to let you, the Zope 2 developer, use Zope 3 code in
Zope 2. Our aim is to make as much of Zope 3 code work in Zope 2 as
possible, while integrating it with Zope 2.
Five can be used inside your current Zope 2 project. The benefits are:
* availability of Zope 3 technologies in Zope 2 like the component
architecture and declarative configuration.
* you can gradually evolve your Zope 2 project so it is better
positioned for the migration to Zope 3.
* you start learning about Zope 3 right now, preparing yourself better
for the future. Since Zope 3 is open to contributions, you could
even influence your future for the better.
Five can also be used to develop new Zope 2 products, though depending
on your deployment requirements it might in that case make more sense
to develop for Zope 3 directly.
Five is only useful on the Python (Product) level in Zope 2, not from
within the Zope Management Interface. Five makes no attempt to provide
a user interface, but is aimed squarely at the Python developer.
Zope 3 interfaces
-----------------
Zope interfaces
---------------
Interfaces?
===========
......@@ -95,61 +68,32 @@ Interfaces themselves are good for a number of reasons:
hopefully improving it.
* If an object provides an interface, that object is considered to be
a *component*. This means you can use Zope 3's component
a *component*. This means you can use Zope's component
architecture with these objects.
In order to use Five, you'll have to make your objects provide
interfaces. Sometimes, you cannot change the code of class (as you are
In order to use the component architecture, you'll have to make your objects
provide interfaces. Sometimes, you cannot change the code of class (as you are
not the maintainer), but you still want to make it implement an
interface. Five provides a ZCML directive to do this::
<five:implements class="tolkien.Oliphant"
implements="interfaces.IElephant" />
Interfaces in Zope 2 versus Zope 3
==================================
You may be familiar with Zope 2's way of declaring interfaces. Zope 2
has used the ``__implements__`` class attribute for interface
declarations. Zope 2 cannot detect Zope 3 interfaces and the Zope 3
machinery cannot detect Zope 2 interfaces. This is a good thing, as
Zope 2 has no way to deal with Zope 3 interfaces, and Zope 3 cannot
comprehend Zope 2 interfaces. This means you can safely make a class
declare both a Zope 2 and Zope 3 interface independently from each
other. It's a rare case where you need this though; you're usually
better off just switching to ``implements()`` for your application if
you are using Five.
Switching from Zope 2 interfaces to Zope 3 interfaces is easy -- just
make your interfaces inherit from ``zope.interface.Interface`` instead
of ``Interface.Interface`` (or ``Interface.Base``). Next, change all
``__implements__`` to ``implements()``.
This should get you going and your application may very well still
work. Later on, you will also have to change calls to
``isImplementedBy`` and such in your application to ``providedBy``, as
``isImplementedBy`` has been deprecated (you'll see the
DeprecationWarnings in your Zope log).
N.B.: As of Zope 2.12, the old Zope2 interfaces are *removed*.
interface. Zope provides a ZCML directive to do this::
<class class="tolkien.Oliphant">
<implements interface=".interfaces.IElephant" />
</class>
Adapters
--------
From a Python programmer's perspective, the immediate thing that Five
brings to do the table are adapters. This section goes through some
demo code to explain how everything is tied
together. ``demo/FiveDemo`` is a demo Product you can install and
examine that has all the presented here together.
demo code to explain how everything is tied together.
Zope 3 adapters depend on Zope 3 interfaces. To create a Zope 3
interface you need to subclass it from
``zope.interface.Interface``. Here is an example::
Zope adapters depend on Zope interfaces. To create a Zope interface you need
to subclass it from ``zope.interface.Interface``. Here is an example::
from zope.interface import Interface
class IMyInterface(Interface):
"""This is a Zope 3 interface.
"""This is an interface.
"""
def someMethod():
"""This method does amazing stuff.
......@@ -167,9 +111,6 @@ need to use the ``implements()`` function in the class::
def someMethod(self):
return "I am alive! Alive!"
For an explanation of the relation of Zope 3 interfaces to Zope 2
interfaces, see below.
Now let's set up the interface that we are adapting to::
class INewInterface(Interface):
......@@ -212,7 +153,7 @@ called ``classes.py`` and the interfaces in a module called
</configure>
Five will automatically pickup ``configure.zcml`` when it's placed in
Zope will automatically pickup ``configure.zcml`` when it's placed in
the product's directory. Any object that provides ``IMyInterface``
can now be adapted to ``INewInterface``, like this::
......@@ -223,26 +164,18 @@ can now be adapted to ``INewInterface``, like this::
adapted = INewInterface(object)
print adapted.anotherMethod()
Views in Five
-------------
Views
-----
This section will give a brief introduction on how to use the five
view system. ``demo/FiveViewsDemo`` is a demo Product you can install
and examine that has all the presented here tied together, please
consult it for more details. ``tests/products/FiveTest`` actually
contains a more detailed set of test views, trying a number of
features. Finally, read up on the way Zope 3 does it. While Five is a
subset of Zope 3 functionality and has been adapted to work with Zope
2, much of Zope 3's documentation still works.
This section will give a brief introduction on how to use the Zope view system.
Five enables you to create views for your own objects, or even built-in
Zope enables you to create views for your own objects, or even built-in
Zope objects, as long as two things are the case:
* The object provides an Zope 3 interface, typically through its class.
* The object provides a Zope interface, typically through its class.
* The object (typically its class) is made Zope 3 traversable. This
allows Zope 3 views, resources and other things to be attached to a
Zope 2 object.
* The object (typically its class) is made traversable. This allows Zope
views, resources and other things to be attached to a Zope object.
Typically you give your classes an interface using the ``implements``
directive in the class body::
......@@ -256,15 +189,11 @@ an example, to make Zope's ``Folder`` (and all its subclasses)
implement ``IFolder`` (an interface you defined), you can do the
following in ZCML::
<five:implements class="OFS.Folder.Folder"
interface=".interfaces.IFolder" />
``five`` in this case refers to the XML namespace for Five,
``http://namespace.zope.org/five``.
<class class="OFS.Folder.Folder"
<implements interface=".interfaces.IFolder" />
</class>
Views in Five are simple classes. The only requirements for a Five
view class are:
Views in Zope are simple classes. The only requirements for a view class are:
* They need an ``__init__()`` that take a context and a request
attribute. Typically this comes from a base class, such as
......@@ -272,20 +201,20 @@ view class are:
An example of a simple view::
from Products.Five import BrowserView
from zope.publisher.browser import BrowserView
class SimpleFolderView(BrowserView):
def eagle(self):
"""Test
"""
return "The eagle has landed: %s" % self.context.objectIds()
return "The eagle has landed: %s" % self.context.keys()
Note that it is not a good idea to give a view class its own
``index_html``, as this confuses Five's view lookup machinery.
``index_html``, as this confuses Zope's view lookup machinery.
This view uses methods in Python, but you can also use other Zope 2 mechanisms
such as ``PageTemplateFile``.
This view uses methods in Python, but you can also use other mechanisms
such as ``ViewPageTemplateFile``.
Finally, we need to hook up the pages through ZCML::
......@@ -297,9 +226,8 @@ Finally, we need to hook up the pages through ZCML::
permission="zope2.ViewManagementScreens"
/>
``browser`` in this refers to the XML namespace of Zope 3 for browser
related things; it's
``http://namespace.zope.org/browser``. ``permission`` declares the
``browser`` in this refers to the XML namespace for browser related things;
it's ``http://namespace.zope.org/browser``. ``permission`` declares the
Zope 2 permission needs in order to access this view. The file
``permissions.zcml`` in Five contains a mapping of Zope 2 permissions
to their Zope 3 names.
``permissions.zcml`` in AccessControl contains a mapping of Zope 2 permissions
to their zope.security names.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%deffont "standard" xfont "helvetica-medium-r"
%deffont "thick" xfont "helvetica-bold-r"
%deffont "typewriter" xfont "courier-medium-r"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings per each line numbers.
%%
%default 1 area 90 90, leftfill, size 2, fore "gray20", back "white", font "standard", hgap 0
%default 2 size 7, vgap 10, prefix " ", ccolor "blue"
%default 3 size 2, bar "gray70", vgap 10
%default 4 size 5, fore "gray20", vgap 30, prefix " ", font "standard"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings that are applied to TAB-indented lines.
%%
%tab 1 size 5, vgap 40, prefix " ", icon box "red" 50
%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Five - Zope 3 in Zope 2
%center
Martijn Faassen, Infrae
faassen@infrae.com
%page
Motto
It was the dawn of the third age of Zope. The Five project was a dream given form. Its goal: to use Zope 3 technologies in Zope 2.7 by creating a Zope 2 product where Zope 3 and Zope 2 could work out their differences peacefully.
(Babylon 5 season 1 intro, creatively quoted)
%page
Motto 2
The Law of Fives states simply that: ALL THINGS HAPPEN IN FIVES, OR ARE DIVISIBLE BY OR ARE MULTIPLES OF FIVE, OR ARE SOMEHOW DIRECTLY OR INDIRECTLY RELATED TO FIVE.
THE LAW OF FIVES IS NEVER WRONG.
(Principia Discordia)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
The problem
We're using Zope 2 in production
Zope 2 is showing its age
Zope 3 has better ways to do things
But can't just switch, we have customers!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Benefits of using Zope 3 in Zope 2
Able to use Zope 3 technologies right away
Don't reinvent the wheel/APIs
Better prepared for Zope 3 transition
Evolution, not revolution
Convergence, not divergence
%page
What works now?
Interfaces (zope.interface)
Schema (zope.schema)
ZCML (zope.configuration)
Adapters (zope.component)
Views, including layers, skins (zope.component)
%page
Brief demo
Show ZCML, adapters and views in action
%page
Next?
Utilities (global ones should work)
Forms
Views (improve the current system)
Who knows?
%page
Plans
Relicense from BSD to generic ZPL 2.1
Move from CVS at Infrae into SVN at codespeak.net
Convergence; join us!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%deffont "standard" xfont "helvetica-medium-r"
%deffont "thick" xfont "helvetica-bold-r"
%deffont "typewriter" xfont "courier-medium-r"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings per each line numbers.
%%
%default 1 area 90 90, leftfill, size 2, fore "gray20", back "white", font "standard", hgap 0
%default 2 size 7, vgap 10, prefix " ", ccolor "blue"
%default 3 size 2, bar "gray70", vgap 10
%default 4 size 5, fore "gray20", vgap 30, prefix " ", font "standard"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings that are applied to TAB-indented lines.
%%
%tab 1 size 5, vgap 40, prefix " ", icon box "red" 50
%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Five - Zope 3 in Zope 2
%center
Martijn Faassen, Infrae
faassen@infrae.com
Five developer
%page
Five future directions
What might happen
%page
Unique id service support
Foundation is there in form of events
Unfortunately implementation can not be the same
Objects are referenced differently in Zope 3
Local services/utilities are difficult in Zope 2
Could lead to Zope 3 catalog support
%page
Page template engine improvements
Right now we already use Zope 3 page templates
These are unicode-only (and work with plain ascii)
To support Zope 2 content, need classic non-ascii string support
Issue in Plone, not in Silva (heh heh)
%page
Zope 2.8 and ZODB 3.3
Should be able to work much better with new-style objects
Things like local services/utilities might be doable
%page
Integration with Plone, CMF, Silva, UnionCMS etc
Sharing a common base is good
Zope 3 is good
That base should be Zope 3
Five can help us start sharing today
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%deffont "standard" xfont "helvetica-medium-r"
%deffont "thick" xfont "helvetica-bold-r"
%deffont "typewriter" xfont "courier-medium-r"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings per each line numbers.
%%
%default 1 area 90 90, leftfill, size 2, fore "gray20", back "white", font "standard", hgap 0
%default 2 size 7, vgap 10, prefix " ", ccolor "blue"
%default 3 size 2, bar "gray70", vgap 10
%default 4 size 5, fore "gray20", vgap 30, prefix " ", font "standard"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings that are applied to TAB-indented lines.
%%
%tab 1 size 5, vgap 40, prefix " ", icon box "red" 50
%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Five - Zope 3 in Zope 2
%center
Martijn Faassen, Infrae
faassen@infrae.com
Five developer
%page
Interfaces, adapters
What are interfaces?
What are adapters?
Why?
A very quick introduction
%page
Actually
This tutorial applies to Zope 3 as much as to Five
Indication Five reached its goal in this area
%page
Interface example
%size 4, fore "blue"
from zope.interface import Interface
class IElephant(Interface):
"""An elephant is a big grey animal.
"""
def getAngerLevel():
"Return anger level on scale 0 (placid) to 10 (raging)"
def trample(target):
"Trample the target."
def trumpet():
"Make loud noise with trunk."
%page
Interface example, continued
%size 4, fore "blue"
from zope.interface import implements
class AfricanElephant:
implements(IElephant)
def getAngerLevel(self):
return 5 # always pretty stroppy
def trample(self, target):
target.flatten()
def trumpet(self):
return "A terrible racket"
%page
Interfaces
Interfaces are about the what, not the how
Interfaces don't do anything, they just describe
Code can state what interfaces objects provide
Code can introspect whether objects provide interfaces
%page
Why interfaces?
They are documentation
Make multiple implementations of same interface easier
Allows you to program against published APIs
Allow glueing by interface
%page
Component architecture
zope.component part of Zope 3
allows glueing together of components in various ways
a component is an object which provides an interface
a Zope 2 object with a Zope 3 interface is a component
%page
Adapters, example
%size 4, fore "blue"
class INoiseMaker(Interface):
"""Something that makes noise.
"""
def makeNoise():
"Returns the noise that's made."
%page
Adapters, example continued
%size 4, fore "blue"
class ElephantNoiseMaker:
"""Adapts elephant to noise maker.
"""
implements(INoiseMaker)
def __init__(self, context):
self.context = context
def makeNoise(self):
return self.context.trumpet()
%page
Adapters, example continued 2
%size 4, fore "blue"
>>> elephant = AfricanElephant()
>>> noise_maker = ElephantNoiseMaker(elephant)
>>> print noise_maker.makeNoise()
'A terrible racket'
%page
Adapters
Add behavior to object without changing its class
More manageable than mixins
Define new behavior in terms of other behavior
%page
Adapters, continued
Less framework burden on adapted objects
They only need to be a component
Adapted doesn't know about the adapter
Adapter is a component itself
%page
Adapter lookup
We just manually glued the adapter to the adapted
What if we had INoiseMaker adapters for other objects?
We want a universal way to say: give me a INoiseMaker for this object
This allows use to write more generic code
%page
Adapter lookup, example
%size 4, fore "blue"
for animal in animal_farm:
noise_maker = INoiseMaker(animal)
print noise_maker.makeNoise()
%page
Adapter glueing
System need to be informed what can adapt what
Zope Configuration Markup Language (ZCML) is used for that
%page
ZCML example
%size 4, fore "blue"
<configure xmlns="http://namespaces.zope.org/zope">
<adapter
for=".module.IElephant"
provides=".module.INoiseMaker"
factory=".module.ElephantNoiseMaker" />
<adapter
for=".other.IChicken"
provides=".module.INoiseMaker"
factory=".other.ChickenNoiseMaker" />
</configure>
%page
ZCML, what we just said
The adapter ElephantNoiseMaker adapts any object that provides IElephant to a INoiseMaker
The adapter ChickenNoiseMaker adapts any object that provides IChicken to a INoiseMaker
%page
This works in Zope 2 with Five
This works in Zope 2 with Five
Your objects just need to be components (provide Zope 3 interfaces)
Your ZCML goes into configure.zcml in your product
That's it
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%deffont "standard" xfont "helvetica-medium-r"
%deffont "thick" xfont "helvetica-bold-r"
%deffont "typewriter" xfont "courier-medium-r"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings per each line numbers.
%%
%default 1 area 90 90, leftfill, size 2, fore "gray20", back "white", font "standard", hgap 0
%default 2 size 7, vgap 10, prefix " ", ccolor "blue"
%default 3 size 2, bar "gray70", vgap 10
%default 4 size 5, fore "gray20", vgap 30, prefix " ", font "standard"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings that are applied to TAB-indented lines.
%%
%tab 1 size 5, vgap 40, prefix " ", icon box "red" 50
%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Five - Zope 3 in Zope 2
%center
Martijn Faassen, Infrae
faassen@infrae.com
Five developer
%page
An Introduction to Five
Why Five?
What is Five?
Where are we, where are we going?
%page
Motto
It was the dawn of the third age of Zope. The Five project was a dream given form. Its goal: to use Zope 3 technologies in Zope 2.7 by creating a Zope 2 product where Zope 3 and Zope 2 could work out their differences peacefully.
(Babylon 5 season 1 intro, creatively quoted)
%page
Motto 2
The Law of Fives states simply that: ALL THINGS HAPPEN IN FIVES, OR ARE DIVISIBLE BY OR ARE MULTIPLES OF FIVE, OR ARE SOMEHOW DIRECTLY OR INDIRECTLY RELATED TO FIVE.
THE LAW OF FIVES IS NEVER WRONG.
(Principia Discordia)
%page
The problem
We're using Zope 2 in production
Zope 2 is showing its age
Zope 3 has better ways to do things
But can't just switch, we have codebases, customers!
%page
Benefits of using Zope 3 in Zope 2
Able to use Zope 3 technologies right away
Don't reinvent the wheel/APIs
Better prepared for Zope 3 transition
Evolution, not revolution
Convergence, not divergence (this is important)
%page
Divergence
Infrae created Silva, Nuxeo CPS, etc
Everybody else started using Plone (why?!)
I want to use cool Plone technology
Silva is cool too, you may want to use it
I don't want to have to reinvent every wheel (just some)
%page
What's stopping us from sharing?
Zope 2 components are hard to share between apps
Even CMF components need work to share
Especially if you don't use CMF... (Silva)
Zope 2 framework burden is making it hard
Clean Python code is easier to share
%page
Convergence
Unify our diverse efforts
Zope 3 allows you to write Python, less framework sacrifices
Zope 3 allows the glueing of components
Zope 3 is the future
Five makes some of the future available today
%page
What works now? - an overview
Interfaces
Schema
ZCML
Adapters
Views, including layers, skins
%page
What works now, continued
Zope 3 page template engine
Traversal, resources
Zope 2 security from ZCML
Events
Beginnings of forms machinery
%page
Progress made since June
Initial announcement at Europython
As promised, moved to SVN at codespeak.net
Got website, mailing list
People joined the project
%page
Progress made since June, continued
Lots of excellent contributions!
Much better view infrastructure (traversal)
ZCML's interaction with Zope 2 products much improved
UnionCMS and other projects are starting to use it!
%page
The Zope 3 Base
Five is part of the Zope 3 Base
Zope 3 Base - All Your Bobobase Are Belong To Us
Possibly the cutest Zope 3 website anywhere
http://codespeak.net/z3
%page
Zope 3 Base
%center
%image "z3-banner.png"
%page
Zope 3 Base, continued
Second area of Zope 3 related development
Equivalent of Plone collective, for Zope 3
More freewheeling than dev.zope.org
Less freewheeling than Plone collective, however
Cuter than both
%page
Evolution: Five-ification
Five is not just for new Zope 2 projects
Five can interoperate with existing Zope 2 applications
Five in Plone - Flon
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%deffont "standard" xfont "helvetica-medium-r"
%deffont "thick" xfont "helvetica-bold-r"
%deffont "typewriter" xfont "courier-medium-r"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings per each line numbers.
%%
%default 1 area 90 90, leftfill, size 2, fore "gray20", back "white", font "standard", hgap 0
%default 2 size 7, vgap 10, prefix " ", ccolor "blue"
%default 3 size 2, bar "gray70", vgap 10
%default 4 size 5, fore "gray20", vgap 30, prefix " ", font "standard"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings that are applied to TAB-indented lines.
%%
%tab 1 size 5, vgap 40, prefix " ", icon box "red" 50
%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Five - Zope 3 in Zope 2
%center
Martijn Faassen, Infrae
faassen@infrae.com
Five developer
%page
Five Misc Topics
A number of as-yet uncategorized Five-related topics
%page
Resources
Various kinds of resources available
File, image, page template resource
Accessible through ++resource++ namespace
%page
Resources, example
%size 4, fore "blue"
<browser:resource
image="z3base.png"
name="z3base.png"
permission="zope2.ViewManagementScreens"
/>
%page
Resources
Any Five traversable object now has can be used to get to resource
url: path/to/object/++resource++z3base.png
Jim says this is not exactly Zope 3 as it ruins caching
%page
ZCML
ZCML can optionally be put in etc/site.zcml
If not, Five will automatically use included zcml
This zcml is in skel
%page
ZCML continued
ZCML loads any configure.zcml in all products
This is driven by five:loadProducts in site.zcml
Overrides are possible in override.zcml
This is driven by five:loadProductsOverrides in site.zcml
%page
Bridging interfaces
"Bride of Frankenzope"
Utility functions in bridge.py
Can convert Zope 2 interface to Zope 3 interface
%page
Events
Can instruct Zope 2 object to send Zope 3 style events using five:sendEvents
These events sent upon copy/move/rename in Zope 2
IObjectMovedEvent, IObjectAddedEvent, IObjectCopiedEvent, IObjectRemovedEvent
Can set up functions to subscribe to these events
%page
Content directive and permissions
Use content directive to declare Zope 2 permissions Zope 3 style
Declare permissions from ZCML, no more declareProtected()
Your classes look cleaner as a result
%page
Macros
Zope 3 way to aggregate macros into single object
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%deffont "standard" xfont "helvetica-medium-r"
%deffont "thick" xfont "helvetica-bold-r"
%deffont "typewriter" xfont "courier-medium-r"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings per each line numbers.
%%
%default 1 area 90 90, leftfill, size 2, fore "gray20", back "white", font "standard", hgap 0
%default 2 size 7, vgap 10, prefix " ", ccolor "blue"
%default 3 size 2, bar "gray70", vgap 10
%default 4 size 5, fore "gray20", vgap 30, prefix " ", font "standard"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Default settings that are applied to TAB-indented lines.
%%
%tab 1 size 5, vgap 40, prefix " ", icon box "red" 50
%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%page
Five - Zope 3 in Zope 2
%center
Martijn Faassen, Infrae
faassen@infrae.com
Five developer
%page
Views with Five
What are views?
Why?
How to make them work?
%page
Actually
This tutorial contains only a few Five specific bits
Otherwise it applies to Zope 3 as much as to Five
The Five specific bits are mainly some extra ZCML directives
These are in their own ZCML namespace
%page
Page example: overview.pt
%size 4, fore "blue"
<html>
<body>
<p tal:content="context/objectIds"></p>
</body>
</html>
%page
Page example: configure.zcml
%size 4, fore "blue"
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:five="http://namespaces.zope.org/five">
<five:traversable
class="OFS.Folder.Folder"
/>
<browser:page
for="OFS.interfaces.IFolder"
name="overview.html"
template="overview.pt"
permission="zope2.ViewManagementScreens"
/>
</configure>
%page
What works now
some/folder/overview.html
%page
Hooking up the page, explanation
Much like hooking up an adapter
Adapter provides new interface (API) for developer
View provides new interface (UI) for user
Only five-specific thing is making Folder Zope-3 traversable
Well, and the Zope 2 permission.
%page
Hooking up a page, with class
We need some helper methods
Very similar to the way you'd use Python scripts in Zope 2
%page
View class example: overview2.pt
%size 4, fore "blue"
<html>
<body>
<p tal:content="view/reversedIds"></p>
</body>
</html>
%page
View class example: browser.py
%size 4, fore "blue"
from Products.Five import BrowserView
class Overview(BrowserView):
def reversedIds(self):
result = []
for id in self.context.objectIds():
l = list(id)
l.reverse()
reversed_id = ''.join(l)
result.append(reversed_id)
return result
%page
Example: configure.zcml
%size 4, fore "blue"
<browser:page
for="OFS.interfaces.IFolder"
name="overview2.html"
template="overview2.pt"
permission="zope2.ViewManagementScreens"
class=".browser.Overview"
/>
%page
A note on security
There is none: both python code and ZPT are trusted
Only checks are happening on the outside
Performance benefit
Advantage of simplicity
%page
Publishing an attribute
Expose python method on view directly to the web
%page
Attribute example: browser.py
%size 4, fore "blue"
def directlyPublished(self):
return "This is directly published"
%page
Attribute example: configure zcml
%size 4, fore "blue"
<browser:page
for="OFS.interfaces.IFolder"
name="test.html"
class=".browser.Overview"
attribute="directlyPublished"
permission="zope2.ViewManagementScreens"
/>
%page
Publishing multiple pages
Convenience directive: browser:pages
%page
Multiple pages example
%size 4, fore "blue"
<browser:pages
for="OFS.interfaces.IFolder"
class=".browser.NewExample"
permission="zope2.ViewManagementScreens"
>
<browser:page
name="one.html"
template="one.pt"
/>
<browser:page
name="two.html"
attribute="two"
/>
</browser:pages>
%page
Default view for object
We can now set views that are named
What if we traverse to the object itself?
Use browser:defaultView
%page
Uh oh
This doesn't seem to work yet with Zope folders. Sidnei, help!
So we'll try it with a custom SimpleItem-based object
%page
DefaultView example
%size 4, fore "blue"
<browser:defaultView
for=".democontent.IDemoContent"
name="someview.html" />
%page
Conclusions
This works the same way as Zope 3 does too
Can supplement existing view systems in Zope 2
##############################################################################
#
# Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
# this is a package.
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:five="http://namespaces.zope.org/five"
>
<browser:resource
image="z3base.png"
name="z3base.png"
permission="zope2.ViewManagementScreens"
/>
</configure>
##############################################################################
#
# Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
import module, other
def initialize(context):
print "*" * 70
module.demo_manual_adaptation()
other.demo_animal_farm()
print "*" * 70
<configure xmlns="http://namespaces.zope.org/zope">
<adapter
for=".module.IElephant"
provides=".module.INoiseMaker"
factory=".module.ElephantNoiseMaker" />
<adapter
for=".other.IChicken"
provides=".module.INoiseMaker"
factory=".other.ChickenNoiseMaker" />
</configure>
##############################################################################
#
# Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
from zope.interface import Interface, implements
class IElephant(Interface):
"""An elephant is a big grey animal.
"""
def getAngerLevel():
"Return anger level on scale 0 (placid) to 10 (raging)"
def trample(target):
"Trample the target."
def trumpet():
"Make loud noise with trunk."
def terribleRacket():
return "A terrible racket"
class AfricanElephant:
implements(IElephant)
def getAngerLevel(self):
return 5 # always pretty stroppy
def trample(self, target):
target.flatten()
def trumpet(self):
return "A terrible racket"
class INoiseMaker(Interface):
"""Something that makes noise.
"""
def makeNoise():
"Returns the noise that's made."
class ElephantNoiseMaker:
"""Adapts elephant to noise maker.
"""
implements(INoiseMaker)
def __init__(self, context):
self.context = context
def makeNoise(self):
return self.context.trumpet()
def demo_manual_adaptation():
elephant = AfricanElephant()
noise_maker = ElephantNoiseMaker(elephant)
print noise_maker.makeNoise()
##############################################################################
#
# Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
from zope.interface import Interface, implements
from module import INoiseMaker, IElephant, AfricanElephant
class IChicken(Interface):
def getConfusionLevel():
"Get the confusion level of this chicken, 0 asleep, 10 frantic"
def cluck():
"""Return clucking sound of the chicken.
"""
class Chicken:
implements(IChicken)
def __init__(self, confusion_level):
self._confusion_level = confusion_level
def getConfusionLevel(self):
return self._confusion_level
def cluck(self):
return ' '.join(["cluck"] * self.getConfusionLevel())
class IndianElephant:
implements(IElephant)
def __init__(self, anger_level):
self._anger_level = anger_level
def hit(self):
"""Hit the indian elephant with a stick.
"""
if self._anger_level <= 10:
self._anger_level += 1
def getAngerLevel(self):
return self._anger_level
def trumpet(self):
return "t" + ("o" * self._anger_level) + "t"
class ChickenNoiseMaker:
implements(INoiseMaker)
def __init__(self, context):
self.context = context
def makeNoise(self):
return self.context.cluck()
def demo_animal_farm():
animal_farm = [Chicken(5), AfricanElephant(),
Chicken(3), IndianElephant(3)]
for animal in animal_farm:
noise_maker = INoiseMaker(animal)
print noise_maker.makeNoise()
This directory contains Five tutorial products.
<h1 tal:replace="structure context/manage_page_header">Header</h1>
<h2 tal:define="form_title string:Add Demo Content"
tal:replace="structure context/manage_form_title">Form Title</h2>
<p class="form-help">
Add Demo Content
</p>
<form action="." method="post"
tal:attributes="action request/ACTUAL_URL">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-label">
Id
</div>
</td>
<td align="left" valign="top">
<input type="text" name="add_input_name" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Title
</div>
</td>
<td align="left" valign="top">
<input type="text" name="title" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
</td>
<td align="left" valign="top">
<div class="form-element">
<input class="form-element" type="submit" name="submit_add"
value=" Add " />
</div>
</td>
</tr>
</table>
</form>
<h1 tal:replace="structure context/manage_page_footer">Footer</h1>
import random
from democontent import DemoContent
class Overview:
"""View for overview.
"""
def reversedIds(self):
result = []
for id in self.context.objectIds():
l = list(id)
l.reverse()
reversed_id = ''.join(l)
result.append(reversed_id)
return result
def directlyPublished(self):
return "This is directly published"
class NewExample:
"""View for new example.
"""
def helpsWithOne(self):
return random.randrange(10)
def two(self):
return "Two got called"
class DemoContentAddView:
"""Add view for demo content.
"""
def __call__(self, add_input_name='', title='', submit_add=''):
if submit_add:
obj = DemoContent(add_input_name, title)
self.context.add(obj)
self.request.response.redirect(self.context.nextURL())
return ''
return self.index()
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:five="http://namespaces.zope.org/five">
<!-- OFS.Folder.Folder views -->
<browser:page
for="OFS.interfaces.IFolder"
name="overview.html"
template="overview.pt"
permission="zope2.ViewManagementScreens"
/>
<browser:page
for="OFS.interfaces.IFolder"
name="overview2.html"
template="overview2.pt"
class=".browser.Overview"
permission="zope2.ViewManagementScreens"
/>
<browser:page
for="OFS.interfaces.IFolder"
name="test.html"
class=".browser.Overview"
attribute="directlyPublished"
permission="zope2.ViewManagementScreens"
/>
<browser:pages
for="OFS.interfaces.IFolder"
class=".browser.NewExample"
permission="zope2.ViewManagementScreens"
>
<browser:page
name="one.html"
template="one.pt"
/>
<browser:page
name="two.html"
attribute="two"
/>
</browser:pages>
<!-- .democontent.IDemoContent views -->
<browser:page
for="zope.browser.interfaces.IAdding"
name="addDemoContent.html"
template="addDemoContent.pt"
class=".browser.DemoContentAddView"
permission="zope2.ViewManagementScreens"
/>
<browser:resource
name="green5.png"
image="green5.png"
/>
<five:registerClass
class=".democontent.DemoContent"
meta_type="Five Demo Content"
addview="addDemoContent.html"
icon="green5.png"
permission="zope2.ViewManagementScreens"
/>
<browser:page
for=".democontent.IDemoContent"
name="someview.html"
template="someview.pt"
permission="zope2.ViewManagementScreens"
/>
<browser:defaultView
for=".democontent.IDemoContent"
name="someview.html"
/>
</configure>
from zope.interface import Interface, implements
from OFS.SimpleItem import SimpleItem
class IDemoContent(Interface):
def mymethod():
"""Return some text.
"""
class DemoContent(SimpleItem):
implements(IDemoContent)
def __init__(self, id, title):
self.id = id
self.title = title
def mymethod(self):
return "Hello world"
<html>
<body>
<p>The random number is <span tal:replace="view/helpsWithOne">0</span></p>
</body>
</html>
<html>
<body>
<p tal:content="context/objectIds"></p>
</body>
</html>
<html>
<body>
<p tal:content="view/reversedIds"></p>
</body>
</html>
<html>
<body>
<p>Some view</p>
</body>
</html>
......@@ -13,7 +13,7 @@
##############################################################################
"""Five-specific directive handlers
These directives are specific to Five and have no equivalents in Zope 3.
These directives are specific to Five and have no equivalents outside of it.
$Id$
"""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment