Posted in plone on February 10, 2011 by toutpt

The idea is simple. Let Plone manage the content and the portlet be simply a small browser view.

Plone is content centric, but a web page need to display more than the current content. This is why I have created this add-on. The add form let you choose one content item (like in the collection portlet) and a view mode. The default view is covering all plone content type.

There are many examples to cover, to show you how it is simple to use and to add support for.
I have already add conditional support with So now you can choose a content item to act as gallery in a portlet (link, folder or topic + ‘Gallery’ view in Itemview portlet). The same has been done on nmd.plonelinkasvideoembed, so you can publish a video from a link content item.

Comments and feed back are welcome !
This package is on pypi

Advertisements a new Plone website by Makina-Corpus

Posted in plone, zope on July 7, 2010 by toutpt

I’m proud to announce it, the new web site of “The greater Nantes economic agency” is now available here: .

This web site use Plone with some community add-ons (available on pypi). Some of these are new, mean they have been created to fit the customer needs, others has been contributed , mean they has been modified upstream, and last has just been used:

Custom code contains:

  • the theme done as a usual plonetheme (not with xdv).
  • policy (integration of all community add-ons and plone configuration)
  • portlets
  • content-types (collection, folderish document, video/audio interview, …)

System architecture

We have apache2 in front end. Next we have varnish as proxy cache (but not load balancer). Configuration has been taken from Products.PloneOrg subversion. It is already compatible with varnish 2.1.2

Next we have haproxy as load balancer that dispatch request over 4 zope instances. Each zope instances are configured with 2 threads (Zope default configuration is 4 threads).

For the database we use relstorage with postgresql, iw.fss to store files on the server’s file system and OpenLDAP to store users.

Monitoring & maintenace

We use nagios & cacti to monitor all services. We have split services in two categories:

  • system services: apache, postgresql, memcached, ldap
  • app services: varnish, haproxy, zope

This has some advantages: You can deploy the application without system services. This has been possible with buildout because it is very flexible. Supervisord and haproxy has just been taken from the über buildout.

Relstorage has a script to export the database to any database format: mysql, filestorage (data.fs) or whatever you want. So we use a script every night just after the backup to build a file storage “data.fs”, so any developper can work without having to install system services and has the last database available. It is easier to work on bugs when you have the content produce by the customer.

What I would like to improve / add / in to  Plone this year

For sure after a project like this one, I would like to contribute to Plone, share my experience. Here it is.

portlets dynamic template: I would like to be able to register new templates to provide multiple choice of portlet display. As you can choose how a content is displayed with dynamic view fti feature, you should be able to choose how a portlet is displayed.  I overrided collection and static portlet just to do that.

portlets order: I want to have first portlet for users&groups, next portlet for content types and next contextual portlets. To achieve this I overrided portlet mecanism because it was hardcoded.


Plone3 is slow. Right, but it is great. So how can I do a site with traffic and a newsletter of 8300 subscribers. Here are my keys:

  • install experimental add-ons listed below
  • install cachesetup with varnish as proxy cache and configure both (debug is easy with wireshark & firebug)
  • configure of zope: 2 threads, object cache and jarn.checkinterval
  • externalise binary content: fss is the best for plone3. Use blob for plone4
  • collective.solr: I have tryed out solr but I was not satisfied: some plone features are broken
  • add one instance only to deliver the newsletter. This one can not be reached by request, only the clock server

Because we followed the way plone community does website, we succeeded in doing a great web site with only free (GNU & BSD) softwares. We are working on linux desktop and we produce only free software because we love this.

The buildout used to deploy this web site has been push on the collective subversion under the name of nmd. Feel free to use it, to contribute, to share ideas. It has been designed to be useable in offline mode, and built upon reusable pieces depends on what you want.

I would like to thank the community for help, efforts, bug fixes and all great add-ons that have been done. I would like to thank for this experience and their warm welcome of Plone.

Extract all images of your skin with a script to serve them by apache

Posted in plone on June 21, 2010 by toutpt

Following the unloading Plone conference at budapest last year, you may want to serve images from skin directly by apache.

To do this you will need first to extract images. So here is a small python script to help you:

skintool = context.portal_skins
skin = skintool.getDefaultSkin()
PATHS = skintool.getSkinPath(skin).split(',')

images = skintool.ZopeFind(skintool, obj_metatypes=['Filesystem Image'],search_sub=1)
images_skin = [path for path, obj in images if path.split('/')[0] in PATHS and skintool.isFirstInSkin(path)]
images_str = "\n".join(['/'.join(path.split('/')[1:]) for path,obj in images])
print "You have extracted %s images. Here is the result:"%(len(images_skin))
print images_str
return printed

