Blog d'un développeur web

Faire son blog sur github avec Jekyll (20 Aug 2013)

Jekyll c'est quoi ?

C'est un générateur de site Internet "statique". Ce n'est pas un CMS vous n'aurez donc pas de backoffice. Le principe est de créer des fichiers puis de demander à jekyll de constuire le site.

L'intérêt de cet outil réside dans le fait que "github" supporte cette technologie. Par exemple le site de Twitter Bootstrap est réalisé avec Jekyll.

En effet vous pouvez faire un dépot avec votre site jekyll et github s'occupe de générer le HTML et de le servir.

Site Internet officiel de Jekyll

Que faire quand Zope reste à 100% de CPU (25 May 2013)

Cet article donne une méthode de travail sous Linux pour trouver un problème d'occupation CPU à 100% qui peut vite rendre votre site inaccessible (503).

Il y a des matins comme ça ou on a pas de chance: Erreur 503 sur un portail réalisé avec le CMS Plone.

Au bout d'un temps aléatoire le processus monte à 100% du CPU et il y reste. Puis c'est au tour des autres processus de votre cluster jusqu'à ce que toutes les instances soient à 100%.

Le premier reflexe, on relance tout :

supervisorctl restart all

Si le problème persiste:

  • On coupe tout
  • On lance un backup full
  • On télécharge tous les logs
  • On prend un café pour réfléchir

