By Ingeniweb. A Django site.
Octobre 5, 2008
» Why Plone architecture must change


I proposed a conference on this theme but it was not keeped for PloneConf2008. Here comes a short work on its, and I will hope it create a debate.

Plone is born with a goal: make Zope 2 and CMF simple. Those two are frameworks and allowed you to create a website… a so rustic website. With Plone you only needed to fill one form to have a cool site ready to use and to custom. At that time Plone was CMFPlone, an other implementation of CMFDefault.

Some new products were inserted in the bundle like GroupUserFolder in a such way that they cannot be separated from the base implementation of Plone.

The second step was the Archetypes framework: a new manner to manage object’s attributes as schema. With all informations stored in the schema,  mutators and accessors are generated on boot time and forms are generated from schema’s widgets. It was cool, but not perfect. Then the product ATcontentTypes was created to be the glue to upgrade CMFPlone as Plone: all base types from CMF are now overloaded by a type from ATContentTypes.

So came Zope 3 and Five. Five is the glue that allows Zope 2 developpers to use component architecture from Zope 3 in their code. Plone 2.5 and Plone 3 are using Five.

Another product came from Zope ‘renegades’: PluggableAuthService and its implementation in Plone: PlonePAS. It should replace the old GroupUserFolder but users and groups management templates were never refactored.

Plone 3 introduces new component in plone.app to our greatest happiness.

What part of Plone needs CMF?
Why Plone needs to know about Archetypes storage and CMFEditions strategy?
Why GroupUserFolder is always in the bundle as PlonePAS fit is API?

Now Plone is like the linux kernel: a big monolithic Plone with a lot of modules that create a base Plone 3 site. And so much glue! GroupUserFolder is always here because nobody knows and wants to work on the portal_group replacement.
If you are following Plone4Artist or PloneGov you can see that a part of these projects needs to overload Plone base configuration.

CPS 3, an other CMF-based CMS, was conceived with the thinking that components need to be independant to be reusable and maintainable:

  • CPSSchema depends only on Zope
  • CPSCore depends only on Zope
  • CPSDocument depends only on CPSSchema
  • CPSDefault depends on CPSCore and CPSSchema, and implements the CPS site.

After 2 years it was divided into platforms:

  • CPS Legacy
  • CPS Courier
  • CPS Groupware

In front of that Plone propose at single product with a lot of glue that depends on others products or components that use their own glue and so on…
There’s no plone.core and plone.default and we cannot create a plone.artistsite or a plone.govsite.
Do you think that everyone need an openid or an ldap integration in Plone ?

Plone 4 must be a reimplementation, not only a new glue with new concepts. I don’t want any new functionality in Plone 4, I want modularity and scalability.

      

Juin 6, 2008
» Write functionnal doctests with files in forms


A short bill about testing forms with files.

First you need to setup you environment using your site policy product then your
product to test. The function setUpDefaultMembersAndFolder create the
structure with access rights positioned. After that you can focus yourself on
Formula module test.

Test Formule creation process
=============================

For the test you need to create three Nomenclatures and two Validation Process.

First, some set-up:

    >>> from Products.Five import zcml
    >>> import Products
    >>> import iw
    >>> zcml.load_config('configure.zcml', package=iw.sitepolicy)
    >>> zcml.load_config('configure.zcml', package=Products.Formula)

    >>> from iw.sitepolicy.tests import utils
    >>> utils.setUpDefaultMembersAndFolder(self)

    >>> from Products.Five.testbrowser import Browser
    >>> browser = Browser()
    >>> browser.handleErrors = False

Let us log all exceptions, which is useful for debugging. Also, clear portlet
slots, to make the test browser less confused by things like the recent portlet
and the navtree.

    >>> self.portal.error_log._ignored_exceptions = ()
    >>> self.portal.left_slots = self.portal.right_slots = []

Import needed for testing file in forms

    >>> import cStringIO
    >>> portal_url = self.portal.absolute_url()

We will need of cStringIO to create fake files.

