Macadames' blog

Le silence est d'or, jusqu'à ce qu'il devienne plomb.

Archive for the ‘ploneblog’ Category

Three Plone addons – part 3 : CKEditor for Plone

with one comment

Three Plone addons – part 3 : CKEditor for Plone

Why Plone4 is so cool ? because you can create easily new addons in a pure python way, look at this new addon  called « CKEditor for Plone ».

A screencast here :

More information here :

Some lines of code are used to take original ckeditor svn code and place it in a Zope browser resource (because Zope is really strict about XML/XHTML we must do this little work, i hope i could replace it by a simple svn-externals in future).

Other lines of code are here to call dependencies (collective.plonefinder to search server resources, collective.quickupload for fast upload, see previous posts).

A small javascript « select resources » code is here to communicate with Collective Plone Finder.

The most part of code is CKEditor Plone control panel because it’s important for managers to allow or disallow features, toolbars, or some plugins on their Plone site.

The last part of code is the CKEditor integration in plone wysiwyg templates.

Hmm, that’s all.

Some people ask me, why CKEditor ? Plone4 has Tiny MCE …

Because :

– CKEditor is fast (really fast)

– CKEditor is accessible (

– because i’m a FCKeditor’s friend since 10 years, Fred (Frederico Caldeira Knabben) had no chance, his initials offend some English spoken people, now than the software name is more accessible perhaps more people will be interested in its features ?

– Plone needs to be good but it also needs to have reliable addons, and CKEditor cames with a good Plone integration (relax with collective.plonefinder and collective.quickupload)


Written by macadames

24, septembre 2010 at 11:05

Three Plone addons – part 2 : Collective Plone Finder

leave a comment »

Three Plone addons – part 2 : Collective Plone Finder

Collective Plone Finder is a tool for Plone developpers that can be used to find and select elements in a Plone site. The pypi name is « collective.plonefinder » with one dependency called « collective.quickupload »

It’s a widget’s helper, and you will find in the code a simple form lib widget, it’s an example of how you can use this product. In the README.TXT, you will find a way to use the formlib widget in a Plone portlet.

In this screencast, CPF is used in a portlet named « CG30 Direct Access Portlet » (CG30 is a client) :

The goal of Collective Plone Finder is not to be used as a standalone product. But, in this second screen cast and for demonstration purpose, we use it in a full browser screen just to show you the different potential uses. Look at the address bar where you can pass some params in querystring.

More information about this package can be found here :

This product is not complete (need more documentation, unit tests, some refactorisation, and some ajax popup functions are not finished at this time, 1.0.0), but i released it because it was an important part of my third autumn Plone production « CKEditor for Plone », see the next post.

I know that many documentation is missing, free time is too short, so if you need to integrate quickly CPF features in your own widget, at this time the better way is to read the code (really easy to understand, it’s Python + Plone,  a devel dream). In future i hope  many good evolutions will came with Plone4 new energy.

Written by macadames

24, septembre 2010 at 11:05

Three Plone addons – part 1 : Plone Quick Upload

with 9 comments

Three Plone addons – part 1 : Plone Quick Upload

As good things usually happen in threes, i present you three new Plone addons i released in September 2010, i hope you will find them useful.

The first product is Plone Quick Upload (pypi package name is « collective.quickupload »), a pure javascript multiple upload tool for Plone, look at the first screencast, you could think « oh i know it’s a new Flash Upload tool » and you would be wrong, FlashUpload has no drag and drop 😉

Plone Quick Upload has a control panel with useful options (limit size, limit parallel uploads, direct upload on select, fill titles before upload, …)  :

As you can see, Plone Quick Upload manage errors and returns i18n messages when an upload raise an error (file always exist, file is too big, no permission to add content, bad content type, etc …).

For unfortunate MSIE users, the pure javascipt way cannot allow multiple selection and drag and drop, so the upload form has a graceful fallback, look at the next screencast, it’s not so bad.
And you can also choose in Plone Quick Upload control panel, to replace the pure javascript client script by a Flash Upload based script, it’s not recommended and it cannot work behind an HTTP authenticated server, but  some people want it :

More information about Plone Quick Upload (installation, use it in your own template, etc …) here  :

Written by macadames

24, septembre 2010 at 11:04

Resizing and cropping thumbnails with jquery

with 3 comments

Resizing and cropping images with jquery

Sometimes, we need images with fixed dimensions (carousels, photo albums …), but all images don’t have the good dimensions or good ratio height /width.

This little jquery script will help you for this usecase.

In this example we will fix the dimension and position of thumbnails placed in blocks using the class « imageContainer ». « imageContainer » have a fixed width and height (in this example 250px/150px). The size of thumbs will be increased or reduced, and the thumb will be moved inside its container to get a centered cropping. Of course images and its containers must have a relative position.

Your html template code looks like :

  <a class="imageContainer" href="the_link">
    <img src="the_image_src" alt="" width="450" height="300" />
  <a class="imageContainer" href="another_link">
    <img src="another_image_src" alt="" width="200" height="100" />

In your css, you must fix at least :

.imageContainer img {
  position: relative;

.imageContainer {
  width: 250px;
  height: 150px;
  overflow: hidden;
  border: 1px solid grey;

The javascript code is simple :

var canImproveResolution = false;

thumbResize = function(thumb, min_width, min_height, orientation) {
    twidth = jQuery(thumb).width();
    theight = jQuery(thumb).height();
    new_height = theight;
    new_width = twidth;
    // strange 1px bug on MSIE
    if (jQuery.browser.msie) {
        min_width = min_width+1;
        min_height = min_height+1;
    //calculate the good size
    if (orientation=='landscape') {
        ratio = min_width/min_height;
        tratio = twidth/theight;
        if (tratio>ratio) {
            new_height = min_height;
            new_width = parseInt(new_height*tratio);
        else {
            new_width = min_width;
            new_height = parseInt(new_width/tratio);
    else {
        ratio = min_height/min_width;
        tratio = theight/twidth;
        if (tratio>ratio) {
            new_width = min_width;
            new_height = parseInt(new_width*tratio);
        else {
            new_height = min_height;
            new_width = parseInt(new_height/tratio);

    // resize thumb
    if (theight!=new_height || twidth!=new_width) {
    // adjust position (vertical and horizontal centering for css cropping)
    if (new_width > min_width) {
        moveleft = parseInt((new_width-min_width)/2);
        jQuery(thumb).css('left', '-'+moveleft+'px');
    if (new_height > min_height) {
        movetop = parseInt((new_height-min_height)/2);
        jQuery(thumb).css('top', '-'+movetop+'px');
    // improve resolution
    if (canImproveResolution && (new_width > twidth || new_height > theight)) improveResolution(thumb);

resizeThumbs = function(thumbs, min_width, min_height) {
    orientation = (min_height > min_width) ? 'portrait' : 'landscape';
    // hide images before resizing to avoid bad visual effect
    thumbs.each( function() {
            jQuery(this).css('visibility', 'hidden');
    // use window.load because on document.ready images are not always loaded
    jQuery(window).load(function() {
        thumbs.each( function() {
            thumbResize(this, min_width, min_height, orientation );
            jQuery(this).css('visibility', 'visible');

// change image src for a better resolution
// this is just an example for Plone, adapt it with
// your own sizes rules

improveResolution = function(img) {
    img_src = img.src;
    img_src = img_src.replace(/\/image_preview/gi, '/image');
    img_src = img_src.replace(/\/image_mini/gi, '/image_preview');
    img_src = img_src.replace(/\/image_thumb/gi, '/image_mini');
    img.src = img_src;

For Plone users, there is a small improvement, if you fix the variable :

canImproveResolution = true;

you will get a better resolution when increasing image size  (works only with standard plone image thumb sizes …).

At last launch the script for the wanted thumbnails :

  resizeThumbs(jQuery('.imageContainer img'), 250, 150)});

Written by macadames

4, mars 2010 at 12:18

Plone and multilingual sites

with 9 comments

Usually we build multilingual Plone sites with LinguaPlone.

This solution has a big advantage, it’s generic and very easy to implement in a plone site.

But there are many inconvenients, due to the design of this product (translations are independent by design) :

  • Each translation is a new Archetype object, and it could be a big problem on sites with many contents, the portal objects number is increased by the number of available languages.
  • Translations uses plone references catalog to be linked to the original (called canonical) object, but when moving objects translations are not moved, when copying pasting objects, translations are not pasted, when deleting objects translations are not deleted, when reordering contents, translations are not reordered, when publishing objects translations are not published, … For web masters maintaining a site  with LinguaPlone inside could be a challenge.
  • When translating folders with LP, all translated contents are moved from the canonical folder to the translated folder with same language, translating low level folders on big depth tree sites could take a long long time, don’t be surprise if you get errors.
  • If a content is neutral (with no language attribute), inside a translated folder, it could not be seen when browsing a translation of the parent folder.
  • At last a lower problem :  the translation edit forms are not pretty to use, they show a table with two columns, the first column with the « canonical » content inside in « view » mode, the second column with the translation edit form, in fixed width sites the translated form width is sometimes ridiculously small.

But since many years we use LinguaPlone because it was the only easy way to make multilingual Plone sites.

By the past we were using a LP patch called LinguaFace to reduce the number of problems with LP (synchronisation on reorder, copy-paste, delete, or move – see neutral contents inside all translated folders – more usable translation edit forms …), but LF add a new layer of complexity and maintaining it with all LP versions becomes complicated. See some examples on how it works :

  • when a content is copied, all translations are copied
  • when a content is pasted or moved all translations are pasted or moved at the good place (not so easy)
  • when a content is published or retracted translations follow the same workflow transition
  • when a folder is translated, we don’t see only objects inside but also objects with same canonical Path (a new catalog index) to see also neutral contents.
  • Navtree is patched, breadcrumbs are patched, to use canonical path
  • and so on …

A big nightmare.

To day a new solution exists that store translations inside each Archetypes field, raptus.multilingualfields, and a Plone integration of raptus.multilanguagefields called raptus.multilingualplone that extends the schema of all Plone Content Types making them translatable. raptus.multilingualfields also provides multilingual catalog indexes that return the good translated data when searching for contents or displaying trees, and multilingual criterions for topics.

A LP feature not provided by raptus.multilingualfields is the internationalization of urls, if you really need this feature, i think it’s not a big challenge to add some traversal rules, for me it’s not essential.

AnotherLP  feature that can’t be provided when storing translations in fields is to get different workflows or security settings for each translation. If you need this feature use LinguaPlone, LinguaPlone is done for that, it makes all translated contents independent, but i’m curious to know the number of users who really want this feature, all clients i had never ask for that but finally, after some LP experience, always wanted the exact opposite use-case.

To make your Plone site translatable with raptus.multilanguagefields, you have two choices :

  1. Add raptus.multilanguageplone in your buildout and install it in your Plone Site using extensions products control panel, to make all your Plone content types and derived translatable (all fields for which translation make a sense are translatable).
  2. I prefer integrate by myself raptus.multilanguagefields inside a product, since we could want just some fields or content types translatable, as example i don’t need to translate the images or the files contents, just their titles and descriptions.

How to implement the second solution ?

Just take a look at raptus.multilanguageplone code, it’s easy :

  1. Make your archetype extenders to make your wanted fields translatable, example can be found here
  2. register your extenders in setuphandlers (Generic Setup import step), example here
  3. replace the standard catalog  indexes with multilingual indexes in Generic Setup profile, example here

That’s all, you will get superb edit forms with translatable fields inside, you also will get a google help to translate contents (a pleasant gadget). I say « Bravo » to raptus developpers.

Important :

  • these products are young, and there’s still many work todo to make it work without problems (tests are needed …). Last 0.6 releases have bugs under plone3.3, use the svn versions below instead.
  • raptus.multilanguageplone 0.6  has a bug in extenders with primary fields, tested in Plone 3.3  (fixed in branch aws_evols, not tested with images at this time)
  • raptus.multilanguagefields 0.6 has a bug, doctests are broken in Plone3.3 (fixed in trunk )
  • At this time these products don’t have unit tests or functional tests, it’s the only reproach i can make.  I started the work  here, and here

Written by macadames

6, février 2010 at 2:28

The power of Deliverance and PyQuery

with 8 comments

Some times ago i made a new skin for the French-speaking PYthon Association (AFPY) web site, using Deliverance and PyQuery. I made this exercice on my free time with many pleasure.

You can see the Deliverance power here :

The home page without Deliverance, the same using Deliverance proxy : all dynamic contents are taken from original Plone site, try to find it, you will notice the Deliverance + PyQuery magic in action 🙂

The association pages without Deliverance (a sphinx site), the same contents injected in the site with Deliverance

Thanks to Gaël Pasgrimaud, a friend of mine and coworker, for his big work which really help me :

Here, we use a specific Gael’s buildout and a specific package done for our Deliverance projects used at Ingeniweb, our company. With these tools (if some people are interested in, it could be released on pypi, tell us …), we get the best flexibility for Deliverance :

  • PyQuery integration
  • The good base rules for Deliverance to avoid theming bugs with Ajax and HTML editor (*)
  • Dynamic css : css are mako templates served by a skin server, colors fonts and other properties are set in a « .ini » file
  • A base mako css for Plone which permits to start the work of externalize the entire css :
    in our projects, all portal_css content links from Plone are stripped when the Plone site is called through Deliverance (just add a condition for Plone stylesheets in portal_css : python:request.HTTP_HOST in request.SERVER_URL), the final css is lighter, the Deliverance css is really clean without many ‘!important’ bad overloads)
  • Supervisor deamon to control skin servers
  • We can use eggs for our Deliverance skins.

(*) to get real wysiwyg rendering in Plone behind Deliverance ‘s  HTML editor areas, use also FCKeditor.Plone 2.6.4, in FCKeditor control panel you will find the way to inject Deliverance css in wysiwyg area, it’s an important feature for end users.

Now i can take my summer holidays in peace with myself 🙂

Written by macadames

1, août 2009 at 1:13

3 Colors Theme : a collective phantasy based theme

with 2 comments

Since Plone base properties style could seems too rich for a standard use case, phantasy skin edit forms could be also too complex.

When i saw how easy it is to change some skin properties in a blog system like word press ( …),  i thought we need the same feature in Plone.

Collective Phantasy is done for that.

Building a new skin product with a standard static theme and a customized skin schema is something you can do easily with collective phantasy.

If you want an example, just test the « 3 colors theme » plone product.

In your buildout :

in instance eggs section add :


in zcml section add :


Relaunch your buildout.
Launch your zope instance.

In plone_control_panel you will get :

Check for « Three Colors Theme » Product, this will install the product and its dependencies :

Go back to the home page, of course the « static » theme has changed (my poor contribution to plone themes community)

We want to change the dynamic properties, so we click on « Contents » tab, and we can see that everybody is here : the dynamic root skin for portal, and the phantasy skins repository (read previous posts …) :

We want to build a new skin, so as we have seen in previous posts, in phantasy skins repository we add a new skin :

In this form you could see differences with a classic phantasy skin form (for developpers/integrators look at the code it’s just some easy Archetypes bidouille) :

– 3 colors only + mutators to change all colors

– an entire fieldset removed

– many fields unuseful in this theme are hidden

– some skin attributes added in schema

Go back to reality : just change some colors

Now we will import a skin sample provided in « three colors theme product ».

In alternate_skin folder you will find a zip file and a txt file (howtouseit.txt).

Click on « import images and files », choose the file

Read howtouseit.txt and change some colors or properties

Use plone kss power to change images’ names quickly

CTRL-F5 to refresh the page, of course you need some design feeling to understand what’s happen here, but it’s not so complicated (…)

In the product you will find another example with another howtouseit.txt, here, then just add a folder and choose the good phantasy skin and you will get :

Loving Plone 🙂

Written by macadames

21, octobre 2008 at 9:10