Les questions à poser durant le café (les réponses à avoir):

  • (Aux administrateurs système) Depuis quelle heure le problème a lieu ?
  • (Aux administrateurs système) Des livraisons ont elle eut lieu ? (mise à jour système, d'applications, de webservices, ...)
  • (Au client) Quoi que ce soit d' inhabituel dans les manipulations réalisées sur le site ?   Le but de ces questions est d'obtenir un maximum d'information sur les dernières modifications du contenu et de l'environnement, pour pouvoir réduire l'étendue de la recherche.

Cas d'une mise à jour

Il devient simple de résoudre le problème: Une dicotomie du code, correction puis livraison du patch ou retour arrière sur la mise à jour (pas toujours possible)

Autres

Dans ce cas, site planter pour site planter, vous pouvez travailler directement sur le serveur quand c'est possible sinon il faut reproduire le problème ailleur et donc synchronier votre base de données avec celle de prod.

Regarder les logs et corriger les erreurs 500 et les 404 les plus fréquentes

Il faut analyser les logs (instance-X-Z2.log et instance-X.log) et tenter de corriger les erreurs dans un premier temps.

Une page qui fait une erreur est couteux en CPU pour le serveur. Moins vous avez d'erreur plus votre site sera rapide à répondre et plus vos utilisateurs seront content. Il est important de temps en temps de regarder le fichier instance.log pour ça.

Pour corriger une 404 rien de plus simple, il suffit de créer une série de dossier en ZMI avec comme dernier élément un PythonScript avec l'instructuion suivante: return ''  

Rechercher le contenu qui pose problème

Votre client n'a pas pu vous indiquer d'ou venait le problème (ou peut être n'avez vous pas lu vos emails ...) Il faut donc partir à la recherche du contenu.

Dans un premier temps, vous aller augmenter le niveau de log d'une seule instance que vous allez démarrer (seule) puis vous aller regarder les log passer avec la commande tail -f var/log/instance1.log et dans une autre console tail -f var/log/instance1-Z2.log)

Récupérez également la liste des derniers contenus publiées dans votre site et essayer de les afficher.

Regarder dans le fichier access log (Z2.log) vous trouverez les URLs visitée. Pour plus d'information sur les logs Zope, vous pouvez lire la documentation.

Un exemple: La newsletter a été envoyée 12H avant le début des problèmes et il y a eu pas mal d'activité sur Twitter. Dans ce cas afficher l'ensemble des contenus un par un. Il faut trouver ce contenu !

C'est lui !

Vous avez trouvez le contenu qui pose problème ? Chaque fois qu'on essaye de l'afficher, l'instance Zope reste à 100% ! Alors un dernier restart de votre instance et faite /edit pour pouvoir analyser le problème.

Pour ma part le problème était simple, un rédacteur a réaliser un copier/coller d'une image sur le bureau dans l'éditeur WYSIWYG et sous MSWindows cette manipulation insert le contenu de l'image au format base 64. du coup le contenu censé être du texte devient tout de suite plus volumineux. Il suffit d'afficher le code source (bouton HTML dans l'éditeur) pour s'en rendre compte. Supprimez le vitre !

Vous pouvez maintenant revenir en arrière:

  • repasser le niveau de log en erreur
  • démarrer les autres instances
  • appeler votre client

Je ne suis pas certain de la raison mais je pense que le problème vient à l'affichage de la page. En effet le code base64 est valide au sens HTML du terme, donc le CMS le conserve. En revanche la transformation qui a lieu au moment de l'affichage (post filtre) doit être la responsable de l'occupation CPU. Plus de recherche serait nécessaire pour corriger le vrai problème mais ici je me suis contenté de supprimer ce contenu et de faire tourner une note comme quoi il ne faut pas copier/coller une image dans un wysiwyg (tout du moins sous Windows).

Dans mon cas j'ai appris ensuite que le client m'avait envoyé par email cet manipulation réalisée la veille, cet article était bien dans la newsletter mais je l'ai 'manqué' durant ma recherche et j'étais trop occupé pour lire mes emails ... Bref ce fut une mauvaise journée !

L'utilisateur n'est pas le problème ici c'est bien la technologies qui doit permettre de filtrer les images copier/coller dans le wysiwyg au moment de la sauvegarde.

Comment obtenir le mode développeur pour le nexus 4 (27 Mar 2013)

Cet article présente la manipulation à réaliser pour passer son téléphone nexus 4 en mode développeur et ainsi profiter des options de debug USB.

Pour passer un nexus 4 en mode développeur vous devez réaliser la manipulation suivante:

  • Ecran d'accueil
  • -> Toutes les applications (icon)
  • -> paramètres (icon)
  • tout en bas -> à propos du téléphone
  • tout en bas -> Numéros du build
  • faire un tap (click) 7 fois
  • revenir sur paramètres
  • -> options pour les développeurs

Source de l'article

Fr Actualites Comment Installer Openam Avec Buildout (28 Feb 2013)

Contributions pypi (09 Dec 2012)

package name releases downloads collective.js.s3slider 2 1583 collective.recipe.funkload 3 2051 collective.js.jqueryui 35 65363 makina.recipe.postgres 1 1102 collective.steps 4 2465 ooo2tools.core 2 1641 experimental.aggressiveopaquespeedup 2 2182 nmd.plonelinkasvideoembed 2 1588 collective.harlequin 4 2136 collective.remove.kss 2 1538 collective.funkbot 1 736 collective.coreloadtests 1 748 collective.gallery 12 8527 collective.remove.rules 1 686 collective.remove.kupu 1 765 collective.inplacetopicview 1 689 collective.dewslider 1 829 collective.js.galleryview 2 1516 collective.alerts 6 5010 collective.dewplayer 5 3121 collective.hook 1 653 collective.js.slimbox2 4 2102 collective.cssgridsystem 1 640 collective.sugarcrm 7 3345 collective.portlet.contact 3 1555 collective.js.pikachoose 3 1808 collective.js.datatables 15 11367 collective.js.galleriffic 2 2517 collective.js.cufon 1 584 collective.googlelibraries 1 574 collective.portlet.itemview 5 2722 collective.masonry 6 3298 toutpt.zopeskel 7 2579 collective.js.formalize 2 783 collective.googlenews 4 2199 collective.googleforms 1 528 collective.googleloader 1 538 collective.jqueryuithememanager 3 1483 plonetheme.flowerbuds 1 750 collective.configviews 5 2771 collective.googledocsviewer 1 656 collective.seo 2 974 collective.galleria 6 2910 collective.swfobject 2 1013 collective.picnik 2 829 collective.scss 1 443 collective.portlet.embed 3 1741 collective.js.oembed 1 433 collective.oembed 7 3389 collective.portlet.oembed 3 1119 collective.js.easing 1 440 collective.js.fancybox 1 772 collective.js.galleria 6 3887 collective.js.highslide 1 698 collective.js.imagesloaded 2 627 collective.js.mousewheel 1 391 collective.js.twittertext 1 427 collective.registry 1 810 plonetheme.responsive1140 1 344 collective.galleriffic 1 438 collective.fancybox 8 5599 collective.portlet.lingualinks 2 693 collective.localrolesdatatables 6 2448 collective.linguaanalytics 2 528 collective.linguadomains 2 529 collective.linguasitemap 3 988 collective.js.fitvids 1 326 archetypes.linguakeywordwidget 4 1487 collective.portlet.group 2 631 collective.azindexpage 5 1815 collective.addthis 10 6859 collective.js.jcarousel 1 451 collective.js.nivoslider 2 1172 collective.js.nomensamediaplayer 1 371 collective.js.jwplayer 1 307 collective.portlet.videoanysurfer 3 1005 collective.videoanysurfer 6 2173 captionstransformer 4 1255 collective.js.simplecart 1 280 collective.captionmanager 1 305 collective.js.ckeditor 1 223 collective.portlet.nivoslider 1 244 collective.portlet.organization 1 218 collective.metarobots 3 640 collective.baseline 1 202 collective.footerportletmanager 1 181 collective.js.masonry 1 170 collective.js.timeago 2 299 collective.portlet.globalnav 1 151 collective.portlet.jqueryuicalendar 1 137 collective.portlet.twittermultistream 2 196 collective.contentrules.yearmonth 1 106 collective.fancyboxgallery 1 83 collective.portlet.fancyboxgallery 1 77 total 288 201562

Nantes Métropole Développement (09 Dec 2012)

C'est en juillet 2010 que j'avais annoncé la nouvelle version du site Internet nantes-developpement.

Ce projet utilisant beaucoup de modules, je vous fais profiter de ce choix:

Ces modules étaient présent dans la version Plone3 mais ont été retirés:

Migrer de Plone3 à Plone4

La migration a été réalisé via un script de prémigration pour préparer la base de donnée à la migration, la migration effective du site, puis une migration liée aux modules.

Retirer iw.fss

Ce ne fut pas le plus simple. Après avoir lu pas mal de mails autour de ça j'ai adapté un bout de code à mon cas.

Theme

Le changement de charte graphique a été l'évènement déclencheur de la migration. Le thème utilise le framework de grille CSS 960 avec le tout nouveau moteur de thème Plone: plone.app.theming, basé sur diazo.

C'est mon second thème avec ce moteur. Mon avis est qu'il accélère la création de thème simple mais ne permet pas la création d'un thème complet.

Le besoin de surcharger des templates, des viewlets, de connaitre la mécanique des 'skins directories' et autre 'browser view' reste nécessaire.

Integration

J'ai testé beaucoup de modules, créé quelques modules, amélioré, fait des rapports de bug, mais aussi de l'intégration.

J'ai ajouté l'intégration entre les modules collective.addthis et collective.googleanalytics pour que tout partage pousse un évènement social dans GA.

J'ai découvert le module plone.app.search qui est le moteur de recherche de la prochaine version de Plone (4.2). L'intégration au projet a été simple, il m'a suffit d'ajouter Modernizr au registre des javascripts, de modifier le rendu (simple template) et de modifier les liens dans le livesearch pour utiliser cette nouvelle version. Ce nouveau module est bien plus simple que les précédents moteur de recherche.

Le proxy cache Varnish est utilisé et intégré à l'aide du module plone.app.caching. J'ai rapporté un bug concernant la fonction afficher/masquer une portlet qui ne fonctionne pas bien avec varnish.

SugarCRM est utilisé à plusieurs niveaux: authentification, portlet contact, formulaire de lead (via le module PloneFormGen) et une viewlet affichant une entreprise et un contact (activé avec un formulaire autocomplete) le tout via le module collective.sugarcrm.

TinyMCE 1.3 est utilisé dans sa version developpement et utilise ici une modification: la configuration n'est pas la même pour un administrateur de site que pour un contributeur. Vous trouverez le master sur github.

Les galleries (diaporamas) sont affichés avec le module collective.gallery et un affichage basé sur le plugin jquery ad-gallery, en utilisant picasaweb comme base d'albums photos.

Mise à jour du plugin Masonry (09 Dec 2012)

Le module collective.masonry a été mis à jour ! Les nouveautés sont:

Le module JQuery Masonry a été mis à jour à la version 2.0 ainsi que le module JQuery imageLoaded qui l'accompagne.

La page de démonstration a aussi été mis à jour avec des images.

Les deux conteneur de portlets ont été déplacés:

de IAboveContent à IAboveContentBody

de IBelowContent à IBelowContentBody

Votre point de vue m'intéresse !

Comment valider l'accès à webmaster tools avec Plone (30 Aug 2012)

Lors d'une migration d'un site Plone vers une version plus récente avec entre autre un thème Diazo, nous avons perdu la validation du site par Google webmaster tools.

En effet le contenu renvoyé par Plone est modifié par Diazo et devient:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">

Google estime alors que le contenu n'est pas valide et soulève l'erreur suivante: "Vérification Failed"

Pour fixer ce problème vous devez aller en ZMI et remplacer votre fichier html par un 'Script Python' ayant exactement le nom du fichier HTML.

Voici le contenu à mettre dans votre script python:

res = "CONTENU DU FICHIER"
context.REQUEST.response.setHeader('X-Theme-Disabled', 'True')
return res

De cette manière vous indiqué à Dizao de ne pas thémé ce contenu. Le tour est joué !

Comment patcher CKEditor dans le CMS Plone (12 Jun 2012)

Cet article montre comment patcher le module Plone collective.ckeditor et utiliser vos changements en production.

Le cas d'utilisation ici est de changer la valeur par défaut de la largeur du tableau

Il y a des fois ou les modifications que l'on réalise ne peuvent pas être des contributions (souvent parcequ'elles sont spécifiques au projet) et ou l'on ne peut pas simplement surcharger. Je prend ici le cas d'utilisation suivant: Modifier la valeur par défaut du plugin tableau de l'éditeur CKEditor. Il s'agit ici de modifier un fichier JS au milieu des autres et de permettre un déploiement toujours à partir des modules, bref on ne fait pas de fork !

Par défaut le formulaire d'ajout d'un tableau dans CKEditor spécifie une largeur de 500 pixels. La bonne raison de changer ce comportement ? Mon client change cette valeur manuellement à chaque ajout de tableau et met "100%".

Donc en premier lieu, en tant que développeur on récupère le code source de collective.ckeditor:

git clone git://github.com/collective/collective.ckeditor.git

Ensuite il s'agit de trouver les fichiers à modifier. Dans notre cas

collective/ckeditor/browser/ckeditor/_source/plugins/table/dialogs/table.js
collective/ckeditor/browser/ckeditor/plugins/table/dialogs/table.js

Vous pouvez donc maintenant effectuer les modification puis executer la commande suivante à partir de la racine du module:

git diff --no-prefix > table-default.diff

N'oubliez pas l'option --no-prefix ou votre patch ne sera pas utilisable. Maintenant vous avez votre patch. Vous avez donc besoin de l'utiliser dans le déploiement en production de votre projet. Nous utilisons buildout pour déployer nos projet, donc voici un exemple simple de fichier buildout: ckeditor-patch.cfg

[buildout]
extends=http://dist.plone.org/release/4.1-latest/versions.cfg
parts =
    instance
    patch-ckeditor

[instance]
recipe = plone.recipe.zope2instance
user = admin:admin
eggs=
    Plone
    collective.ckeditor
zcml =
    collective.ckeditor

[patch-ckeditor]
recipe = collective.recipe.patch
egg = collective.ckeditor
patches = table-default.diff

Ce buildout installera Plone avec le module collective.ckeditor et appliquera le patch dessus. Voici le résultat dans la console:

$ bin/buildout -c test-patch.cfg
Installing instance.
Getting distribution for 'collective.ckeditor'.
warning: no previously-included files matching '*pyc' found anywhere in distribution
Got collective.ckeditor 3.6.2.
Generated script '/Users/toutpt/myproject/bin/copy_ckeditor_code'.
Installing patch-ckeditor.
patch: reading patch /Users/toutpt/myproject/table-default.diff
patch: total files: 2  total hunks: 2
patch: in /Users/toutpt/.buildout/installed_eggs/collective.ckeditor-3.6.2-py2.6.egg...
patch: processing 1/2:      /Users/toutpt/.buildout/installed_eggs/collective.ckeditor-3.6.2-py2.6.egg/collective/ckeditor/browser/ckeditor/_source/plugins/table/dialogs/table.js
patch: successfully patched /Users/toutpt/.buildout/installed_eggs/collective.ckeditor-3.6.2-py2.6.egg/collective/ckeditor/browser/ckeditor/_source/plugins/table/dialogs/table.js
patch: processing 2/2:      /Users/toutpt/.buildout/installed_eggs/collective.ckeditor-3.6.2-py2.6.egg/collective/ckeditor/browser/ckeditor/plugins/table/dialogs/table.js
patch: successfully patched /Users/toutpt/.buildout/installed_eggs/collective.ckeditor-3.6.2-py2.6.egg/collective/ckeditor/browser/ckeditor/plugins/table/dialogs/table.js

Parce que c'est un déploiement, on essaye toujours deux fois:

$ bin/buildout -c ckeditor-patch.cfg
Installing instance.
Installing patch-ckeditor.
patch: reading patch /Users/toutpt/myproject/table-default.diff
patch: total files: 2  total hunks: 2
patch: in /Users/toutpt/.buildout/installed_eggs/collective.ckeditor-3.6.2-py2.6.egg...
patch: processing 1/2:   /Users/toutpt/.buildout/installed_eggs/collective.ckeditor-3.6.2-py2.6.egg/collective/ckeditor/browser/ckeditor/_source/plugins/table/dialogs/table.js
patch: already patched   /Users/toutpt/.buildout/installed_eggs/collective.ckeditor-3.6.2-py2.6.egg/collective/ckeditor/browser/ckeditor/_source/plugins/table/dialogs/table.js
patch: processing 2/2:   /Users/toutpt/.buildout/installed_eggs/collective.ckeditor-3.6.2-py2.6.egg/collective/ckeditor/browser/ckeditor/plugins/table/dialogs/table.js
patch: already patched   /Users/toutpt/.buildout/installed_eggs/collective.ckeditor-3.6.2-py2.6.egg/collective/ckeditor/browser/ckeditor/plugins/table/dialogs/table.js

Donc maintenant vous avez une instance Zope avec Plone et un CKEditor patché. Tout le monde doit être content!

Attention 1: Comme vous pouvez le constater si vous utilisez un dossier partagés pour vos eggs, le patch y sera appliqué, donc également pour tous les projets utilisant le même egg.

Attention 2: Les plugins sont récupéré à la demande (ajax) et un cache navigateur de 24H est indiqué. Ceci signifie que vous devez vider votre cache navigateur à chaque changement effectué sur le javascript des plugins ou attendre 24 heures. Voici les en-tête HTTP de la réponse pour le fichier table.js qui indique ce cache:

Cache-Control:public,max-age=86400
Content-Length:8733
Content-Type:application/javascript
Date:Tue, 12 Jun 2012 09:07:18 GMT
Expires:Wed, 13 Jun 2012 09:07:18 GMT
Last-Modified:Tue, 12 Jun 2012 08:47:06 GMT

Une série de module pour les sites multi-langues (11 May 2012)

Je viens de mettre à disposition une série de module pour le CMS Plone, réalisé en collaboration avec le CIRB:

collective.linguaanalytics

Ce module surcharge le module très utilisés collective.googleanalytics pour permettre la mise à disposition d'un code de tracking différent par langue. Il peut tout de même être utilisé pour un site mono langue si vous souhaitez ne pas utiliser la fonction d'authentification à google via OAuth mais juste y mettre un code de tracking.

collective.linguadomains

Ce module permet de traduire vos URL et forcer la redirection d'une URL à l'autre si vous changez de langue. Ce module est utile si vous n'utilisez pas les navigationroot du CMS (dossier /fr, /en, ...). Ceci vous évitera de voir des contenus de différentes langues pour chaque domaine. Il va de paire avec le module suivant.

collective.linguasitemap

Ce module met à disposition un sitemap par langue. Par définition un sitemap est multi-langues et doit contenir tous les contenus. Mais si vous traduisez vos noms de domaines, vous allez avoir besoin de prendre en compte la langue et de faire un sitemap par langue.

Le site Internet du Salon Natura 2012 (27 Feb 2012)

Le Salon Natura est le plus grand salon bio de l'ouest. Il aura lieu cette année du 23 au 26 Mars 2012. Le site Internet Salon Natura utilise le CMS Plone avec les modules suivants:

  • collective.addthis
  • collective.galleria
  • collective.googleanalytics
  • collective.masonry
  • collective.js.datatable
  • collective.portlet.embed
  • collective.seo
  • Products.PloneFormGen

Une belle réalisation gérée par la société organisatrice NGE. Toutes mes félicitations !

Comment connaitre les vues utilisées dans votre site Plone (21 Nov 2011)

Ce bout de code affiche les vues utilisées par type de contenu.

Le code source du CMS Plone est maintenant sur Github (06 Oct 2011)

Après un an d'experience pour les modules additionnels via la création de https://github.com/collective , les core développeurs ont décidés de passer le code de Plone sur github.

Encore quelques ajustements sont nécessaires cependant vous trouverez déjà le code de Plone à l'adresse suivante: https://github.com/plone.

En attendant que les comptes LDAP soit migrés vous pouvez forker un module puis faire une pull request.

Le module disqus pour Plone supporte maintenant le multilingue (06 Oct 2011)

Je viens d'ajouter le support du multilingue en suivant l'aide officiel. Donc maintenant disqus s'affiche dans la langue de la page.

Ce module est installé sur le site, vous pouvez donc vérifier en consultant la traduction de cette news !

Présentation du registre de configuration Plone (05 Oct 2011)

Le nouveau moteur de configuration est disponible sous forme de module additionnel depuis Plone4:

Il utilise z3cform comme moteur de formulaire qui sera donc également installé.

Dans les versions précédentes de Plone vous utilisiez le portalproperties qui est un conteneur de "feuille de propriétés" (propertysheet). Dans son utilisation vous pouviez ajouter, modifier ou supprimer vos configuration en ZMI ou via les profiles d'installation. Vous pouviez également accéder à vos propriétés par l'appel à l'API de portalproperties.

Alors pourquoi changer ? Le passage aux composants de zope date de 2001 avec l'apparition de Zope3; La communauté Plone a fait le choix de re-écrire certaines parties de CMF en utilisant les composants dans le plus grand respect de Zope2. On peut ainsi voir l'ensemble des packages plone.* comme des modules python/ztk et tous les packages plone.app.* comme leur intégration dans Zope2/CMF. Au delà des raisons technique l'interface graphique de gestion des confiugration s'en trouve améliorée. On voit aussi disparaitre la notion de propertysheet.

Présentation de plone.registry

Voici la liste des fichiers importants:

  • interfaces.py
  • registry.py
  • recordsproxy.py
  • configure.zcml
  • field.py
  • record.py

Les interfaces (API)

  • IPersistentField
  • IRecord
  • IRecordProxy
  • IRegistry

IPersistentField est un champs persistent. Un champs définit un type de donnée, par exemple le type nombre entier. Il définit également des métadonnées dessus: le nom, la description, quelques contraintes comme la valeur minimale par exemple. La liste des types de champs est disponible sur la documentation officiel ou dans le fichier field.py. En dehors des champs de type primitif, on retrouve un champs de type référence vers un autre Record.

IRecord est un enregistrement dans le registre de configuration. Cet objet appartient donc au registre et garde un pointeur vers celui ci via l'attribut parent. L'attribut field correspond à une instance de IPersistentField et l'attribut value correspond à la valeur de votre configuration.

IRecordProxy est utilisé dans le cadre de l'utilisation de schéma de configuration. Un schéma de configuration est une interface (zope.interface.Interface) ayant des champs (zope.schema). C'est l'approche que je privilégie dans mes implémentations car elle est très claire, orientée objet et facile à utiliser. Donc un RecordProxy est un objet qui peut implémenter dynamiquement un schéma de données. Les accès au valeur se font alors par les attributs de l'instance.

IRegistry est le chef d'orchestre. C'est le composant que vous allez demander via l'utilisation de queryUtility. Il est le conteneur des enregistrements et dispose d'une api permettant d'accéder à la configuration de différente manière:

  • clé/valeur
  • record proxy

Intégration au CMS (plone.app.registry)

Maintenant que vous avez compris la base de ce module nous allons passer à la partie CMS.

L'intégration réalisée met à disposition un registre au niveau du site accessible par le panneau de configuration sous le nom 'Registre de configuration'. Il se présente sous la forme d'un tableau clé, valeur. Chaque clé est affichée sous la forme d'un lien qui ouvrira un 'overlay' contenant un formulaire qui vous permettra de modifier les valeurs

screenshot of the plone.app.registry controlpanel

Utilisation (développeur & intégrateur)

Qui dit configuration dit aussi profile de configuration. Lors de l'installation de votre module vous souhaitez disposer d'une configuration. Voici la marche à suivre.

Définition et initialisation de la configuration

Il faut commencer par créer un schéma de données comme par exemple :

from zope.interface import Interface
from zope import schema
class IZooSettings(Interface):
    entryPrice = schema.Decimal(title=u"Admission charge")
    messageOfTheDay = schema.TextLine(title=u"A banner message", default=u"Welcome!")

Ajouter un fichier registry.xml dans le profile d'installation de votre module:

<registry>
  <record interface="my.package.interfaces.IZooSettings" prefix="my.package"/>
</registry>

Vous pouvez installer votre module pour qu'il bénéficie de la configuration correspondante. Les clés auront toutes la forme "my.package." via l'utilisation de l'option prefix.

Les valeurs par défaut de l'interface seront utilisées à la création de votre configuration. Vous pouvez cependant outre passer cela de la manière suivante et proposer d'autres valeurs dans le profile de configuration:

<registry>
  <record interface="my.package.interfaces.IZooSettings" prefix="my.package">  
    <value key="entryPrice">70</value>
  </record>
</registry>

C'est pratique lorsque vous effectuez une intégration de plusieurs modules et que vous souhaitez proposer une autreconfiguration que celle par défaut d'un module X ou Y.

Vous pouvez également demander au registre de ne pas prendre en compte certains champs de votre interface::

<records interface="my.package.interfaces.IZooSettings">
  <omit>messageOfTheDay</omit>
</records>

Utilisation de la configuration

Nous pouvons maintenant apprendre à utiliser cette configuration. Vous pouvez récupérer votre configuration sous deux forme. Soit vous continuer avec un objet correspondant aux schémas de données que plone.registry se charge de construire pour vous avec la classe Record, soit vous décidez d'utiliser la configuration sous forme de dictionnaire python (clé; valeur)

La base est toujours la même::

from zope import component
from plone.registry.interfaces import IRegistry
from my.package import interfaces

...

def mymethod():
    registry = component.getUtility(IRegistry)
    #access par cle/valeur
    entryPrice = registry['my.package.entryPrice']
    #access par recordproxy
    zooSettings = registry.forInterface(interfaces.IZooSettings, check=False)
    if zooSettings is not None:
        entryPriceBis = zooSettings.entryPrice

Le paramètre "check=False" permet de ne rien retourner si le registre ne dispose pas des enregistrements correspondant à l'interface. Dans le cas contraire une exception "KeyError" est soulevée et vous devez donc la gérer avec les instructions python try/except.

Création d'un panneau de configuration de votre module additionnel

Il est toujours pratique pour un administrateur de site de disposer d'un panneau de configuration de votre module additionnel. L'intégration de plone.registry dans le CMS met à disposition la base nécessaire pour pouvoir réaliser un panneau de configuration très rapidement. Pour commencer vous devez créer un fichier controlpanel.py avec ce code:

from plone.app.registry.browser import controlpanel as basepanel
from plone.z3cform import layout
from my.package import interfaces
from my.package import messageFactory as _

class ZooControlPanelForm(basepanel.RegistryEditForm):
    schema = interfaces.IZooSettings

ZooControlPanelView = layout.wrap_form(ZooControlPanelForm, ControlPanelFormWrapper)

ZooControlPanelView.label = _(u"Zoo settings")

Dans votre fichier configure.zcml il faut maintenant ajouter la vue correspondante:

<browser:page
  name="zoo-controlpanel"
  for="Products.CMFPlone.interfaces.IPloneSiteRoot"
  permission="cmf.ManagePortal"
  class=".controlpanel.ZooControlPanelView"
/> 

Dans le profile d'installation vous devez également déclarer la "configlet" pour que votre vue soit accéssible à partir du panneau de contrôle:

<?xml version="1.0"?>
<object
  name="portal_controlpanel"
  xmlns:i18n="http://xml.zope.org/namespaces/i18n"
  i18n:domain="my.package">

  <configlet
    title="Zoo settings"
    action_id="my.package.zoosettings" 
    appId="my.package"
    category="Products"
    condition_expr=""
    url_expr="string:${portal_url}/@@zoo-controlpanel"
    icon_expr="string:${portal_url}/++resource++my.package/icon.png"
    visible="True"
    i18n:attributes="title">
      <permission>Manage portal</permission>
  </configlet>

</object>

La classe RegistryEditForm définie les méthodes "updateFields" et "updateWidgets" qui vous permette d'intervenir sur la construction du formulaire, pour par exemple changer le widgetFactory d'un champs ou encore changer les paramètres d'un widget comme par exemple le paramètre rows d'un champs texte.

Disponible sous forme de module additionnel pour Plone 4 ce module est déjà largement utilisé.

collective.gallery 1.0 et 2.X (22 Sep 2011)

Je viens juste de sortir la première version officiellement stable 1.0.

Un peu d'histoire pour commencer. Ce module a été commencé en 2009. J'avais choisi galleriffic comme plugin JQuery pour réaliser une UI parce que c'était le seul à me permettre d'afficher un album ayant plus de 300 photos. Ensuite j'avais choisi picasaweb comme mode de stockage pour les fonctionnalités et aussi parce que c'est Google.

Aujourd'hui collective.gallery peut afficher des photos fournis par un dossier, une collection, mais aussi par facebook, flickr et picasaweb au travers du type de contenu lien.

Plan pour la 2.0. Faire une super jolie galerie de photos n'est pas chose simple. En effet les photos sont des éléments à tailles fixes alors que Plone propose une interface fluide par défaut. De plus la réalisation d'un site web ne permet pas de prédire la largeur qui sera disponible. Rendre ceci configurable page par page serait juste un enfer pour tout le monde.

C'est pourquoi collective.gallery ne sera pas fourni avec une interface d'affichage dans sa version 2.0. Cependant vous aurez juste à choisir une de celles disponible:

collective.galleriffic collective.galleria collective.gallery deviendra donc un fournisseur de photos utilisant les types de contenu de Plone avec une bonne documentation sur comment réaliser une interface graphique rapidement.

Comment tester un module Plone en 10 minutes (21 Sep 2011)

Introduction

Quand on travaille avec un CMS, il est courant de vouloir tester un module et de ne pas le faire par faute de temps. Ce que vous ne savez peut être pas c'est qu'un module peut être testé en 10 minutes.

Prérequis

Il faut pour suivre ce tutorial disposer d'un python version 2.6 avec le nécessaire en dépendances (support SSL, tar, zip, libjpeg, ...)

Un autre prérequis est de connaitre l'adresse URL du dépot de code utilisé pour ce module. Avec Plone vous avez souvent:

Sinon c'est pas bon signe, votre module ne fait pas partie de la communauté Plone.

Tutorial

Initialisation (2 minutes)

svn co https://svn.plone.org/collective/collective.lemodule/trunk collective.lemodule
/my/python/2.6/bin/python bootstrap.py
bin/buildout
bin/instance fg

Si le module ne dispose pas des fichiers buildout.cfg et bootstrap.py c'est assez facile de les ajouter:

wget http://svn.zope.org/*checkout*/zc.buildout/trunk/bootstrap/bootstrap.py
wget https://github.com/collective/collective.googledocsviewer/blob/master/buildout.cfg

Il vous reste à modifier le fichier buildout.cfg pour remplacer le contenu de la variable package-name par le nom du module que vous souhaitez tester (dans notre cas il faudra mettre collective.lemodule)

Lecture du code (3 minutes)

Il faut jeter un oeil pour savoir:

  • setup.py il y a des dépendances ?
  • [src/]collective/package/profiles/default/* Qu'est ce que le module installe, un tool ? un type de contenu ? des vues ? ...)
  • regarder rapidement le reste du code pour en voir la qualité
  • regarder changelog ([docs]/CHANGES.txt, [docs]/HISTORY.txt) pour voir si le module est récent et s'il le développement est actif

Tester le module

  • ajouter un site plone
  • installer le module
  • tester les fonctionnalités que vous avez compris du default profile du module

Si Il vous reste un peu de temps tu peux faire la traduction directement et faire un mail sur la liste de diffusion plone-fr.