Now we will logon with an user and jump directly into working folder.

    >>> browser.open('%s/logout' % portal_url)
    >>> browser.open(portal_url + '/login_form')
    >>> browser.getControl('Login Name').value = 'jdoe'
    >>> browser.getControl('Password').value = 'secret'
    >>> browser.getControl('Log in').click()
    >>> 'John Doe' in browser.contents
    True
    >>> browser.open(self.formula_folder.absolute_url())
    >>> browser.url
    '.../formula...'

Verify that an author keeps modification and creation rights

    >>> self.formula_folder.absolute_url()+'/edit' in browser.contents
    True

    >>> self.formula_folder.absolute_url()+'/createObject?type_name=BaseFormula' in browser.contents
    True

self.formula_folder is set in setUpDefaultMembersAndFolder.

Now we can fill the form and test the result. Document’s id is the filename
prefixed by ‘formula_‘ and document’s title is the first file line.

Create a new Formula for with special pink flavor

    >>> browser.getLink('Add Base Formula').click()
    >>> 'portal_factory' in browser.url
    True
    >>> browser.getControl(name='special').value = u"pink flavor"
    >>> browser.getControl(name='formula_file').add_file(cStringIO.StringIO('Pink flavor\n   etc'), 'text/plain', "32048432.txt")
    >>> browser.getControl('Save').click()
    >>> 'Changes%20saved' in browser.url
    True
    >>> browser.getLink('View').click()
    >>> '<h1>Pink flavor</h1>' in browser.contents
    True
    >>> print browser.url
    http://nohost/plone/folder1/formula_folder/formula_32048432

If you want to do the same with Plone 2.5 - Zope 2.9 - you will have an error
because the ‘add_file‘ is not implemented on FileControl. You need to use
following code:

getControl(name='formula_file').mech_control.add_file

Avril 28, 2008
» encolpe


Yet another post to manage automatically you po files…

We are using i18ndude to manage translation for the Plone bundle and helpers script are in PloneTranslations/utils. If we can do this for the whole bundle you can do it too for your products.

Here come an example of a script that manage translations for a Plone 2.5 product:


#!/bin/sh

##
## First we work on the 'plone' domain and then on the local domain to define below.
##

PLONEPRODUCTS="/path/to/plone/bundle/Products"
LOCALDOMAIN="product_name"
POPREFIX="product_name_in_lowercase"

##
## Domain: 'plone'
##

##
## Search all translations in 'plone' domain and rebiuld a new catalog
i18ndude rebuild-pot --exclude build --pot "./i18n/i18ndude-plone.pot" \
                     --create plone "./"

##
## Filter out all msgids that are already translated in PloneTranslations
i18ndude filter "./i18n/i18ndude-plone.pot" \
                "${PLONEPRODUCTS}/PloneTranslations/i18n/plone.pot" > "./i18n/filtered-plone.pot"

##
## Merge generated file with manual maintained pot file then with the current catalog
i18ndude merge --pot "./i18n/${POPREFIX}-plone.pot" \
               --merge "./i18n/filtered-plone.pot" \
               --merge2 "./i18n/manual-plone.pot"

##
## Cleaning
rm "./i18n/filtered-plone.pot" "./i18n/i18ndude-plone.pot"

##
## Refresh po files for 'plone' domain
i18ndude sync --pot "./i18n/${POPREFIX}-plone.pot" \
                    "./i18n/${POPREFIX}-plone-fr.po" "./i18n/${POPREFIX}-plone-en.po"

##
## Domain: LOCALDOMAIN
##

##
## Search all translations in ${LOCALDOMAIN} domain and rebiuld a new catalog
i18ndude rebuild-pot --exclude build --pot "./i18n/i18ndude.pot" \
                     --create ${LOCALDOMAIN} "./"
##
## generated.pot is given by ArchGenXML during product generation
i18ndude merge --pot "./i18n/${POPREFIX}.pot" \
               --merge "./i18n/i18ndude.pot" \
               --merge2 "./i18n/generated.pot"
##
## Cleaning
rm "./i18n/i18ndude.pot"

##
## Refresh po files for LOCALDOMAIN
i18ndude sync --pot "./i18n/${POPREFIX}.pot" \
                    "./i18n/${POPREFIX}-fr.po" "./i18n/${POPREFIX}-en.po"