To use it, you just have to go in the Zope Management Interface (ZMI), Add a Script (Python) with the drop down menu and paste this script. Next you can excecute it with the “test” tab or access it by it’s url.

Write the content of the result page in a text file and then follow this blog post:

Hope this will help you to unloading Plone.

How to add a random time between two emails sent from zope.sendmail

Posted in plone, zope on June 15, 2010 by toutpt

I’m using collective.dancing for a mass mailing: +8000 emails to send.

One of the question is how to not be blacklisted ? A first thing I have done today is to add a random time between two sent.

To achieve this I have read the code of zope.sendmail. It is a well documented egg so this is not hard to understand how it works:

  • A maildir (a directory) store mails under files ready to be sent
  • A mailer (a utility) is ready to be called to send email one by one
  • A queue mail delivrery (utility) is ready to put messages inside a maildir
  • A mailqueue processor (not a component, a thread implementation) parse every 3 seconds if there is new emails to send in the mailbox

So to achieve this you just have to unconfigure the plone.smtp utility and declare a new utility called plone.smtp with this code:

import random
import time

from zope.sendmail import mailer

class SMTP(mailer.SMTPMailer):
    """Override SMTPMailer to let a random time"""

    def send(self, fromaddr, toaddrs, message):
        super(SMTP, self).send(fromaddr, toaddrs, message)

It’s working !

A more simple editorial process in Plone: Classic CMS + InPlace Topic view

Posted in plone on February 17, 2010 by toutpt

For a project I have tried to create a more simple editorial process for Plone.To understand this you have first to know the normal editorial process of Plone:

* First you have to go to the folder where you want to add your article.
* Next you click on add an article
* You fill the form (content + categorisation)
* Finaly you publish your article.

Pages are created with topic to fake publication of one article in multiple sections.

Contents are stored like on a computer : inside folders.

In many project this is a pain because the writer must first thinking about “where do I will add this article”.

So the idea is here. Remove the first step and simply use a link “add article” available anywhere in the site.

The way to achieve this is to create one “database” (large plone folder) per content type and add one action category with all “add xxx” actions + a portlet. At the moment I initialise this in policy.

Now we are able to create article without that first step. We need to know How to keep my tree that make so nice URL with Plone ? Let me introduce you the magic “acquisition” used with topic: collective.inplacetopicview.

A topic is like a persistent search done in Plone. The webmaster add criteria, and the display is like folders but links point to the real destination where article has been added. This add a real issue when you add contextual theming inside Plone. The user can be very surprised if just by clicking on an article link he moved outside the current context (so theme can change).

With inplacetopicview the link has a different behaviour. When you click you just stay in the current context so theme just stay the same.

There are different way to achieve this. inplacetopicview doesn’t add any new content type or what so ever, it just add some new views that let your visitor stay in the context of the topic but in different ways:
* With acquisition ( with myarticle real path = /myplone/articles/myarticles)
* With beatifulsoup by rendering both article and topic, and replace the content of the topic with the content of the article.

There are some other idea to implements in inplacetopicview like
* Ajax
* Popup

Now let’s try it by installing collective.inplacetopicview and add an initial structure with transmogrifier in your profile.

This process is not perfect but it is one first step done. For example image content handle threw wysiwyg editor need customization. The breadcrum show the real path.

Let me know what you think of this process and if you have idea to improve it.

Functional doctest snippet of the day

Posted in plone on January 6, 2010 by toutpt

I was looking for an easy way to get the current browser.contents in my real browser to easy debug what is happening in my doctest.

Here is the snippet:

Updated the 01/13/2009

>>> import tempfile as tmp
>>> def contents():
...    fd, fn = tmp.mkstemp(suffix=".html", prefix="testbrowser-")
...    file = open(fn, 'w')
...    file.write(browser.contents)
...    file.close()
...    print fn
>>> import pdb; pdb.set_trace()

So now you can just call contents() and copy paste the file path in your real browser and see what’s happening in your tests. May it can be added to testbrowser.Browser ?


Posted in plone on November 30, 2009 by toutpt

Plone has lots of features. collective.remove is a project to remove some features from Plone and be usefull to integrators.

Why ? My customer don’t need them and for performance purpose, it’s good to remove things not used.

What ? This project has three eggs at the moment:

To know what to remove, it’s per project need. For example I’m using TinyMCE on my last project, so I have removed kupu. Vicent Fretin tells me rules tab permission check is slow and I don’t need it. Limi has tweet kss make Plone slower so I have removed it.

The goal is to remove one thing at a time when a feature is not needed. Most of the time I was doing this in the policy but I have written the same thing multiple times, so lets released it in a reusable package.

It is more than uninstall profiles. It is uninstall packages.