##
## Check for missing translations in all page templates
echo
echo "#########################################################"
echo "##"
echo "## untranslated messages summary report"
echo
i18ndude find-untranslated -s `find skins -name "*.*p?"`

echo "To display the full report use:"
echo "i18ndude find-untranslated \`find skins -name \"*.*p?\"\`"

exit 0

You can repeat this for every domain you are using in your products.
You still have to manage a manual-domain.pot by hand to be able to i18n selectboxes or Archetype name for a content type for example, but your work is really easier to maintain you translations.

Thanks to Hanno for maintaining this tool.

Avril 27, 2008
» encolpe


Since Plone 3 is out, integrators are affected by the new way to do themes and to manage page layout. Through The Web customization is reduce to the strict minimum and some of them just leave Plone to another thing more easier to integrate. Before the sprint there were three proof of concept products trying to modify this.

The only one that can be used is CSSManager developed by Weblion. It only allow the site manager to modify the base_properties through the PMI without having to type anything: have ave a picker color widget and dropdown menu for other properties. It works only if your theme use base_properties. For example NuPlone does not.

In Paris Sprint, Jean-Mathieu Grimaldi (macadames) create a new product to ameliorate plone skinning collective.phantasy that you can found here: http://svn.plone.org/svn/collective/collective.phantasy/trunk/

The main goal of this product is to be able to have theme associated with folders in the same way that you can see on Quintagroup skins site.

This is far from online theming that you can have here on wordpress or in CPSSkins.

What do dummies wnat to their site? Inline edting is cool, but they want to be able in few clicks to appropriate their brand new site adding a new logo and getting round corners everywhere. They want to get a theme and modify it quickly as we done with base_properties. They don’t want to see the ZMI or to learn python and Zope 3 interfaces.

Such a tool should be a component of the Plone social sprint and must be available with or within the next major version of Plone.

I’m leaving Plone Paris sprint with a lot to think. It was great to met you again guys and girl from the community.

» encolpe


CMFEditions is a Plone generic versionning product and a framework for more dedicataed versioning task like staging (Iterate). It was included in Plone bundle and is activated by default on new sites. It is very simple to use and well documented. A really nice poduct in a developer point of view and a very useful tool from a customer point of view. Diggig deeper you can find something dangerous from a storage point of view.

About storage

Then, what are we calling storage?

There’s the storage from Archetypes (AttributeStorage now replaced by AnnotationStorage, FileSystemStorage, SQLStorage, etc). They are the way we want to store a field value. Here we just want to know if it is inside or outside Zope… dig deeper…

There’s the storage from ZODB. They manage how each object is stored and what structure has the ZODB:

  • FileStorage: the ZODB is a single and potentialy big file called Data.fs
  • DirectoryStorage: each object in the ZODB is a folder in the filesystem and every object attribute is a file
  • RelStorage: object are stored in an external database (PostGresSQL)

These storages have now blob support for file object: it means that your file is stored outside the ZODB and this one just store the reference on it.

There’s also a CMFEditions storage to store versionning informations and data. It’s currently based on ZVC that store everything in the Data.fs.

How is created a document’s revision ?

CMFEditions doesn’t know anything about Archetypes. It’s a transversal tool that can be apadted quickly if we move from Archetypes to something else. And we want it to keep this independance.

When a new revision is created, the docuement is parse like a simple python object and each attribute is stored following different strategies define by some modifiers. An attribute doesn’t show which Archetypes storage is used for it. until know it supposes that AnnotationStorage or AttributeStorage is used the it just copie each attribute elsewhere in the ZODB. In the FileSystemStorage case the whole file is copied from the filesystem into the ZODB for each revision… here size does matter and smaller is better.

Do get storage information we need to use Archetypes API. Then we need an extra modifier for each Archetypes storage. But now, what to do with this information? You have to modify you specific Archetypes storage to be able to store revision informations and to restore them if needed. CMFEditions communicate a very few informations during these operations.

Novell Plone team submit a patch on FileSystemStorage to do such work and next releases would include it.

What to do to simplify storage inclosing

This approach doesn’t allow to define advanced strategies in Archetypes storages above versionning. But why do we need to defin advanced strategies in Archetypes storages?

The only real storages should be the ZODB storages. But they doesn’t allow advanced strategy creation to manage objects on different ways following some rules.

What is the advantage to have strategy implemented directly in the ZODB?

CMFEditions would not need to know anything about field storage: everything is managed by the ZODB. You don’t need to configure storage strategy in several configuration files and the developper doesn’t need to know about this. blob is one of this strategy. An Archetypes field would just indicate if it use standard or blob.

» encolpe


Enfold Desktop is a very cool product for Windows users. Linux and Mac users already have builtin WebDav tools that do the trick. Enfold provides both server side products and client side user interface.

All this come from my only experience on Enfold Desktop 4 and may be there’s some errors. There no documentation for all this on Enfold Site

Client side

The client user interface needs to be installed on every computer that you want they use webdav access. It’s a plugin for the standard windows file explorer. Once you configured your access with the public url of your plone site you browse it like a local folder with a little time penalty but faster than in your web browser.

cooler than cool

hum, it’s not a water cooler advertising, but this product is really cool: in a Plone 3 site you can through your file explorer create new content types, modify and delete existing ones. You can doing a workflow transition. And for my customer site… we will see that point later.

Server side component

Enfold provide also an archive with several product that integrates your customer plone site for Enfold Desktop. It comes especially with the ShelExServer product that you have to install within the plone control panel. This product extend several tools to be more WebDav aware: content_type_registry and portal_workflow for example. It also modify permission for roles in the zope instance root.

Where things get more complicated

The last point is very useful in a plone site without any customization but can be very painful with a site managed with a policy registered in GenericSetup. Couple this with some bug in the last release candidate of Enfold Desktop 4 and you have a big mess.

What do I need to check after installing server side product

First: Don’t apply your customer profile before having update it at the end of this process. You will loose all Enfold Desktop settings.

Roles:

webdav access are correctly set in the zope instance root, but not in the plone instance root with Plone 3. Go in the Security tabs and fix webdav permissions for the three new roles: Editor, Contributor and Reader. Webdeav permissions have to be the same than on ‘View’ and ‘Access portal content’ permisions.

Workflows:

For each state webdav permissions are clone from ‘View’ and ‘Access portal content’… but the ‘acquire’ setting isn’t cloned during the operation. You have to fix that manually on each state of each workflow.

Content type registry:

Enfold Desktop create new predicates on base ATCT types, and only on them. If you need to manipulate your own types you have to confifure them manually.

Now you can export your profile and merge the modification in your customer profile.

More and more

It is impossible to modify which content type are created during a copy/paste: In one folder I want to create a document from a text file, in another I want to create a newsletter.

For HTML files created via webdav, the code is displayed as it until the document is edited and submit once.

It may be cool if Enfold Desktop can access to other web framework through webdav… May Sidney and Alan can answer on this.

Avril 19, 2008
» encolpe


Limi m’a posé la question pourquoi en français nous rajoutions des espaces avant certains signes de ponctuation. Pour lui répondre j’ai effectué quelques recherches qui m’ont permises de m’apercevoir que je me trompais sur certains points.

Espaces en usage avant et après les signes de ponctuation

  1. Point et virgule sont suivis d’un blanc.
  2. Point d’interrogation, point d’exclamation, point-virgule et deux-points sont suivis d’un blanc et précédés d’une “espace fine insécable” ou ½ cadratin.
  3. Les guillemets ouvrants ou fermants sont, respectivement, précédés ou suivis d’un blanc.
  4. Les parenthèses ou crochets ouvrants sont précédés d’un blanc.
  5. Les parenthèses ou crochets fermants sont suivis d’un blanc.
  6. Les apostrophes et traits d’union ne sont ni précédés ni suivis de blanc.
  7. Le tiret est précédé et suivi d’un blanc.
  8. Les points de suspension sont suivis d’un blanc.

Selon le deuxième point l’espace insécable classique n’est pas le bon caractère dans bien des cas où nous l’utilisons actuellement.

Nos moyens d’action

  1. THIN SPACE (&​#8201; / &​#x2009;)

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

  2. ZERO WIDTH SPACE (&​#8203; / &​#x200b;)

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&