Lire la dernière version de ce document au format PDF

publicité
Plone pour les intégrateurs
Version 1.0.0
plone-fr
17-April-2017
Table des matières
1
A propos de ce document
1.1 Organisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Liste des thèmes abordés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3 Ressources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
Présentation de Plone
2.1 Les besoins . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Pourquoi Plone . . . . . . . . . . . . . . . . . . . . . . .
2.3 Centralisation des documents . . . . . . . . . . . . . . .
2.4 Édition des contenus . . . . . . . . . . . . . . . . . . . .
2.5 Visualisation des documents . . . . . . . . . . . . . . . .
2.6 Classement des documents . . . . . . . . . . . . . . . . .
2.7 Stockage des documents . . . . . . . . . . . . . . . . . .
2.8 Authentification . . . . . . . . . . . . . . . . . . . . . .
2.9 Permissions, rôles et groupes d’utilisateurs . . . . . . . .
2.10 Indexation . . . . . . . . . . . . . . . . . . . . . . . . .
2.11 Photothèques . . . . . . . . . . . . . . . . . . . . . . . .
2.12 Fonction d’alerte . . . . . . . . . . . . . . . . . . . . . .
2.13 Actualités, événements, calendrier, lettres d’informations .
2.14 Espace projet . . . . . . . . . . . . . . . . . . . . . . . .
2.15 Répertoires dynamiques . . . . . . . . . . . . . . . . . .
2.16 Références croisées . . . . . . . . . . . . . . . . . . . .
2.17 Modération du contenu . . . . . . . . . . . . . . . . . . .
2.18 Historique des changements effectués sur le contenu . . .
2.19 Flux RSS . . . . . . . . . . . . . . . . . . . . . . . . . .
2.20 Langue du portail, Multilinguisme, Traduction . . . . . .
2.21 Charte graphique . . . . . . . . . . . . . . . . . . . . . .
2.22 Trombinoscope et annuaires . . . . . . . . . . . . . . . .
2.23 Génération de documents à partir de modèles . . . . . . .
3
3
3
3
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
5
6
6
11
12
12
12
12
14
14
14
15
15
15
15
15
17
18
18
20
20
20
3
Les nouveautés de Plone
3.1 Les nouveautés de Plone 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Les nouveautés de Plone 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
23
26
4
Paramétrer votre site Plone
4.1 Objectif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Accéder au menu de configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 Configurer les paramètres de messagerie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
31
33
33
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
i
4.4
4.5
4.6
4.7
4.8
4.9
4.10
4.11
4.12
4.13
4.14
4.15
4.16
4.17
4.18
4.19
4.20
4.21
4.22
4.23
4.24
5
6
7
8
9
ii
Paramètres du site . . . . . . . . . . . . . . . . .
Paramètres de base de la sécurité du site . . . . . .
Paramétrage du calendrier . . . . . . . . . . . . .
Paramétrage de la navigation . . . . . . . . . . . .
Paramètres de la recherche . . . . . . . . . . . . .
Configurer le thème . . . . . . . . . . . . . . . .
Paramétrage des modules . . . . . . . . . . . . .
Paramétrage des règles de contenu . . . . . . . . .
Paramétrer l’édition de contenus . . . . . . . . . .
Paramétrer le filtrage du contenu ajouté en HTML
Paramétrer le comportement wiki . . . . . . . . .
Gestion des tailles d’images . . . . . . . . . . . .
Maintenance du serveur et de la base . . . . . . .
Choix de la langue du Site . . . . . . . . . . . . .
Paramétrer les types de contenu . . . . . . . . . .
Gestion des utilisateurs et groupes . . . . . . . . .
Caching . . . . . . . . . . . . . . . . . . . . . . .
Discussion . . . . . . . . . . . . . . . . . . . . .
Registre de configuration . . . . . . . . . . . . . .
Syndication . . . . . . . . . . . . . . . . . . . . .
Éditeur de texte riche TinyMCE . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
33
35
39
45
49
53
53
55
55
58
62
62
62
64
64
69
72
72
72
72
72
Choix et ajout d’un module
5.1 Introduction . . . . . . . . . . . . .
5.2 Rechercher et sélectionner un module
5.3 Installer un module . . . . . . . . . .
5.4 Tester le module . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
73
73
73
74
76
Le protocole HTTP et ses tests
6.1 Définition . . . . . . . . .
6.2 Savoir . . . . . . . . . . .
6.3 Exercice . . . . . . . . .
6.4 Ressources . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
77
77
78
82
83
Rappel HTML et XML
7.1 Définition . . . . .
7.2 Savoir . . . . . . .
7.3 Exercices . . . . .
7.4 Ressources . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
85
85
86
89
89
Concept de Python eggs
8.1 Définition . . . . . . . . . . . . . . . . . . . . . . . . .
8.2 Savoir . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.3 Installation de Python et Distribute . . . . . . . . . . .
8.4 Packaging Python . . . . . . . . . . . . . . . . . . . .
8.5 Passons au développement . . . . . . . . . . . . . . . .
8.6 L’API pkg_resources . . . . . . . . . . . . . . . . . . .
8.7 Les entry points . . . . . . . . . . . . . . . . . . . . .
8.8 Mise en place d’un Pypi privé avec PloneSoftwareCenter
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
91
. 91
. 92
. 92
. 92
. 99
. 103
. 104
. 105
Introduction à zc.buildout
9.1 Définition . . . . . . . . . . . . . . . .
9.2 Introduction . . . . . . . . . . . . . .
9.3 Organisation d’un buildout . . . . . . .
9.4 Section principale [buildout] . . . . . .
9.5 Partage du dossier eggs et downloads .
9.6 Pinning des versions . . . . . . . . . .
9.7 Extension buildout.dumppickedversions
9.8 Option extends . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
109
109
110
110
110
112
113
113
114
9.9
9.10
9.11
9.12
9.13
9.14
Recipe collective.recipe.omelette . . . . .
Utilisation de variable . . . . . . . . . . .
Repinning et fusion de section de données .
Ordre d’installation des parts . . . . . . . .
L’option develop . . . . . . . . . . . . . .
Option index et find-links . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
115
116
117
117
118
118
10 Installation et création d’une instance Plone
121
10.1 Savoir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
10.2 Exercice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
11 Création d’un buildout Plone avec ZopeSkel
11.1 Création du buildout . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11.2 Installation de produits tierces . . . . . . . . . . . . . . . . . . . . . . .
11.3 Création d’un policy package contenant la configuration du site Plone . .
11.4 À propos des versions . . . . . . . . . . . . . . . . . . . . . . . . . . .
11.5 Releaser le policy package . . . . . . . . . . . . . . . . . . . . . . . . .
11.6 Repasser au développement . . . . . . . . . . . . . . . . . . . . . . . .
11.7 Utilisation de mr.developer pour gérer les composants en développement
11.8 Fabric . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11.9 Ressources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
129
130
131
132
137
137
138
139
140
141
12 Déploiement et backup
12.1 Définition . . . . . . . . . . . . . . . . . . . . .
12.2 Savoir . . . . . . . . . . . . . . . . . . . . . . .
12.3 Profil de déploiement . . . . . . . . . . . . . . .
12.4 Supervisor . . . . . . . . . . . . . . . . . . . .
12.5 Support des backups . . . . . . . . . . . . . . .
12.6 Cron job pour zeopack et backup . . . . . . . .
12.7 Configuration d’Apache . . . . . . . . . . . . .
12.8 Configuration des DNS . . . . . . . . . . . . . .
12.9 Installation et configuration de plone.app.caching
12.10 Ressources . . . . . . . . . . . . . . . . . . . .
12.11 Exercice . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
143
143
144
144
148
149
150
150
152
152
153
153
13 Zope External Editor
13.1 Activation du lien “Modifier avec une application externe”
13.2 Installation du client External Editor sous Ubuntu . . . . .
13.3 Installation du client External Editor sous Windows . . .
13.4 Problèmes de cache avec l’External Editor . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
155
155
155
156
156
14 Monitoring avec Munin
14.1 Plugins Zope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14.2 Plugins Varnish . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14.3 Ressources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
159
160
161
161
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
15 PloneFormGen
163
15.1 Présentation de PloneFormGen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
15.2 Exercice : Réalisation d’un formulaire de sondage . . . . . . . . . . . . . . . . . . . . . . . . . 174
16 Le theming Plone avec Diazo
175
16.1 Diazo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
16.2 Produit de skin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
17 Ecrire des scripts Plone : bases
17.1 Introduction . . . . . . . . . . . . . . . . . . .
17.2 Mon premier script . . . . . . . . . . . . . . . .
17.3 Créer et gérer des contenus par script . . . . . .
17.4 Connaître et exploiter les informations utilisateur
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
195
196
196
199
203
iii
17.5 Utiliser le catalogue de Plone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
18 Ecrire des templates Plone : bases
18.1 Introduction . . . . . . . . . . . . . . . . . . . . . .
18.2 Ma première template . . . . . . . . . . . . . . . . .
18.3 Appel à un script . . . . . . . . . . . . . . . . . . . .
18.4 Utiliser la master template de Plone . . . . . . . . . .
18.5 Utiliser une structure plus complexe dans une template
18.6 Appeler une template depuis une autre template . . . .
18.7 Exercices . . . . . . . . . . . . . . . . . . . . . . . .
18.8 Ecrire la template sous la forme d’une vue . . . . . .
18.9 Une vue pour un export csv . . . . . . . . . . . . . .
18.10 Une viewlet pour ajouter un lien vers une vue . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
209
209
210
210
211
212
213
213
213
214
216
19 TAL/Metal : les templates de Zope et Plone
19.1 Le langage TAL . . . . . . . . . . . .
19.2 TALES . . . . . . . . . . . . . . . . .
19.3 METAL . . . . . . . . . . . . . . . . .
19.4 Ressources . . . . . . . . . . . . . . .
19.5 Namespaces . . . . . . . . . . . . . .
19.6 Variables globales . . . . . . . . . . .
19.7 Présentation des ZPT . . . . . . . . . .
19.8 Le langage TAL . . . . . . . . . . . .
19.9 TALES . . . . . . . . . . . . . . . . .
19.10 METAL . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
219
220
221
221
221
221
222
222
223
224
226
20 Paramétrage local des workflows
20.1 Préparation . . . . . . . . . . . . .
20.2 Installation du module . . . . . . .
20.3 Gestion des politiques de workflow
20.4 Affectation des workflows locaux .
20.5 Export Generic Setup . . . . . . .
20.6 Conclusion . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
229
229
229
232
235
235
235
21 Déclenchement d’événements avec les règles de contenu
21.1 Objectif de la formation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21.2 Préparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21.3 Créer une règle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21.4 Paramétrer une règle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21.5 Créer une condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21.6 Créer une action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21.7 Activer la règle pour une partie du site . . . . . . . . . . . . . . . . . . . . . . . . .
21.8 Tester la règle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21.9 Exemple 2 : Logguer les suppressions de documents . . . . . . . . . . . . . . . . .
21.10 Exemple 3 : Déplacer les événements dans un même dossier, où qu’ils soient ajoutés
21.11 Export Generic Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21.12 Extensibilité . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21.13 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
239
239
240
240
240
242
242
243
245
245
246
247
247
248
22 Créer des pages composées en ligne avec Collage
22.1 Préparation . . . . . . . . . . . . . . . . . .
22.2 Objectif de la formation . . . . . . . . . . .
22.3 Installer Products.Collage . . . . . . . . . .
22.4 Créer un Collage . . . . . . . . . . . . . . .
22.5 Ajouter les éléments du Collage . . . . . . .
22.6 Utiliser le collage comme page d’accueil . .
22.7 Paramétrer l’affichage du collage . . . . . .
22.8 Extensibilité . . . . . . . . . . . . . . . . .
22.9 Conclusion . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
249
249
249
249
250
250
254
254
258
258
iv
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
23 Glossaire
267
24 Indexes et tables
271
25 Contributeurs
273
Index
275
v
vi
Plone pour les intégrateurs, Version 1.0.0
Astuce : Pour voir cette documentation dans son site original et accéder à son moteur de recherche, veuillez vous
rendre ici.
Lire la dernière version de ce document au format PDF
Ce document constitué à partir de contributions de la communauté Plone francophone, notamment :
– Le manuel de formation intégrateur Plone par Vincent Fretin (Ecréall)
– Les travaux, les relectures et les très nombreuses contributions de Gilles Lenfant, Thomas Desvenain et Michael
Launay
– La documentation sur le theming par Éric Bréhault (Makina Corpus)
Cette création est mise à disposition selon le Contrat Paternité-Partage des Conditions Initiales à l’Identique 2.0
France disponible en ligne http ://creativecommons.org/licenses/by-sa/2.0/fr/ ou par courrier postal à Creative
Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA.
Table des matières
1
Plone pour les intégrateurs, Version 1.0.0
2
Table des matières
CHAPITRE 1
A propos de ce document
1.1 Organisation
La formation est découpée en thèmes.
Presque chaque thème comprend :
– un objectif,
– un savoir à acquérir,
– un exercice pratique permettant de fixer le savoir acquis,
– un bilan oral, résumant ce qui a été acquis.
1.2 Liste des thèmes abordés
–
–
–
–
–
–
–
–
–
–
–
–
Présentation de Plone
Concept de Python eggs
Création d’un buildout
Création d’un thème
Moteur de template (TAL/Metal)
Concepts de base Zope 3 (composants)
Internationalisation
Moteur de règle (pour réagir à un événement)
Notions avancées de formulaire d’édition
Migration d’une version de Plone à l’autre
Déploiement et backup
[deprecated] ArchgenXML
1.3 Ressources
Livres de Packt Publishing, en anglais :
– Professional Plone 4 Development Martin Aspeli Aout 2011
– A users guide to Plone september 2010
– Practical Plone 3 : A Beginner’s Guide to Building Powerful Websites, Alex Clark, Clayton Parker, Darci
Hanning, David Convent, John DeStefano, Jon Stahl, Martin Aspeli, Matt Bowen, Ricardo Newbery, Sam Knox,
Steve McMahon, Tom Conklin, Veda Williams, février 2009
– Plone 3 Theming, Veda Williams, juillet 2009
– Plone 3 for Education, Erik Rose, décembre 2009
– Plone 3.3 Site Administration, Alex Clark, mars 2010
– Plone 3.3 Multimedia, Tom Gross, juin 2010
3
Plone pour les intégrateurs, Version 1.0.0
4
Chapitre 1. A propos de ce document
CHAPITRE 2
Présentation de Plone
Author Michael Launay
Version 0.1.0
Copyright (C) 2010 Michael Launay <michaellaunay AT ecreall.com>.
Chacun est autorisé à copier, distribuer et/ou modifier ce document suivant les termes de la licence
Paternité-Pas d’Utilisation Commerciale-Partage des Conditions Initiales à l’Identique 2.0 France accessible à
http ://creativecommons.org/licenses/by-nc-sa/2.0/fr
Le code source présent dans ce document est soumis aux conditions de la « Zope Public License », Version 2.1
(ZPL).
THE SOURCE CODE IN THIS DOCUMENT AND THE DOCUMENT ITSELF 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.
2.1 Les besoins
Plone permet de satisfaire les besoins d’espaces collaboratifs pour organiser, partager et diffuser des informations
et des documents.
Il permet de centraliser et référencer l’information pour l’utilisateur via une interface web intuitive.
Il fournit une vitrine et un outil d’animation.
Nous montrerons comment le CMS open source Plone répond aux exigences fortes que sont :
– Un usage simple et ergonomique pour l’utilisateur.
– Un fort niveau de paramétrage pour l’administrateur.
2.2 Pourquoi Plone
Plone est une solution open source multiplateforme, performante, stable et sûre qui existe depuis 2001.
Le CMS Plone évolue constamment sans perte de compatibilité. Il est maintenu par une communauté de sociétés
qui en assure la pérennité et l’adéquation avec le besoin des clients.
En France on trouve pas moins de 14 sociétés spécialisées réalisant en support expert sur cette technologie sur les
369 sociétés mondiales réparties sur 62 pays (C.f. http ://plone.org/support/providers).
5
Plone pour les intégrateurs, Version 1.0.0
2.3 Centralisation des documents
Le portail collaboratif Plone est un un espace unique où trouver et échanger des informations. Il se présente sous
la forme d’un site internet accessible en intranet comme en extranet.
Le fonctionnement client-serveur d’internet offre naturellement la centralisation voulue.
Les utilisateurs saisissent l’URL du portail depuis leur navigateur internet, s’authentifient, et accèdent alors aux
documents de l’entreprise.
2.4 Édition des contenus
L’édition des contenus se fait par une étape de création, suivie automatiquement d’une édition, d’un enregistrement
puis éventuellement d’un changement d’état.
L’utilisateur se place dans une partie de l’arborescence du site en utilisant la navigation.
S’il en a les droits il peut alors ajouter un contenu qui peut être un document, d’événement, de répertoire, de fichier
ou tout type créé spécifiquement, etc.
F IGURE 2.1 – Exemple de navigation
Une fois placé à l’endroit voulu dans l’arborescence, l’utilisateur choisit le type d’élément voulu dans le menu
“Ajout d’un élément”.
Une page sur l’édition du nouveau document s’ouvre et l’on peut saisir le contenu du document :
Le portail vérifie les saisies lorsqu’on passe d’un champ à l’autre.
Une fois la saisie réalisée, il suffit de cliquer sur le bouton “Enregistrer”.
Tant que l’enregistrement n’est pas fait le nouveau contenu est en mode brouillon, c’est-à-dire qu’il n’est pas
réellement ajouté à l’arborescence.
6
Chapitre 2. Présentation de Plone
Plone pour les intégrateurs, Version 1.0.0
F IGURE 2.2 – Ajout d’un élément
F IGURE 2.3 – Création d’un document
2.4. Édition des contenus
7
Plone pour les intégrateurs, Version 1.0.0
L’édition des contenus se fait par l’intermédiaire de formulaires propres à chaque type.
F IGURE 2.4 – Exemple d’édition d’un document
On peut remarquer dans cette capture l’éditeur en ligne qui permet une mise en forme riche avec création de titre,
changement de police, de couleur, insertion de listes numérotées, d’images pouvant être retaillées...
De nombreuses fonctionnalités de cet éditeur peuvent être paramétrées par l’administrateur (boutons disponibles,
etc)
Chaque type de document possède une liste de méta-informations telles que l’auteur, la date de création, la date
de publication, la date de retrait du document, etc.
Il est à noter que toutes les méta-informations sont remplies par défaut avec les valeurs issues du contexte.
L’édition des méta-informations se fait par clic sur l’onglet voulu, ici nous avons appuyé sur “Catégorisation”.
Pour ajouter de nouveaux mots-clés, il suffit lorsqu’on a les droits de les entrer dans l’encart “Nouveaux motsclés”.
L’onglet date permet de préciser la période de publication d’un élément. Ici le document sera visible entre le 16
juin 2010 et le 30 juillet.
8
Chapitre 2. Présentation de Plone
Plone pour les intégrateurs, Version 1.0.0
F IGURE 2.5 – Association de mots clés aux documents
F IGURE 2.6 – Date de publication d’un document
2.4. Édition des contenus
9
Plone pour les intégrateurs, Version 1.0.0
F IGURE 2.7 – Propriété d’un élément
10
Chapitre 2. Présentation de Plone
Plone pour les intégrateurs, Version 1.0.0
L’onglet propriété permet de gérer les notions de droit d’auteur.
F IGURE 2.8 – Paramètres d’un document
L’onglet paramètres permet de préciser comment le document sera visible dans l’arborescence et si l’on autorise
les commentaires.
Seul l’onglet “contenu” est obligatoire, les autres sont remplis par défaut et peuvent être cachés aux utilisateurs.
Une fois que l’on a “enregistré”, le document s’affiche en mode consultation et l’on peut alors changer son état en
cliquant sur l’onglet affichant l’état (ici “Privé”).
2.5 Visualisation des documents
La visualisation des documents, que ce soient des fichiers, des pages, des images, des liens, des actualités, des
événements, permet des mises en formes élaborées reposant sur les dernières techniques du web.
Si les documents à partager via le portail sont des images ou des fichiers produits par les outils de bureautique classique (suite Microsoft office, Open Office, PDF, etc.), ils pourront être prévisualisés directement sur le navigateur
internet des utilisateurs.
Plone peut embarquer des outils permettant de transformer des documents Word, Excel, PowerPoint, etc, en page
web. Dès lors un simple navigateur internet suffit pour les consulter.
2.5. Visualisation des documents
11
Plone pour les intégrateurs, Version 1.0.0
2.6 Classement des documents
La création et le dépôt des documents peuvent suivre les règles de classement des documents édictées par les habitudes des utilisateurs. Il est donc possible de garantir le respect d’un plan documentaire défini par des procédures
qualités.
Ce classement est naturel, le portail possède un espace de navigation qui se présente comme une arborescence de
fichiers, en conséquence Plone ne permet de créer les documents et sous-répertoires que là où ils ont du sens.
On peut définir des types de sous-répertoires n’acceptant que certains types d’éléments, par exemple un répertoire
Photothèque ne contiendra que des images.
Autre exemple, le répertoire Présentation ne permettra que le dépôt des documents respectant le modèle des
présentations.
Le plan documentaire peut être établi dynamiquement en ligne par les utilisateurs du site – selon leurs droits et/ou être défini de manière statique.
2.7 Stockage des documents
Le portail est une zone d’échange et d’archivage des contenus, qui permet de savoir qui a déposé un document, et
quand.
Il gère le temps de visibilité des documents et les droits de consultation ou de modification.
Les documents, les changements effectués, la liste des membres sont stockés par défaut dans une base de données
objet. Il est possible d’utiliser notre solution avec d’autres bases de données, relationnelles ou non.
2.8 Authentification
Seules les personnes habilitées à voir les documents les voient, seules celles habilitées à les modifier peuvent le
faire.
Chaque utilisateur de Plone possède son propre login et mot de passe.
Ils peuvent être spécifiques au site ou issus d’une source externe, comme un annuaire LDAP (l’Active Directory
de Microsoft par exemple).
Il est très aisé de combiner différentes sources.
Des solutions existent pour gérer la connexion par SSO.
Dans ce cas, l’utilisateur connecté à sa session de Windows (par exemple) est automatiquement logué au site
quand il y accède.
2.9 Permissions, rôles et groupes d’utilisateurs
Chaque état d’un type de contenu définit les permissions nécessaires à sa création, sa consultation, à son édition
et sa suppression.
Un utilisateur possède un ou plusieurs rôles qui lui attribuent ou non les permissions sur les contenus parcourus.
On peut définir autant de rôles que voulus.
Il est possible de réunir plusieurs rôles dans des groupes auxquels appartiennent plusieurs utilisateurs (administrateur, relecteur, membre, anonyme, authentifié, etc). En conséquence, un utilisateur possède un ou plusieurs rôles,
et un rôle peut lui être attribué de façon locale dans un dossier, ou attribué par les groupes auxquels il appartient.
Les administrateurs peuvent aisément créer des groupes et les gérer.
12
Chapitre 2. Présentation de Plone
Plone pour les intégrateurs, Version 1.0.0
F IGURE 2.9 – Authentification par login et mot de passe
F IGURE 2.10 – Gestion des utilisateurs
2.9. Permissions, rôles et groupes d’utilisateurs
13
Plone pour les intégrateurs, Version 1.0.0
La gestion des permissions se fait à travers le mécanisme des ACL (Access Control List).
La gestion des utilisateurs, des rôles, et des groupes se fait à travers une interface relativement simple.
2.10 Indexation
Le portail offre des fonctions de recherche simple et complexe, sur le contenu des documents et les métainformations.
Le texte des documents saisis en ligne ou téléchargés (pour les formats les plus courants : Word, Excel, Power
Point, pdf, etc.) est indexé.
Le moteur de recherche rapide est constitué d’un champ présent en permanence sur toute les pages.
Il permet d’effectuer des recherches rapides.
La recherche de l’utilisateur est analysée au fur et à mesure de la saisie, des propositions sont faites automatiquement à partir des données de la base.
Un formulaire de recherche détaillé permet de filtrer la recherche en fonction des méta-informations, et de lier les
critères entre-eux avec les mots-clés OR et AND.
F IGURE 2.11 – Recherche dynamique
L’indexation des éléments (document, fichier, événements) est entièrement paramétrable.
2.11 Photothèques
Les images, dessins, photos peuvent être gérées dans des galeries permettant leur manipulation, visualisation,
recherche et intégration aux documents rédigés en ligne.
Plone permet de retailler les images, de les afficher sous forme de vignettes, ou dans des diaporamas.
2.12 Fonction d’alerte
Les membres du portail peuvent être prévenus lorsque des mises à jour ou des modifications ont été réalisées sur
les documents.
Un mécanisme événementiel permet de réaliser des actions lorsque certaines choses se produisent sur le portail
(nouvel utilisateur, publication d’un document...).
Toutefois, la façon standard de notifier les contenus modifiés récemment, ou à modérer est d’afficher leur liste à
droite ou à gauche du contenu publié.
14
Chapitre 2. Présentation de Plone
Plone pour les intégrateurs, Version 1.0.0
2.13 Actualités, événements, calendrier, lettres d’informations
Les actualités et les événements sont des types de base de Plone, le calendrier affiche les événements que l’on est
autorisé à voir en fonction de ses rôles, ou groupes.
La liste des événements est accessible par simple clic sur l’onglet “Événements”.
Les dernières actualités sont accessibles en cliquant sur l’onglet “Actualités”.
Ces deux listes peuvent être affichées directement à gauche ou à droite du contenu.
Ce placement est paramétrable en ligne par l’administrateur (par exemple en dessous du calendrier).
Plusieurs types de lettres d’informations sont possibles, il est facile de modifier la charte graphique des lettres.
Le système de lettres d’informations permet de gérer les abonnements désabonnements et peut déléguer à l’émetteur de choisir les membres ou groupes devant la recevoir.
2.14 Espace projet
Le portail permet facilement de mettre en place la notion de projet, et offre donc :
1. un calendrier qui tient compte de vos droits pour afficher les événements,
2. des listes de tâches,
3. des classeurs de documents (containers),
4. des forums,
5. des sondages,
6. des actualités.
2.15 Répertoires dynamiques
Il est également possible de créer ses propres “collections” de documents : il s’agit de répertoires dont le contenu
est en réalité le résultat d’un recherche basée sur des filtres.
Il peuvent être emboité les uns dans les autres et en modifiant les critère de recherche, on peut ainsi créer des
répertoires transversaux au plan documentaire.
2.16 Références croisées
Le portail permet de “lier” des documents entre-eux. Exemples :
1. Fiche descriptive d’un produit et différentes photos d’applications de ce produit.
2. Associer un document en anglais et des traductions faites à partir de ce document.
La notion de lien internet est fortement utilisée et permet à Plone de créer des références entre documents.
2.17 Modération du contenu
Certaines personnes peuvent avoir pour charge d’accepter ou non la publication des documents sur le portail.
Plone permet ceci comme la plupart des CMS (Content Management System) du marché, mais il ne fige pas la
chaîne de validation (Workflow), que l’on peut modifier.
Par exemple nous avons défini le workflow des tâches de la gestion des projets comme suit :
Les états définissent les permissions à avoir pour par exemple voir ou modifier les documents, en les attribuant ou
non à des rôles.
2.13. Actualités, événements, calendrier, lettres d’informations
15
Plone pour les intégrateurs, Version 1.0.0
F IGURE 2.12 – Exemple de workflow
16
Chapitre 2. Présentation de Plone
Plone pour les intégrateurs, Version 1.0.0
Les transitions définissent qui a le droit de changer les états des documents, dans quelles conditions et quels sont
alors les traitements à réaliser.
Les utilisateurs voient les transitions qu’ils peuvent exécuter.
F IGURE 2.13 – Changement d’état d’un élément
La mise en place de chaîne de validation des documents autres que ceux prévus par défaut, passe par la création
d’états et transitions. Ceci se fait soit directement à travers l’interface d’administration de Plone soit par l’utilisation d’outils spécifiques.
La possibilité de créer simplement et efficacement les workflows associés aux documents déposés ou créés sur le
portail est l’un des grands atouts de Plone.
La précision de paramétrage des permissions permet de cacher ou montrer les champs d’un document en fonction
de l’état du document et des rôles de l’utilisateur.
Il est possible de modéliser les workflows en utilisant les outils graphiques basés sur UML (Unified Model Language), Argouml et ArchgenXML.
Les administrateurs peuvent modifier les workflows soit en utilisant ces même outils, soit le faire directement à
travers le web une fois authentifiés sur le portail.
2.18 Historique des changements effectués sur le contenu
Le système trace toutes actions. De plus il permet de revenir à l’état précédent pour chaque action.
Ainsi pour les document nous avons un historique pour les changement d’états et pour les modifications apportées.
L’historique permet de voir les changements du document que ce soit les états ou les modifications du contenu.
En comparant deux versions ensemble on peut voir les modifications apportées.
2.18. Historique des changements effectués sur le contenu
17
Plone pour les intégrateurs, Version 1.0.0
F IGURE 2.14 – Affichage de l’historique d’un élément
Ici nous voyons que l’image a été déplacée et qu’un paragraphe a été ajouté.
Il est facile de revenir à une version précédente, puisqu’il suffit de cliquer sur les boutons “revenir à cette version”
que l’on voit dans l’historique.
2.19 Flux RSS
Plone propose nativement l’intégration des flux RSS, ce qui permet aux habitués d’utiliser leur lecteur de flux rss
pour savoir s’ils ont des documents à lire.
2.20 Langue du portail, Multilinguisme, Traduction
Plone est multi-langue et permet de traduire chaque document ou formulaire en plusieurs langues.
Actuellement prés de 80 langues sont supportées et 32 le sont complètement.
Pour rajouter une langue non encore supportée par exemple le “Picard”, il suffit de traduire un ensemble de fichiers
linguistiques.
Les contributeurs peuvent traduire les articles dans une des langues activées pour le site.
Quand un contenu est traduit, les visiteurs du site le consultent dans leur propre langue.
S’il n’est pas traduit dans leur langue, ils le consultent dans la langue par défaut.
18
Chapitre 2. Présentation de Plone
Plone pour les intégrateurs, Version 1.0.0
F IGURE 2.15 – Différences entre deux versions d’un élément
2.20. Langue du portail, Multilinguisme, Traduction
19
Plone pour les intégrateurs, Version 1.0.0
2.21 Charte graphique
Plone utilise la technologie CSS2 pour réaliser les feuilles de styles permettant d’avoir le design approprié.
Le placement des composants tels que le calendrier est facilement effectué en ligne ou par fichier de configuration.
F IGURE 2.16 – Exemple de style basique
Il est possible d’adapter des chartes existantes à vos besoins en changeant par exemple les couleurs, les icônes.
2.22 Trombinoscope et annuaires
Le portail, fournit un trombinoscope des membres.
2.23 Génération de documents à partir de modèles
Il est possible de créer des formulaires permettant aux utilisateurs de n’avoir à saisir que les informations à forte
valeur ajoutée d’un document et de laisser le portail générer les documents en les complétant avec les données
pouvant être automatisées.
Ces documents pourraient aussi bien être des documents textes que des feuilles de calcul, des organigrammes, des
tableaux, des diagrammes et autres courbes.
2.23.1 Sécurité
Plone est reconnu pour le souci de la sécurité qui fait parti de son design initial. Il a été choisi par la CIA, le FBI,
le ministère français de la défense pour cette raison.
20
Chapitre 2. Présentation de Plone
Plone pour les intégrateurs, Version 1.0.0
2.23.2 Montée en charge
Plone fournit des mécanismes de dimensionnement permettant de déployer plusieurs processus sur une ou plusieurs machines en fonction des besoins.
Il est également possible d’utiliser un proxy cache permettant de limiter la sollicitation du serveur.
F IGURE 2.17 – Exemple d’architecture de déploiement pour un site conséquent
2.23.3 Serveur virtuel GNU/Linux vs Serveur W2K8
Plone est compatible avec Windows 2008 mais nous lui préférons GNU/Linux en raison de la puissance du scripting shell qui permet de réaliser simplement et à moindre frais l’intégration de composants complexes.
Avec GNU/Linux, il est possible de réaliser des montages vidéos, photos, ou gérer de la génération de documents
sans interface graphique, ce qui permet par exemple de réaliser des conversions de vidéos avec incrustation et
watermarking avec pour seul investissement celui d’une formation.
2.23.4 Tests Unitaires, tests d’intégrations, tests fonctionnels
La communauté assure un haut niveau de qualité en automatisant les tests unitaires qui vérifient le bon fonctionnement du code, les tests d’intégration quant à eux permettent de tester que les différents composants n’entrent
pas en conflit.
Les tests de validation vérifient que les fonctionnalités continuent de fonctionner comme prévu.
Pour les tests de validation nous enregistrons des scénarios d’utilisation avec des outils comme Selenium.
Ainsi nous pouvons les rejouer à chaque changement, ce qui permet de détecter les effets de bord.
2.23.5 Besoin de formation / Transfert technique
L’ensemble des développements, fichiers de configuration, sont réalisés sous licence compatible GPL.
Nos supports de cours sont reversés à la communauté Plone sous licence Creative-Common Share Alike By, ils
sont donc librement téléchargeables et peuvent être partagés, modifiés tant qu’à votre tour vous redistribuez vos
améliorations sous les même termes de licence.
2.23.6 Sécurisation
La sécurité de tout site Internet passe par l’utilisation du protocole ssl et vous devez donc acheter un certificat
X509 auprès d’une autorité reconnue par les navigateurs internet ou en générer un autosigné.
2.23. Génération de documents à partir de modèles
21
Plone pour les intégrateurs, Version 1.0.0
2.23.7 Statistiques
Les rapports sur la fréquentation sont donnés par des outils libres complémentaires tels que piwik, ou fournissant
les même services que Google Analytics pour les sites web.
Piwik offre une solution très avancée pour réaliser l’analyse du trafic sur votre site Internet. Le module plone
collective.piwik.core
Ceci est rendu possible par l’utilisation d’un script javascript exécuté par le navigateur chaque fois qu’une page
du portail est affichée.
F IGURE 2.18 – Statistiques avec Piwik
La solution Google analytics est supportée grace au module collective.googleanalytics qui met à disposition une
intégration très avancée des événements suivant :
– téléchargement
– lien externe
– commentaire
– lien sur un email (contact)
De plus ce module est intégré automatiquement avec les modules suivants et donc votre analyse pourra bénéficier
des actions utilisateurs supplémentaires correspondant au module :
– collective.addthis (partage sur réseaux sociaux)
– Products.PloneFormGen (définition d’objectifs)
22
Chapitre 2. Présentation de Plone
CHAPITRE 3
Les nouveautés de Plone
3.1 Les nouveautés de Plone 4
Présentation des nouveautés de Plone 4 par rapport à Plone 3.3.
Vidéo disponible
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
Performances
Thème
Ergonomie
Amélioration de l’administration du site
Ordonnancement dans les dossiers amélioré
Interface améliorée de gestion des groupes
Tableaux de bord des groupes
Possibilité de masquer les portlets
Authentification par email
Amélioration de la customisation du site
Gestion des icones d’actions
Suppression du base_properties
Améliorations techniques
Utilisation de Python 2.6 et Zope 2.12
Gestion des pièces jointes avec les blobs
Refonte de l’outil de migration
JQuery Tools de base
Support de l’indexation des langues asiatiques
Les dossiers sont tous des BTree
Migration de Plone 3.3 vers Plone 4
3.1.1 Performances
Plone 4 est centrée sur l’amélioration des performances. Il est en environ deux fois plus rapide que Plone 3, et
jusqu’à quatre fois plus rapide que Plone 2.5 aussi bien pour les anonymes que pour les utilisateurs connectés. Il
consomme beaucoup moins de mémoire que les anciennes versions. Plone 4 est, à la date de sa sortie l’une des
plateformes open source CMS les plus rapides du marché.
Cela est dû à la fois à un effort majeur sur l’optimisation du code de Plone, qu’au passage à Python 2.6 plus rapide
et moins gourmand que Python 2.4.
En savoir plus (fr)
23
Plone pour les intégrateurs, Version 1.0.0
3.1.2 Thème
Plone 4 possède un nouveau thème par défaut appelé “Sunburst”, élégant et, minimaliste. Il est conçu comme un
composant à part, mais inclus par défaut. Il est donc facile à remplacer.
Il n’utilise plus de tableaux. La css a été très fortement simplifiée. Il reste compatible avec Internet Explorer 6.
Il est prévu pour être compatible avec le futur outil de mise en page Deco prévu pour Plone 5.
En savoir plus (en)
3.1.3 Ergonomie
L’interface utilisateur de Plone 4 a été améliorée.
Il est plus facile de créer un site Plone , via une page dédiée.
Plone 4 inclut par défaut un nouvel éditeur wysiwyg (TinyMCE), et offre de nouveaux paramètres de configuration.
TinyMCE remplace kupu. Il existe un produit en remplacement de l’éditeur complet FCKeditor : ckeditor.
En savoir plus (en)
Amélioration du formulaire de recherche : les options non pertinentes ont été retirées, les critères sont choisis par
un système de plié/déplié beaucoup plus clair.
En savoir plus (en)
3.1.4 Amélioration de l’administration du site
3.1.5 Ordonnancement dans les dossiers amélioré
L’interface pour ordonner les documents dans les dossiers a été améliorée. L’intégration entre ‘tri’ et ‘ordonnancement’ a été améliorée.
24
Chapitre 3. Les nouveautés de Plone
Plone pour les intégrateurs, Version 1.0.0
3.1.6 Interface améliorée de gestion des groupes
L’interface a été améliorée pour chercher des groupes, associer des utilisateurs à des groupes, etc.
Plone 4 permet de mieux gérer les groupes imbriqués. Dans Plone 3.3, vous ne voyiez pas que vous aviez un
rôle récupéré grâce un super groupe. Plone 4 a été modifié pour le voir, un peu comme la présentation faite dans
l’onglet partage pour les rôles locaux.
En savoir plus (en)
3.1.7 Tableaux de bord des groupes
Il est maintenant possible de paramétrer des tableaux de bord par défaut pour tous les utilisateurs d’un groupe.
En savoir plus (en)
3.1.8 Possibilité de masquer les portlets
Un simple clic dans l’outil de management des portlets permet de masquer/afficher un portlet.
3.1.9 Authentification par email
Plone 4 prévoit la possibilité d’autoriser l’authentification de l’utilisateur par son email plutôt que par son login.
3.1.10 Amélioration de la customisation du site
3.1.11 Gestion des icones d’actions
Les icones d’actions ne sont plus gérées séparément des actions (disparition du tool portal_actionicons)
3.1.12 Suppression du base_properties
Les css ne sont plus écrites en dtml, mais en texte pur. L’expérience d’utilisation a montré que l’utilisation de
variables dans les css posait plus de risques qu’elle ne faisait gagner de temps.
3.1.13 Améliorations techniques
3.1.14 Utilisation de Python 2.6 et Zope 2.12
Plone 2.5 et 3.x fonctionnaient sous Python 2.4. Python 2.6 est plus rapide et beaucoup moins gourmand en
mémoire.
Zope 2.12 est compatible avec la version 2.9.x de la ZODB supportant nativement les blobs. Totalement eggifié,
il est plus facile à déployer.
En savoir plus (en)
En savoir plus (en)
3.1. Les nouveautés de Plone 4
25
Plone pour les intégrateurs, Version 1.0.0
3.1.15 Gestion des pièces jointes avec les blobs
La ZODB gère maintenant les pièces jointes (images et fichiers) de Plone dans des fichiers à part de la Data.fs,
appelés “blobs”.
Cela limite l’impact des modifications de pièces jointes sur la taille des transactions : la zodb est plus rapide et
grossit moins rapidement entre chaque pack.
En savoir plus (en)
3.1.16 Refonte de l’outil de migration
Plone utilise maintenant Generic Setup comme outil de migration. On a maintenant le même système de mise à
jour pour les modules tierces et pour Plone lui-même.
En savoir plus (en)
3.1.17 JQuery Tools de base
La bibliothèque Javascript JQuery Tools est incluse de base. Cela permet d’avoir des popups améliorant l’expérience utilisateur.
En savoir plus (en)
3.1.18 Support de l’indexation des langues asiatiques
Le moteur d’indexation plain texte gère maintenant les langues asiatiques (Chinois, Japonais, Coréen).
En savoir plus (en)
3.1.19 Les dossiers sont tous des BTree
Il y avait auparavant deux types de dossiers : Folder et Large Folder, les seconds étant des BTree. Les Folder sont
maintenant des BTree et les Large Folder ont été retirés.
En savoir plus (en)
3.1.20 Migration de Plone 3.3 vers Plone 4
Plone 4 apporte quelques changements radicaux. Il vous faudra sans doute adapter le code de vos produits. Il existe
une documentation pour vous y aider.
3.2 Les nouveautés de Plone 3
Présentation des nouveautés de Plone 3 par rapport à Plone 2.5.
26
Chapitre 3. Les nouveautés de Plone
Plone pour les intégrateurs, Version 1.0.0
–
–
–
–
–
–
–
–
–
–
–
–
–
Édition en ligne
Validation des champs via AJAX
Support des copies de travail
Vérification de l’intégrité des liens
Verrouillage d’un document lors de l’édition
Nouvel onglet partage
Versionnement des documents
Visualiser un document en mode diaporama
Navigation Précédent/Suivant dans un dossier
Générer une table des matières pour un document
Indexage des documents Word et PDF
Mais aussi
Et pour le développeur
3.2.1 Édition en ligne
Description de la fonctionnalité “Inline editing”
Désactivé par défaut dans Plone 3.3. Pour l’activer, cochez “Activer l’édition en ligne” dans “Configuration du site
-> Site”
3.2.2 Validation des champs via AJAX
La validation d’un champ d’un formulaire se fait dès que vous le quittez.
3.2.3 Support des copies de travail
Working Copy support
Installez le produit “Support des copies de travail (Iterate)” via “Configuration du site -> Produits d’extension”.
Vous avez maintenant une nouvelle action “Créer un brouillon” accessible sur n’importe quel contenu.
3.2.4 Vérification de l’intégrité des liens
Link and reference integrity checking
Lors de la suppression d’une image, Plone regarde si des documents sont en train de l’utiliser pour éviter de casser
des liens.
3.2.5 Verrouillage d’un document lors de l’édition
Automatic locking and unlocking
Le document est verrouillé lorsque vous l’éditez. Cela permet d’éviter à un autre utilisateur d’éditer en même
temps et d’écraser votre travail.
Le verrouillage a été amélioré dans Plone 3.3. Le verrouillage n’est actif que 10 minutes, reconductible si l’utilisateur est toujours en train de l’éditer.
3.2. Les nouveautés de Plone 3
27
Plone pour les intégrateurs, Version 1.0.0
3.2.6 Nouvel onglet partage
Easy collaboration and sharing
L’onglet partage a été amélioré, plus simple d’utilisation. Chaque intitulé des colonnes correspond à un rôle.
– Peut Ajouter : Contributor
– Peut modifier : Editor
– Peut voir : Reader
– Peut Modérer : Reviewer
3.2.7 Versionnement des documents
Versioning, history and reverting content
Vous pouvez activer le versionnement d’un type de contenu à partir de “Configuration du site -> Types”.
Pour pouvoir visualiser les différences entre deux versions, il faut ajouter le type de contenu dans portal_diff.
3.2.8 Visualiser un document en mode diaporama
Presentation mode for content
Éditez le document et allez dans Paramètres pour cocher “Mode présentation”.
3.2.9 Navigation Précédent/Suivant dans un dossier
Automatic previous/next navigation
À partir d’un document d’un dossier, vous avez la possibilité d’ouvrir le document précédent ou le suivant.
Éditez le dossier et allez dans Paramètres pour cocher “Activer la navigation ‘précédent/suivant”’.
3.2.10 Générer une table des matières pour un document
Auto-generated tables of contents
Éditez le document et allez dans Paramètres pour cocher “Table des matières”.
3.2.11 Indexage des documents Word et PDF
Full-text indexing of Word and PDF documents
Plone indexe le texte des documents Word et PDF. Il est donc ensuite possible de rechercher un terme qui est dans
ces documents.
Cette fonctionnalité est active si vous avez les packages Ubuntu wv (pour les documents Word) et poppler-utils
(pour la commande pdftotext) d’installés. Voir howto
D’autres formats peuvent être indexés avec le produit ARFilePreview, qui nécessite AROfficeTransforms ou le
nouveau plone.transforms.
– ARFilePreview-v2 branch (2.3.0) fonctionne avec AROfficeTransforms (utilise portal_transforms).
– ARFilePreview trunk v3 fonctionne avec plone.transforms (architecture Zope 3).
28
Chapitre 3. Les nouveautés de Plone
Plone pour les intégrateurs, Version 1.0.0
3.2.12 Mais aussi
–
–
–
–
–
–
–
–
–
Éditeur HTML visuel (WYSIWYG) amélioré
Puissantes fonctionnalités de workflow
Gestion flexible de l’authentification
Collections
Support du protocole de moteur de recherche Sitemap
Support de différents formats de balises
Support du wiki
Moteur de règles de contenu pour la gestion d’évènements
Moteur de portlets
En savoir plus : Features in Plone 3
3.2.13 Et pour le développeur
Technologies qui ont fait leur entrée dans Plone 2.5 et qui sont maintenant incontournables dans Plone 3 :
– profils GenericSetup pour importer/exporter une configuration de site, pour une meilleure industrialisation
– technologies Zope 3 (évènements, vues...), pour une meilleure maintenabilité du code
Technologies qui font leur apparition dans Plone 3 :
– gestion des éléments de page avec les nouvelles viewlets et portlets, pour une meilleure réutilisabilité des développements et une meilleure maintenabilité
3.2. Les nouveautés de Plone 3
29
Plone pour les intégrateurs, Version 1.0.0
30
Chapitre 3. Les nouveautés de Plone
CHAPITRE 4
Paramétrer votre site Plone
Author Thomas Desvenain
Created 2010-10-18
Version 0.1.0
Copyright (C) 2010 Thomas Desvenain <thomas.desvenain AT gmail.com>.
Chacun est autorisé à copier, distribuer et/ou modifier ce document suivant les termes de la licence
Paternité-Pas d’Utilisation Commerciale-Partage des Conditions Initiales à l’Identique 2.0 France accessible à
http ://creativecommons.org/licenses/by-nc-sa/2.0/fr
4.1 Objectif
Nous allons présenter ici les options de paramétrage offertes de base à l’administrateur d’un site Plone.
31
Plone pour les intégrateurs, Version 1.0.0
Contents
– Paramétrer votre site Plone
– Objectif
– Accéder au menu de configuration
– Configurer les paramètres de messagerie
– Paramètres du site
– Paramètres de base de la sécurité du site
– Auto-inscription
– Mot de passe choisi par l’utilisateur
– Activer les dossiers de l’utilisateur
– Affichage de la ligne d’information du document pour les anonymes
– Connexion par email
– Paramétrage du calendrier
– Ajouter un calendrier
– Compléter le calendrier
– Configurer le calendrier
– Paramétrage de la navigation
– Configuration des onglets
– Configuration de la navigation
– Configuration du portlet de navigation
– Conclusion
– Paramètres de la recherche
– Configurer le thème
– Paramétrage des modules
– Paramétrage des règles de contenu
– Paramétrer l’édition de contenus
– Edition de l’identifiant
– Éditeur de texte par défaut
– Éditeur externe
– Vérification de l’intégrité des liens
– Verrouillage des documents en modification
– Paramétrer le filtrage du contenu ajouté en HTML
– Filtrage des balises
– Balises indésirables
– Balises non-XHTML autorisées
– Filtrage des attributs
– Filtrage des styles et des classes
– Paramétrer le comportement wiki
– Activer le comportement wiki
– Se servir de Plone comme d’un Wiki
– Gestion des tailles d’images
– Maintenance du serveur et de la base
– Choix de la langue du Site
– Paramétrer les types de contenu
– Définir le workflow par défaut
– Définir le workflow de chaque type
– Ajout global
– Politique de versionnement
– Autoriser les commentaires
– Portlets spécifiques du type de contenu
– Gestion des utilisateurs et groupes
– Caching
– Discussion
– Registre de configuration
– Syndication
– Éditeur de texte riche TinyMCE
32
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.2 Accéder au menu de configuration
Vous devez être connecté avec un administrateur. Pour accéder au menu de configuration, cliquez sur votre nom
d’utilisateur, par défaut en haut à droite du site,
Vous arrivez sur le menu de configuration du site.
Cette page est composée de trois parties :
– la partie supérieure, Configuration générale, contient des liens vers les différents menus de configuration de
Plone,
– la partie centrale contient les liens vers les menus de configuration ajoutés par les modules complémentaires
que vous aurez installés,
– la partie inférieure contient les informations de version et de debug.
4.3 Configurer les paramètres de messagerie
Si vous arrivez sur cette page la première fois, un message vous alerte sur le fait que vous n’avez pas configuré le
serveur smtp. Nous allons commencer par remédier à cela.
Plusieurs fonctionnalités de Plone provoquent des envois de mail. Pour un bon fonctionnement de votre site, vous
devez configurer la messagerie.
Cliquez sur Envoi de courriels.
Vous arrivez sur la page des Paramètres d’envoi des courriels.
Entrez dans le champ ‘Serveur SMTP’ l’addresse de votre serveur d’envoi. Si vous êtes dans le réseau d’une
entreprise, contactez l’administrateur système pour connaitre ce nom. Si vous êtes à votre domicile, ce nom se
trouve dans le courrier d’ouverture de votre ligne envoyé par votre fournisseur d’accès internet (FAI). Il s’agit en
général de smtp.nomdufai.fr ou smtp.nomdufai.com.
Si vous utilisez Extended-SMTP, remplissez les champs login-mot de passe suivants. À défaut ou si vous n’êtes
pas sûr, ne les remplissez pas.
Les deux derniers champs, obligatoires, indiquent les informations de l’émetteur des mails envoyés par le site
(champ From).
Cliquez sur Enregistrer pour sauvegarder vos modifications.
4.4 Paramètres du site
La page Paramètres du site permet d’éditer les métadonnées du site, et des réglages de référencement (utiles
principalement si votre site est un site internet)
Notamment :
– le titre du site,
– sa description dans les résultats du moteur de recherche
Exposer les métadonnées Dublin Core : si cette option est activée, chaque page du site aura des metatags dont le
contenu correspondra aux métadonnées du document affiché.
Exposer sitemap.xml.gz : activé, les moteurs de recherche auront accès au sitemap, optimisant l’indexation (activez
l’option, puis allez sur sitemap.xml.gz depuis la racine de votre site).
4.2. Accéder au menu de configuration
33
Plone pour les intégrateurs, Version 1.0.0
34
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.5 Paramètres de base de la sécurité du site
La sécurité dans Plone est un vaste sujet, qui sera traité principalement dans d’autres chapitres sur les workflows,
les rôles et permissions, etc.
Un certain nombre d’options sont disponibles depuis le lien Sécurité de la configuration du site.
4.5.1 Auto-inscription
Si l’option est choisie, une option S’inscrire apparaît dans la zone de login pour les anonymes.
4.5.2 Mot de passe choisi par l’utilisateur
Si cette option est activée, lorsqu’un utilisateur est créé un mot de passe provisoire est envoyé au nouvel inscrit,
qui peut le modifier immédiatement.
4.5.3 Activer les dossiers de l’utilisateur
L’option ajoute un lien dossier personnel dans le menu de l’utilisateur.
Il s’agit d’un dossier qui est administré par l’utilisateur, dans lequel il peut ajouter des documents qu’il peut
soumettre à publication.
4.5.4 Affichage de la ligne d’information du document pour les anonymes
Par défaut, seuls les membres voient la ligne de métadonnées Par xxx — Dernière modification xxx sous le titre
des documents. Si cette option est activée, elle est visible par les anonymes.
4.5.5 Connexion par email
Permet aux utilisateurs de se connecter en utilisant leur email à la place de leur login.
4.5. Paramètres de base de la sécurité du site
35
Plone pour les intégrateurs, Version 1.0.0
36
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.5. Paramètres de base de la sécurité du site
37
Plone pour les intégrateurs, Version 1.0.0
38
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.6 Paramétrage du calendrier
Le calendrier de Plone affiche, dans un portlet, un petit calendrier dans lequel les dates comprenant des événements
apparaissent en surbrillance.
Nous allons d’abord ajouter un portlet calendrier sur notre site, en haut à gauche.
4.6.1 Ajouter un calendrier
Rendez-vous à la racine de votre site, en cliquant sur le logo. En bas à gauche de la page, cliquez sur Gérer les
portlets
Vous arrivez sur la page de gestion des portlets.
Cliquez sur Ajouter un portlet... sur la colonne de gauche, et sélectionnez le portlet calendrier.
Cliquez sur la flèche-haut devant Calendrier pour monter le calendrier au-dessus de la navigation.
Revenez sur l’accueil. Vous avez maintenant votre portlet calendrier.
Il est bien vide pour le moment...
4.6.2 Compléter le calendrier
Le calendrier contient des références à des contenus événement.
Allez dans le dossier Événements et ajoutez-en un.
Pour l’instant, rien n’a changé. Publiez-le. Il apparait dans le calendrier.
4.6. Paramétrage du calendrier
39
Plone pour les intégrateurs, Version 1.0.0
40
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.6. Paramétrage du calendrier
41
Plone pour les intégrateurs, Version 1.0.0
42
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.6. Paramétrage du calendrier
43
Plone pour les intégrateurs, Version 1.0.0
Créez un autre événement pour la veille du précédent, Préparation de la salle, et enregistrez-le, cette fois sans le
publier.
Vous voudriez peut-être que les événements ‘privés’ s’affichent pour leurs propriétaires et tous ceux qui y ont
accès. Il est possible de configurer cela.
4.6.3 Configurer le calendrier
Retournez dans la Configuration du site, puis cliquez sur Calendrier
Vous pouvez ici sélectionner les états dans lesquels vos événements apparaîtront dans le calendrier.
Sélectionnez Privé [private].
En France, la norme est plutôt de commencer la semaine par le lundi. Sélectionnez Lundi
Enregistrez.
Le document privé apparaît (ici le 18) et l’ordre des jours a changé.
44
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.7 Paramétrage de la navigation
La page Paramètres de navigation permet de configurer deux choses : les onglets généraux du site et le portlet de
navigation.
4.7.1 Configuration des onglets
Par défaut, la barre de navigation supérieure affiche un onglet pour chaque dossier ajouté à la racine.
La première option permet de désactiver ce comportement. (Dans ce cas, il faudra ajouter manuellement les actions
sur la barre d’onglet, ce qui est plus complexe et fera l’objet d’un autre chapitre)
Si la seconde option est activée, les documents de la racine seront également affichés comme onglets.
Si vous voulez masquer un dossier des onglets (par exemple : Membres), rendez-vous sur le dossier, cliquez sur
Modifier, puis Paramètres.
Cochez Exclure de la navigation et enregistrez.
Membres n’apparaît plus dans la barre de navigation supérieure.
4.7.2 Configuration de la navigation
Vous pouvez également choisir ici les types de contenus affichés dans le portlet de navigation. Il est fréquent de
choisir de n’afficher que les dossiers.
Vous pouvez également filtrer les contenus affichés dans l’arborescence par état documentaire (sachant que, de
toute façon, seuls les dossiers et documents qu’un utilisateur a le droit de voir apparaissent dans la navigation)
Le plan du site utilise également ces paramètres.
4.7.3 Configuration du portlet de navigation
Attention, ces paramètres ne recouvrent qu’une partie de la configuration du portlet de navigation. Pour la configurer, revenez à la racine et cliquez sur Gérer les portlets à gauche.
4.7. Paramétrage de la navigation
45
Plone pour les intégrateurs, Version 1.0.0
46
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.7. Paramétrage de la navigation
47
Plone pour les intégrateurs, Version 1.0.0
48
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
Cliquez maintenant sur le nom du portlet Navigation.
Vous arrivez sur un menu de configuration (assez complexe) où vous définissez essentiellement trois choses :
– le niveau d’affichage, qui est le nombre de niveaux à partir du niveau racine avant qu’on affiche les contenus
dans la navigation
– le niveau racine, qui est le niveau à partir duquel on compte le niveau d’affichage
– la profondeur d’affichage, qui est le nombre de niveaux maximal qu’on affiche sous le niveau racine...
Par défaut, le niveau d’affichage est 1 et le niveau racine est la racine du site : on ne voit donc que les documents
contenus dans les dossiers ajoutés à la racine... (les choses sont paramétrées par défaut de cette façon de sorte que
les dossiers à la racine n’apparaissent pas ET dans le portlet de navigation ET dans la barre d’onglets)
Imaginons que nous voulions afficher les dossiers à la racine. Entrez 0 pour niveau d’affichage et enregistrez.
4.7.4 Conclusion
Pourquoi deux pages pour configurer le portlet de navigation : dans les paramètres du site et dans les paramètres
du portlet ? En fait, vous pouvez tout à fait avoir plusieurs portlets de navigation sur votre site, configurées différemment. Mais toutes sont concernées par les paramètres définis au niveau de la configuration du site...
4.8 Paramètres de la recherche
La page Paramètres de la recherche permet :
– D’activer / désactiver la recherche instantanée,
– De sélectionner les types de contenu dans lesquels on fait nos recherches,
Et de décider finement d’activer ou pas certaines options de recherche de la recherche avancée :
– possibilité de chercher par état pour les anonymes,
4.8. Paramètres de la recherche
49
Plone pour les intégrateurs, Version 1.0.0
50
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.8. Paramètres de la recherche
51
Plone pour les intégrateurs, Version 1.0.0
52
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
–
–
–
–
possibilité de modifier l’ordre des résultats,
possibilité de modifier le nombre de résultats par page,
champs de recherche spécifiques Titre et Description,
réduction automatique des options rarement utilisées.
4.9 Configurer le thème
Cette page permet de configurer les paramètres d’apparence, notamment le thème sélectionné.
Amusez-vous à sélectionner le Plone Classic Theme
Il permet de s’assurer que Plone 4 est toujours compatible avec les thèmes conçus pour les anciennes versions...
Ceci étant dit, vous pouvez revenir sur le thème de Plone 4 (Sunburst) :)
Vous pouvez paramétrer les liens externes de sorte qu’ils soient marqués,
et qu’ils s’ouvrent dans un nouvel onglet.
Vous pouvez également supprimer les icônes de type de contenu dans les listes et les portlets.
Enfin, vous pouvez désactiver le système de popup en superposition (dit aussi lightbox) pour les formulaires
simples.
4.10 Paramétrage des modules
Pour l’activation et la désactivation de modules, référez-vous au chapitre Choix et ajout d’un module.
4.9. Configurer le thème
53
Plone pour les intégrateurs, Version 1.0.0
54
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.11 Paramétrage des règles de contenu
Pour les règles de contenu, référez-vous au chapitre Déclenchement d’événements avec les règles de contenu.
4.12 Paramétrer l’édition de contenus
La page des Paramètres d’édition permet de configurer le comportement général de l’édition de documents.
4.12.1 Edition de l’identifiant
Chaque contenu a un identifiant, qui est unique dans chaque dossier. Par défaut, l’identifiant est généré automatiquement à partir du titre proposé. Vu que l’identifiant est utilisé dans l’URL, de nombreux utilisateurs préfèrent le
saisir eux mêmes.
4.11. Paramétrage des règles de contenu
55
Plone pour les intégrateurs, Version 1.0.0
Avec cette option activée, les utilisateurs auront une nouvelle option dans leurs préférences personnelles :
Si elle est activée, l’utilisateur pourra saisir l’identifiant d’un document lorsqu’il le crée ou le modifie.
4.12.2 Éditeur de texte par défaut
Par défaut sur Plone, l’éditeur de texte est TinyMCE. Cependant il est possible d’installer d’autres éditeurs (ckeditor notamment).
Chaque utilisateur peut choisir son éditeur, mais par défaut, l’éditeur sera celui choisi sur cette page de configuration.
Si vous avez installé un nouvel éditeur sur votre site, ckeditor par exemple, il aura une page de configuration
spéciale, avec un lien ajouté dans la partie Configuration de module du menu de configuration.
4.12.3 Éditeur externe
Si cette option est activée, les utilisateurs auront la possibilité d’activer l’édition externe dans leurs préférences
personnelles.
L’édition externe permet, à condition d’avoir installé un soft sur son poste, de modifier des documents de Plone
en les éditant directement avec son logiciel préféré, sans avoir besoin de passer par un formulaire. Ce qui est
particulièrement utile pour les fichiers type tableur ou traitement de texte.
Veuillez vous référer au chapitre Zope External Editor pour de plus amples informations.
4.12.4 Vérification de l’intégrité des liens
Si cette option est activée, lorsque vous supprimez un document, Plone vérifie qu’aucun autre document ne
contient un lien vers ce document, et vous alerte le cas échéant.
56
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
Nous avons créé un document Mon document de référence et un document Mon document contenant des liens.
Dans ce dernier, nous avons ajouté un lien, dans le texte principal, avec le premier.
Quand nous supprimons Mon document de référence nous obtenons cette popup de confirmation :
4.12.5 Verrouillage des documents en modification
Quand le verrouillage est activé, si un utilisateur est sur le formulaire de modification d’un document, les autres
utilisateurs susceptibles de modifier le document sont avertis, et ils ne peuvent accéder au formulaire sans forcer
le déverrouillage.
4.12. Paramétrer l’édition de contenus
57
Plone pour les intégrateurs, Version 1.0.0
4.13 Paramétrer le filtrage du contenu ajouté en HTML
Les éditeurs WYSIWYG permettent aux contributeurs du site d’éditer le code html de pages qui seront ensuite
affichées par les navigateurs des visiteurs du site.
Il peut être dangereux ou gênant de permettre à vos utilisateurs de créer des formulaires, d’afficher des objets flash
ou autre, d’ajouter des balises meta, de trop paramétrer le style de son contenu, etc.
La page Paramètres du filtrage HTML permet à l’administrateur du site de contrôler les éléments html dont il
permet l’introduction par les contributeurs.
Dans l’autre sens, si vos utilisateurs s’étonnent que certains contenus qu’ils ajoutent ne sont pas enregistrés, c’est
ici que vous pouvez étendre les autorisations.
La première page permet de définir les balises qui sont filtrées.
4.13.1 Filtrage des balises
Par défaut, toutes les balises XHTML sont acceptées, les autres sont filtrées : l’élément est supprimé mais pas son
contenu.
Éditez un document du site avec un éditeur WYSIWYG, mais avec l’option HTML (éditer le code source). Entrez
le contenu
<toto>Ceci est du texte dans une balise non-html</toto>
Enregistrez le document. Éditez-le à nouveau. Le texte ci-dessus a été remplacé par du XHTML valide, par
exemple avec TinyMCE
<p>Ceci est du texte dans une balise non-html</p>
4.13.2 Balises indésirables
Ajoutez maintenant ce code
<script language="Javascript">while(0!=1) alert(’toto’);</script>
Enregistrez. Heureusement, ce script ne s’applique pas ! Rééditez votre page sur l’édition, et cliquez sur ‘HTML’.
Vous verrez que votre code a été remplacé par
<!-- while(0!=1) alert(’toto’); // -->
Les balises indésirables sont commentées. Là donc, même le contenu n’apparaît pas.
4.13.3 Balises non-XHTML autorisées
Le troisième bloc de la page permet d’autoriser dans le html des balises qui ne sont pas XHTML. On y trouve
notamment les balises HTML5.
58
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.13. Paramétrer le filtrage du contenu ajouté en HTML
59
Plone pour les intégrateurs, Version 1.0.0
60
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.13.4 Filtrage des attributs
La deuxième page permet de filtrer les attributs.
Le premier bloc indique la liste des attributs qui seront simplement supprimés à l’enregistrement.
Le second bloc indique les attributs qui seront supprimés s’ils sont dans telle ou telle balise en particulier. Par
exemple, ici on retire les attributs width et height des tables et des cellules.
4.13.5 Filtrage des styles et des classes
Si l’attribut style est autorisé, vous ne voulez pas forcément que vos utilisateurs puissent attribuer n’importe quelle
valeur css.
De même, vous craignez peut-être que vos utilisateurs utilisent certaines classes css.
Vous pouvez maitriser la liste des attributs css disponibles dans les attributs ‘styles’, ainsi que les noms de classes
interdits dans toute balise ‘class’.
Editez votre document, et entrez ce code
<p style="font-size: 250px; text-align: right">Mon texte stylé</p>
Vous observez que seul le text-align s’applique. Éditez à nouveau le contenu, vous verrez que ce code est conservé
<p style="text-align: right; ">Mon texte stylé</p>
4.13. Paramétrer le filtrage du contenu ajouté en HTML
61
Plone pour les intégrateurs, Version 1.0.0
4.14 Paramétrer le comportement wiki
4.14.1 Activer le comportement wiki
Plone permet d’avoir un comportement wiki, afin d’optimiser la création de contenus liés.
Par défaut, cela n’est pas activé. Allez dans Paramètres du formatage de texte.
Puis allez sur l’onglet Comportement wiki.
Nous allons l’activer pour les documents. Cochez Documents et enregistrez.
4.14.2 Se servir de Plone comme d’un Wiki
Créez maintenant un document sur votre site. Mettez entre double-parenthèses (( )) ou entre double-crochets [[ ]]
les documents que vous voulez pouvoir lier par la suite.
Un clic sur un lien ‘+’ crée un nouveau contenu ayant pour titre le texte lié.
Le lien + se transforme en lien vers le nouveau contenu.
L’identifiant (ici : CMS) peut être utilisé à plusieurs endroits (y compris sur plusieurs pages différentes), il crée
automatiquement un lien vers cette nouvelle page.
4.15 Gestion des tailles d’images
Quand vous ajoutez une image dans un document, vous choisissez parmi un certain nombre de tailles d’images.
Ces tailles disponibles sont éditables dans la configuration du site, dans Paramètres de la gestion des images.
4.16 Maintenance du serveur et de la base
Les opérations de maintenance sont disponibles depuis la page Maintenance du menu de configuration.
Vous pouvez, de cette page, arrêter ou redémarrer le site, et ‘packer’ la base de données.
62
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.16. Maintenance du serveur et de la base
63
Plone pour les intégrateurs, Version 1.0.0
La base de données (ZODB) doit être packée régulièrement. Elle stocke toutes les transactions effectuées, ce qui
est utile notamment pour la fonction Undo, mais ralentit progressivement les performances en lecture / écriture.
Il est nécessaire de purger ces informations, en conservant celles des derniers jours.
Un chapitre sur la ZODB est à venir dans la documentation développeur.
4.17 Choix de la langue du Site
La page Paramètres linguistiques permet de choisir la langue du site. Elle est définie par défaut comme la langue
du navigateur de l’utilisateur qui a créé le site.
Les options de langue pour les sites multilingues ne se configurent pas ici. Nous fournirons une documentation
spécifique pour les sites en plusieurs langues.
4.18 Paramétrer les types de contenu
4.18.1 Définir le workflow par défaut
Première page : workflow par défaut.
Changer le workflow :
Enregistrer :
4.18.2 Définir le workflow de chaque type
Sélectionner un type. On peut choisir son workflow spécifique.
64
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.18. Paramétrer les types de contenu
65
Plone pour les intégrateurs, Version 1.0.0
66
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.18. Paramétrer les types de contenu
67
Plone pour les intégrateurs, Version 1.0.0
68
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.18.3 Ajout global
Si cette option est activée pour un type, un document de ce type peut être ajouté dans n’importe quel dossier qui
ne comporte pas de restriction sur son contenu.
4.18.4 Politique de versionnement
Activer le versionnement manuel pour les fichiers.
Modifier ensuite un fichier.
Cocher la case nouvelle version.
4.18.5 Autoriser les commentaires
Si cette option est activée, le type de contenu est ouvert au système de commentaires.
Activez les commentaires pour le type Fichier. Allez sur un contenu fichier, vous voyez maintenant une section
Commentaires avec un bouton Ajouter un commentaire.
Si vous cliquez sur Ajouter un commentaire, une popup s’ouvre vous permettant de saisir votre texte.
Enregistrez-le, il apparaît au bas du document. Il est possible de le supprimer, ou d’y répondre.
4.18.6 Portlets spécifiques du type de contenu
Vous pouvez paramétrer des portlets qui s’afficheront suivant le type de contenu de la page affichée.
Sélectionnez un type de contenu (ici Fichier) sur l’écran de configuration des types. Vous avez un lien Gérer les
portlets affectés à ce type de contenu.
Cliquez ce lien, vous arrivez sur une page similaire à la page Gérer les portlets vue plus haut.
Ajoutez un portlet, en naviguant sur le site, vous verrez que lorsque vous allez sur une page Fichier, ce portlet
apparaît.
4.19 Gestion des utilisateurs et groupes
Cette page permet de gérer les utilisateurs et groupes.
4.19. Gestion des utilisateurs et groupes
69
Plone pour les intégrateurs, Version 1.0.0
70
Chapitre 4. Paramétrer votre site Plone
Plone pour les intégrateurs, Version 1.0.0
4.19. Gestion des utilisateurs et groupes
71
Plone pour les intégrateurs, Version 1.0.0
4.20 Caching
Pour gérer les règles de cache.
4.21 Discussion
Pour gérer les options liées aux commentaires.
4.22 Registre de configuration
Pour configurer certaines options qui n’ont pas d’interface dédiée.
4.23 Syndication
Pour gérer les options liées aux flux RSS.
4.24 Éditeur de texte riche TinyMCE
Pour gérer les options de TinyMCE.
72
Chapitre 4. Paramétrer votre site Plone
CHAPITRE 5
Choix et ajout d’un module
Author Michael Launay
Version 0.1.0
Copyright (C) 2010 Michael Launay <michaellaunay AT ecreall.com>.
Chacun est autorisé à copier, distribuer et/ou modifier ce document suivant les termes de la licence
Paternité-Pas d’Utilisation Commerciale-Partage des Conditions Initiales à l’Identique 2.0 France accessible à
http ://creativecommons.org/licenses/by-nc-sa/2.0/fr
5.1 Introduction
Plone est un Content Management System, c’est à dire un portail collaboratif qui permet de gérer des contenus
tels que des documents, des images, des événements, des vidéos, etc.
Il permet de créer et de gérer les cycles de publications des contenus, ainsi on peut affecter des rôles aux membres
leur permettant ou non de créer, modifier, voir, ou changer les règles des contenus.
Plone permet facilement la création de nouveaux types de contenu, de nouvelles règles de gestion, de nouveaux
rôles ou groupes.
Cette finesse de la gestion des droits associée au fait que Plone est un logiciel libre a permis la création de
nombreuses extensions permettant soit de spécialiser Plone soit de l’étendre.
Ces extensions ont d’abord été appelées “produits” mais à partir de la version 4 de Plone nous parlons de “modules”.
La première étape consiste à identifier son besoin.
Ensuite, il faut vérifier que Plone ne propose pas déjà les fonctionnalités désirées.
Pour cela, nous pouvons commencer par voir si Plone fournit de base un type de contenu spécifique de ce besoin.
S’il existe un contenu, il faut alors vérifier que le workflow, qui lui est associé, correspond à notre besoin et si
nécessaire en développer un autre.
S’il n’existe pas de contenu correspondant à notre besoin et que celui-ci est générique, alors il existe surement un
module couvrant partiellement ou complètement notre besoin.
On va donc chercher et sélectionner un module.
5.2 Rechercher et sélectionner un module
Le site plone.org contient la vitrine des modules Plone disponibles.
73
Plone pour les intégrateurs, Version 1.0.0
http ://plone.org/products
Depuis la version 4 de Plone le site de la communauté Plone possède un nouveau classement des modules qui
permet entre autres de les chercher par popularité.
Un article sur cette nouvelle interface a été écrit sur le site de la communauté française
http ://plone.fr/news/nouveautes-plone-products
Les modules suivent un cycle de vie de développement, les plus utilisés sont maintenus et sont adaptés aux nouvelles versions de Plone rapidement.
Avant d’utiliser un module, il faut se poser les questions suivantes :
– Ce module est-il compatible avec notre version de Plone ?
– Depuis combien de temps existe le module ?
– Est-il encore utilisé ?
– Est-il maintenu ?
– Y a-t-il eu des remontées de bogues et est-ce possible ?
– Si oui y a-t-il eu des corrections apportées et au bout de combien de temps ?
– La société ou les développeurs derrière ce module, sont-ils actifs dans la communauté ?
– A-t-on accès au code source du module ?
– Le code est-il sur le dépôt de la communauté Python ou Plone ?
– Le module respecte-t-il les standards de programmation de la communauté ?
– Est-il documenté ?
– Modifie-t-il Plone ?
Suivez ensuite la méthode d’installation indiquée sur la documentation du produit. À défaut d’être précisée, c’est
toujours la même, nous la présentons plus loin.
5.3 Installer un module
Les modules Plone proposés sur plone.org sont hébergés sur des dépôts.
– Le dépôt des programmes open source de Python, appelé “pypi” et accessible sur le lien
http ://pypi.python.org/pypi
– Les dépôts des projets et sociétés dont les adresses peuvent être trouvées sur internet.
Le dépôt Pypi est celui de la communauté Python qui est le langage de programmation de Plone. Pour y trouver
un module spécifique de Plone il faut faire une recherche en utilisant le mot-clé Plone et les mots que vous pensez
être associés à votre besoin.
Pypi affichera les “egg” liées à Plone, en effet depuis les versions 3 de Plone les modules sont fournis sous forme de
paquets appelés “egg” dont on détaillera l’anatomie et comment les ajouter à Plone plus loin. Plone est désormais
entièrement constitué de eggs qui forment autant de bibliothèques.
Les modules hébergés exclusivement par les sites de leurs développeurs sont plus durs à identifier et leur capital
confiance est moins bon.
Pour installer un module, il suffit en général d’ajouter le nom du module à la valeur eggs dans le fichier de
configuration (buildout.cfg), et de relancer l’installation du site. (Pour plus d’information sur l’installation de
Plone, consultez la documentation intégrateur).
Il vous faut ensuite aller dans la configuration du site,
section Modules,
puis activer le module.
74
Chapitre 5. Choix et ajout d’un module
Plone pour les intégrateurs, Version 1.0.0
5.3. Installer un module
75
Plone pour les intégrateurs, Version 1.0.0
De nombreux exemples d’installation de modules seront présentés dans cette documentation.
5.4 Tester le module
Ensuite il faut absolument essayer le module sur une copie du site de production pour vérifier qu’il correspond à
notre besoin et surtout qu’il ne casse pas nos autres modules et respecte l’intégrité de notre site.
Il faut alors dérouler des tests de validation du portail pour vérifier l’intégrité du portail.
Puis il faut tester le fonctionnement du module pour vérifier son adéquation avec le besoin.
Si le besoin n’est pas complètement satisfait il faut alors chercher un module plus complet ou compléter le développement du module sélectionné.
Le fait de compléter un module déjà existant par rapport à en créer un ex nihilo est à préférer, surtout si les
évolutions que l’on souhaite apporter sont dans la logique du module.
Cette attitude vertueuse permet :
– de réduire les coûts en ne recréant pas ce qui existe déjà,
– de bénéficier d’une communauté d’utilisateurs et de développeurs,
– d’améliorer la couverture fonctionnelle d’un module ce qui du coup augmente ses chances d’être réutilisé et
donc maintenu.
76
Chapitre 5. Choix et ajout d’un module
CHAPITRE 6
Le protocole HTTP et ses tests
– Définition
– Savoir
– Les versions de HTTP et leur RFC
– L’envoi de requêtes
– Les méthodes (HEAD, GET, POST, DELETE, PUT, CONNECT, OPTIONS, TRACE)
– GET
– HEAD
– POST
– OPTIONS
– CONNECT
– TRACE
– PUT
– DELETE
– L’entête et ses champs (Host, Referer, User-Agent, etc.)
– Host
– Referer
– User-Agent
– Connection
– Accept
– Accept-Charset
– Accept-Language
– La réponse et ses champs
– Date
– Server
– Content-Length
– Content-Type
– Expires
– Last-Modified
– Les cookies
– HTTPS
– Mesures de charges
– Exercice
– Ressources
6.1 Définition
Connaître le protocole HTTP permet d’anticiper certaines limitations de déploiement.
77
Plone pour les intégrateurs, Version 1.0.0
Le protocole HyperText Transfert Protocol est un ensemble de règles qui régit la demande et l’envoi de pages web
entre un client et un serveur.
Le protocole HTTP délègue au protocole TCP (Transmission Control Protocole) l’envoi physique des données.
Les clients sont généralement des navigateurs web qui se connectent via internet à des serveurs Web qui leur
retournent les pages demandées.
Toutefois il existe des applications qui utilisent ce protocole pour communiquer entre elles.
Nous rappelons ce qui se passe généralement lorsqu’un utilisateur demande à son navigateur une page web :
1. L’utilisateur saisit le nom d’un site ou d’une page (adresse URL) dans la barre d’adresse de son navigateur
par exemple http ://www.ecreall.com/societe ;
2. Le navigateur découpe le nom saisi pour extraire le protocole à utiliser, ici http car le préfixe est “http ://”,
et le nom du serveur, ici www.ecreall.com ;
3. Le navigateur réalise alors un résolution de nom en se connectant à un serveur de nom qui lui permettra de
transformer le nom en adresse IP, www.ecreall.com donnera 88.191.227.112 ;
4. Il se connectera alors au serveur via le protocole TCP/IP en se connectant au port 80 qui est celui du protocole http par défaut (il est possible de donner un autre numéro de port par exemple
http ://www.ecreall.com :8080/) ;
5. Si la connexion réussit, le navigateur suivra les règles du protocole http pour demander la page “societe” en
envoyant les requêtes appropriées au serveur ;
6. Le serveur retournera alors cette page au format HTML ou XHTML en utilisant à son tour le protocole
HTTP et fermera la connexion ;
7. Une fois la page reçue, le navigateur analysera son contenu et appliquera les règles html ou xhtml pour
réaliser la mise en forme et afficher le résultat.
6.2 Savoir
6.2.1 Les versions de HTTP et leur RFC
Le protocole HTTP inventé par Tim Berners-Lee en 1989 devient un standard en 1996 et se répand sur internet en
version HTTP/1.0.
Le protocole est décrit par la Request For Comment RFC 1945.
Cette version permet de gérer plusieurs serveurs web sur une même machine et donc de servir un contenu différent
en fonction de la racine de l’URL.
En 1997 sort la version HTTP/1.1 modifiée en 1999 et décrite par la RFC 2616, qui ajoute le support du pipeline
(envoi de plusieurs requêtes puis réception de toutes les réponses) et la négociation de type de contenu.
6.2.2 L’envoi de requêtes
Le client se connecte au serveur et lui transmet ses attentes (que l’on appelle méthodes), le serveur lui répond et
se déconnecte. Cet échange s’appelle une requête.
Avant d’arriver au serveur, la requête peut passer par plusieurs intermédiaires qui peuvent la modifier ou y répondre
s’ils connaissent déjà la réponse (mécanisme de la mise en cache).
L’un des grands avantages du protocole http est qu’il s’agit d’un protocole texte. Ainsi un humain peut à l’aide du
programme “telnet” dialoguer avec un serveur en entrant directement le nom des commandes et leurs paramètres.
78
Chapitre 6. Le protocole HTTP et ses tests
Plone pour les intégrateurs, Version 1.0.0
6.2.3 Les méthodes (HEAD, GET, POST, DELETE, PUT, CONNECT, OPTIONS,
TRACE)
GET
Cette méthode permet de demander une ressource telle qu’une page, une image, etc. Elle ne modifie pas la ressource, en conséquence si la ressource n’a pas été modifiée, le résultat de la requête est toujours le même.
HEAD
Cette méthode permet d’obtenir des informations sur une ressource.
POST
Cette méthode permet d’envoyer le résultat d’un formulaire ou de transmettre un fichier vers le serveur. Les
informations à envoyer se trouvent dans les données de la requête et non pas dans l’URL.
OPTIONS
Cette méthode permet d’obtenir les options de communication d’une ressource ou du serveur en général.
CONNECT
Cette méthode permet de demander aux intermédiaires de ne pas changer le contenu des requêtes et de les passer
au serveur.
TRACE
Cette méthode demande au serveur de retourner ce qu’il a reçu, ceci pour permettre de diagnostiquer la connexion.
PUT
Cette méthode remplace ou ajoute une ressource sur le serveur si l’on en a les droits.
DELETE
Cette méthode supprime une ressource du serveur si l’on est autorisé à le faire.
6.2.4 L’entête et ses champs (Host, Referer, User-Agent, etc.)
Une requête HTTP 1.0 présente le format suivant :
Ligne de commande (Commande, URL, Version de protocole)
En-tête de requête
[Ligne vide]
Corps de requête
Les réponses HTTP 1.0 présentent le format suivant :
Ligne de statut (Version, Code-réponse, Texte-réponse)
En-tête de réponse
[Ligne vide]
Corps de réponse
6.2. Savoir
79
Plone pour les intégrateurs, Version 1.0.0
Exemple de requête :
GET / HTTP/1.0
Host: www.ecreall.com
User-Agent: Telnet
Nous allons voir ici les principaux champs.
Host
Il permet d’indiquer au serveur le site que l’on souhaite interroger et permet donc le virtualhosting.
Il est obligatoire pour le protocole 1.1.
Referer
Donne l’URI sur laquelle on a trouvé et cliqué le lien menant à la page demandée. Ce champ est utilisé pour les
statistiques.
User-Agent
Donne le nom du programme utilisé pour se connecter au serveur.
Le protocole HTTP/1.1 ajoute les champs suivants :
Connection
Ce champ permet au navigateur ou au serveur de préciser des options de connexion souhaitées ou appliquées.
Le champ Connection ne contient que la liste des options.
La valeur d’une option est alors précisée dans l’entête comme s’il s’agissait d’un champ, toutefois le nom du
champ est le même que celui mis dans Connection.
Accept
Indique les types MIME gérés par le client. L’astérisque est un joker.
Accept-Charset
Donne les encodages de caractères supportés.
Accept-Language
Spécifie les langages acceptés.
6.2.5 La réponse et ses champs
Réponse :
80
Chapitre 6. Le protocole HTTP et ses tests
Plone pour les intégrateurs, Version 1.0.0
HTTP/1.1 200 OK
Date: Fri, 19 Feb 2010 13:22:42 GMT
Server: Zope/(Zope 2.10.6-final, python 2.4.5, linux2) ZServer/1.1 Plone/3.1.7
Content-Length: 16051
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Content-Type: text/html;charset=utf-8
Content-Language: fr
Via: 1.0 www.ecreall.com
Connection: close
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
...
La première ligne est le statut de la réponse :
– 2xx (ici 200), pas de problème.
– 3xx la ressource a été déplacée.
– 4xx la ressource n’existe pas.
– 5xx il y a un problème.
Date
Date de création de la réponse.
Server
Annonce le logiciel et la version ayant crée la réponse.
Content-Length
La taille de la ressource en octets.
Content-Type
Type MIME de la ressource.
Expires
Date de “péremption” de la réponse. Au-delà de cette date la page devra être rechargée ce qui permet au navigateur
ou au cache de savoir quand transmettre les requêtes.
Last-Modified
Date de dernière modification de la ressource.
Autres entêtes HTTP
Ce qui précède est un aperçu des entêtes HTTP les plus courantes. D’autres entêtes peuvent également être échangées entre un navigateur et un serveur, notamment pour la gestion du cache. Pour plus de détails sur la négociation
de cache, lire (en anglais) http ://www.mnot.net/cache_docs/
6.2. Savoir
81
Plone pour les intégrateurs, Version 1.0.0
6.2.6 Les cookies
Le cookie est un ensemble de données transmises dans l’entête des requêtes http par un serveur (Set-Cookie :
name=value) à un client qui les stockes sur son disque s’il est persistant et le retransmet à chaque requête au
serveur (Cookie : name=value).
Il sert soit à l’authentification, soit à la gestion de la session, soit à l’enregistrement des préférences du client etc.
6.2.7 HTTPS
HTTPS est l’encapsulation du protocole http dans une couche de chiffrement telle SSL ou TLS.
Le serveur doit posséder un certificat X509 qui permettra d’une part de vérifier l’authenticité du serveur, et d’autre
part d’échanger confidentiellement avec le client une clé permettant de chiffrer symétriquement la suite de la
communication. En effet, l’une des particularités de ssl est que le serveur possède une clé publique qui sera
envoyée en clair au client, et une clé privée qui permettra de déchiffrer les informations chiffrées avec la clé
publique. Ce chiffrement est dit asymétrique et est complexe et lent à mettre en œuvre mais il présente l’immense
avantage que le client n’a pas à partager de secret avec le serveur avant de se connecter et peut ainsi se connecter
avec des serveurs qu’il ne connait pas.
Le certificat X509 du serveur doit être signé par une autorité connue du client pour que le navigateur fasse
confiance au serveur. Le mécanisme mis en œuvre pour cette signature repose également sur le mécanisme de
chiffrement asymétrique, le client possède une liste d’autorités connues avec leurs clés publiques respectives ce
qui permettra de vérifier qu’un certificat X509 est intègre et a bien été signé par l’autorité indiquée dedans.
De plus le chiffrement symétrique de la communication est associé à une fonction de hachage qui permet d’assurer
l’intégrité des données transmises.
Le port utilisé par HTTPS est par défaut le 443.
6.2.8 Mesures de charges
Pour mesurer la vitesse de réponse de notre serveur, ainsi que sa capacité à supporter plusieurs requêtes simultanées nous allons utiliser deux outils : Firebug et ab.
“firebug” est un plugin de Firefox qui permet d’analyser les pages web et d’en connaître les détails. Son onglet
Réseau permet de voir les ressources chargées, leur temps de chargement, leur taille. L’onglet Réseau/HTML
permet de voir les entêtes des requêtes.
ab est un outil fournit avec Apache qui permet de lancer des requêtes en parallèles afin de contrôler la capacité du
serveur à gérer celle-ci.
Exemple :
$ ab http://www.ecreall.com
$ ab -n 20 -c 4 http://www.ecreall.com/ \
# qui envoie 20 requêtes répartie en 4 threads
Lorsqu’on rencontre des problèmes réseaux difficiles à identifier, il peut être utile d’utiliser tcpdump -i eth0 -w
/tmp/nomdufichier sur le serveur, afin d’enregistrer tous les paquets circulant sur l’interface eth0 dans le fichier
/tmp/nomdufichier. On peut alors utiliser ‘wireshark’ pour inspecter les trames enregistrées dans le fichier.
6.3 Exercice
Utilisation de telnet pour accéder au serveur. Test de performance du serveur (la commande “ab” d’Apache).
82
Chapitre 6. Le protocole HTTP et ses tests
Plone pour les intégrateurs, Version 1.0.0
6.4 Ressources
–
–
–
–
–
Le protocole HTTP
Les cookies
Les certificats électroniques
Autorité de certification
Le modèle OSI
6.4. Ressources
83
Plone pour les intégrateurs, Version 1.0.0
84
Chapitre 6. Le protocole HTTP et ses tests
CHAPITRE 7
Rappel HTML et XML
– Définition
– Comment sont composées les pages internet ?
– Rappel sur les bases HTML et XML
– Savoir
– Les nœuds
– Les éléments
– Les attributs
– Le texte
– Distinction entre HTML et XML
– Le prologue
– Le doctype
– Les DTD et schémas
– Les documents bien formés
– Les documents validés
– Les commentaires
– Les espaces de noms
– Exercices
– Ressources
7.1 Définition
7.1.1 Comment sont composées les pages internet ?
Les pages internet sont de simples documents texte dont certains mots sont interprétés par le navigateur pour
insérer des images, mettre en forme le document comme par exemple créer des titres, proposer des liens, exécuter
des scripts qui sont des suites d’instructions indiquant au navigateur ce qu’il doit faire, etc.
Lorsque on utilise un logiciel produisant du HTML, il ne fait qu’écrire un fichier texte mélangeant notre contenu
avec les éléments du HTML.
7.1.2 Rappel sur les bases HTML et XML
Lorsqu’en 1989 Tim Berners-Lee créait le protocole HTTP, il créait aussi HTML (Hypertext Markup Language)
qui est le format de données transmis par HTTP, il met aussi au point le mécanisme d’URL qui permet de localiser
une ressource sur le web.
Le format HTML est un format texte issu de SGML, dont la volonté est de séparer le fond de la forme.
85
Plone pour les intégrateurs, Version 1.0.0
Il permet de mettre en évidence les parties importantes d’un texte en les balisant. Pour cela, on encadre
le texte avec un élément HTML qui se présente sous la forme <element attribut1="valeur1"
attribut2="valeur2">texte</element>.
Les différentes versions de HTML spécifient les noms des éléments et des attributs possibles.
HTML évolue continuellement, nous sommes à la version 4.1 et la version 5 est à l’étude.
Dès ses origines le langage de balise évolue par l’ajout des différents éditeurs de navigateur web.
Jusqu’en 1992, il n’existe aucune spécification du langage, et par convention on parle de HTML 1.0 pour désigner
ce qui se faisait à l’époque. En 1993, Mosaic apporte les formulaires rendant ainsi le web interactif ainsi que
l’affichage des images.
En 1995 sort la version 2.0 de HTML, proposée par le W3C World Wide Web Consortium qui vient d’être créé.
En 1997 sort la version 3 puis la version 4.0 qui décrit le mécanisme des feuilles de styles CSS (Cascading Style
Sheets). La version 4 est devenue la version la plus utilisée sur le web, les dernières corrections datent de 1999
avec la version 4.1.
XML a fait son apparition en 1998 avec la version 1.0, afin de rendre plus cohérent l’usage des éléments, il
demande que chaque balise ouverte soit fermée, que les attributs aient toujours une valeur entre guillemets. En
2004 sort la version 1.1.
La version 2.0 de XHTML qui devait apporter XForms et XFrames a finalement été abandonnée en décembre
2009. Et HTML 5 a du coup été relancé.
La grande force de XML est la possibilité d’enrichir facilement l’ensemble des balises existantes sans avoir à
modifier les recommandations du w3c, contrairement à HTML.
7.2 Savoir
Nous traiterons en priorité XHTML car c’est le format utilisé par Plone.
7.2.1 Les nœuds
On peut représenter un texte XML ou HTML par une arborescence de nœuds contenant du texte et/ou d’autres
nœuds, cela reviendrait à dire qu’un nœud est l’équivalent d’un répertoire ou d’un fichier en faisant le parallèle
avec une arborescence de fichiers.
7.2.2 Les éléments
Chaque nœud ayant un nom est appelée un élément, il est composé d’une balise ouvrante commençant par un
chevron ouvert < puis d’un nom ne contenant que des lettres, des chiffres ou des tirets bas, de zéro à plusieurs
attributs séparés par des espaces, enfin la balise finie par un chevron fermé >.
Exemple :
<un_element>
bla bla
<un_sous_element />
<un_autre_sous_element>
encore du bla bla
</un_autre_sous_element>
<un_element_avec_un_attribut un_attribut="sa valeur"/>
</un_element>
Un élément doit obligatoirement être fermé soit par une balise portant le même nom mais précédé par / et ne
pouvant contenir aucun attribut, soit par / avant le chevron de fermeture.
86
Chapitre 7. Rappel HTML et XML
Plone pour les intégrateurs, Version 1.0.0
7.2.3 Les attributs
Un attribut est un couple nom-valeur écrit à l’intérieur de la déclaration d’une balise, qui permet de préciser
l’élément qu’il qualifie.
En XML la valeur est entre guillemets et peut être vide “” mais ne peux être nulle.
7.2.4 Le texte
Le texte dans XHTML est contenu par un élément et est en unicode par défaut, le jeu de caractère est celui de
l’UTF-8 ce qui permet de traiter toutes les langues.
7.2.5 Distinction entre HTML et XML
HTML peut être vu comme un XML permissif car il autorise que les balises ne soient pas fermées, qu’une balise
ouvrante soit fermée par une balise dont la casse du nom soit différente de celle ouvrante, que les éléments de
style soient fortement mélangés au contenu.
XHTML doit respecter la forme suivante :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-s
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<title>Exemple XHTML 1.0 strict</title>
</head>
<body>
<ul>
<li>Tous les éléments doivent être explicitement balisés.</li>
<li>Les balises fermantes ne sont pas optionnelles.</li>
<li>Les noms d’éléments et d’attributs <em class="important">doivent</em> être en minuscules.</
<li>Tous les attributs doivent avoir une valeur explicite <input type="checkbox" checked="check
<li>Les guillemets sont <em class="important">toujours</em> obligatoires autour des valeurs d’a
<li>Les balises auto-fermantes se terminent tous par un espace et un slash comme pour la balise
ou un retour à la ligne : <br /></li>
</ul>
</body>
</html>
7.2.6 Le prologue
Le prologue est la première ligne d’un document HTML ou XHTML et a la forme <?xml version="1.0"?>.
Il permet de savoir si l’on a affaire à un document XML et si c’est le cas, de connaître la version applicable.
7.2.7 Le doctype
Le doctype est généralement défini tout de suite après le prologue et permet de savoir quelle DTD les éléments
non qualifiés doivent suivre.
Cas du HTML :
<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
Cas du XTHML 1.0 strict :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
Cas du XHTML 1.0 Transitional :
7.2. Savoir
87
Plone pour les intégrateurs, Version 1.0.0
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Cas du XHTML 1.1 :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
7.2.8 Les DTD et schémas
Que ce soit HTML ou XHTML, chacun des deux langages est défini par une DTD (Document Type Définition)
qui est une sorte de grammaire expliquant les combinaisons d’éléments et d’attributs possibles.
XML permet d’utiliser des schémas à la place des DTD, qui ont l’avantage d’être en XML et de mieux détailler
les éléments et attributs. Il y a ainsi moins d’interprétations possibles des spécifications.
7.2.9 Les documents bien formés
On dit d’un document XML qu’il est bien formé si chaque balise ouvrante a une balise fermante, si les attributs
ont bien tous des valeurs au moins vide.
7.2.10 Les documents validés
Un document XML est validé lorsqu’il respecte l’organisation des éléments prévue par une DTD ou un schéma.
La validation identifie la ou les DTD et Schémas à appliquer au document, va les chercher et vérifie que toutes les
règles de construction décrite dedans sont respectées.
7.2.11 Les commentaires
Les commentaires sont délimités par <!-- et -->.
7.2.12 Les espaces de noms
Pour permettre l’extension, XML a introduit la notion d’espace de nom, ainsi il est possible dans un élément de
définir un espace de nom liant un préfixe d’élément à un schéma ou une DTD et donc de mélanger des éléments
de natures différentes. Le format est xmlns:NomPrefixe="URL".
Exemple :
<ex:exemple
xmlns:formation="http://www.ecreall.com/formations/xml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ex="http://example.org">
<formation:plone version="3 4">
<formation:python>
<p>Python c’est bien</p>
<a href="http://www.afpy.org">Association Francophone Python</p>
</formation:python>
</formation:plone>
</ex:exemple>
88
Chapitre 7. Rappel HTML et XML
Plone pour les intégrateurs, Version 1.0.0
7.3 Exercices
Écriture d’une page HTML et d’un document XML.
7.4 Ressources
–
–
–
–
–
–
–
Hypertexte
HTML
XHTML
XML
URL
W3C
Feuilles de styles
7.3. Exercices
89
Plone pour les intégrateurs, Version 1.0.0
90
Chapitre 7. Rappel HTML et XML
CHAPITRE 8
Concept de Python eggs
Note : Ce chapitre utilise un dépôt subversion créé dans le chapitre La gestion des sources avec subversion
–
–
–
–
–
–
–
–
Définition
Savoir
Installation de Python et Distribute
Packaging Python
– Installation d’un egg
– Télécharger un package sans l’installer
– Création d’un environnement isolé avec virtualenv
– Suppression d’un egg
– Methode “originelle” pour installer un package
– Installation de virtualenvwrapper
Passons au développement
– Installation de la commande paster
– Création de votre premier egg
– Déclaration des dépendances
– Egg en mode développement
– Le hello world que tout le monde attend
– Les espaces de nom ou namespaces
L’API pkg_resources
Les entry points
– groupe console_scripts
Mise en place d’un Pypi privé avec PloneSoftwareCenter
– Installation de collective.dist pour Python 2.4 et 2.5
– Configuration des serveurs
– Enregistrement et upload
– Broken release
8.1 Définition
Les Python eggs sont des packages distribuables. La notion de egg doit être bien comprise pour comprendre la
suite. C’est la base des outils d’aujourd’hui comme zc.buildout qui sert au déploiement d’un site Plone et
paster pour la génération de squelette de projet.
91
Plone pour les intégrateurs, Version 1.0.0
8.2 Savoir
–
–
–
–
–
–
distribute/setuptools
environnement isolé avec virtualenv
création d’un egg avec paster
metadata (description au format ReST, dépendances, extras)
installation via easy_install
entry points et plugins (paster utilise ce mécanisme de plugins)
8.3 Installation de Python et Distribute
Dans ce qui suit, je considère que vous êtes sous Ubuntu ou Debian et que vous souhaitez travailler sur Plone 4
qui requiert Python 2.6. Si vous voulez installer un Plone 3, il vous faudra Python 2.4, dans ce cas, remplacez 2.6
par 2.4 dans les instructions suivantes.
Installez les packages suivants :
$ sudo apt-get install build-essential python2.6 python2.6-dev
Le meta-paquet build-essential vous installera tout ce qu’il faut (compilateur gcc, make, etc.) pour compiler certains modules Python. Si par la suite vous avez une erreur disant que le fichier Python.h ne peut être trouvé,
c’est très probablement que vous n’avez pas le paquet python2.6-dev d’installé.
Sous Ubuntu, installez le gestionnaire de paquets distribute comme ceci :
$ wget http://python-distribute.org/distribute_setup.py
$ sudo python distribute_setup.py
Si vous voulez être sûr de la version de Python que vous utilisez, vous pouvez vérifier la version comme ceci :
$ python --version
Python 2.7.3
Et savoir exactement où il se trouve comme ceci :
$ which python
/usr/bin/python
Ce python est en fait un lien symbolique ici vers python2.7, comme on peut le voir :
$ ls -l /usr/bin/python
lrwxrwxrwx 1 root root 9 juil.
9 16:41 /usr/bin/python -> python2.7
À tout moment, vous pouvez exécuter ces commandes pour savoir quel Python vous utilisez réellement.
Après l’installation de distribute, la commande easy_install est disponible pour installer de nouveaux eggs pour
Python 2.7.
8.4 Packaging Python
Un package Python peut être distribué sous la forme d’une simple archive (zip ou tar.gz).
Python inclut la librairie distutils afin de réaliser ces distributions source, mais celle-ci ne gère pas les dépendances entre packages. distribute est un fork de setuptools, une extension à distutils qui ajoute de
nombreuses fonctionnalités :
– dépendances (metadata install_requires)
– distribution binaire, egg
– entry points
92
Chapitre 8. Concept de Python eggs
Plone pour les intégrateurs, Version 1.0.0
Le package distribute fournit la commande easy_intall qui permet d’installer un package donné :
$ easy_install zope.interface
Il y a également pip qui lui propose un moyen alternatif à easy_install pour installer un package.
Tarek Ziadé et d’autres personnes travaillent sur l’amélioration de la gestion des packages Python avec le nouveau
package distutils2 qui remplacera distutils et distribute.
– implémentation d’une fonctionnalité de désinstallation d’un package
– ajout du metadata install_requires (entre autres) pour décrire les dépendances, mais la gestion des dépendances
se fera toujours avec une commande tierce.
Vous pouvez lire le billet de Tarek et les PEPs associés si vous êtes intéressé sur le sujet.
8.4.1 Installation d’un egg
La communauté Python possède un dépôt central où sont stockés tous les packages Python, c’est le Pypi (Python
Package Index), connu autrefois sous le nom de Cheese Shop. Son adresse : http ://pypi.python.org/pypi
Lorsque vous installez un package Python via easy_install, c’est sur cet index que le package est recherché.
En effet l’index par défaut est l’URL suivante : http ://pypi.python.org/simple
Exécutez easy_install Fabric, voici ce qui est exactement fait :
– connexion à l’index http ://pypi.python.org/simple
– recherche de Fabric dans la liste des liens, si un lien est trouvé, il est suivi
– nous arrivons donc sur http ://pypi.python.org/simple/Fabric/ Cette page contient une liste d’urls où l’on peut
télécharger directement l’egg, mais également toutes les urls contenues dans la description longue du egg.
– la liste fournie sur cette page est ensuite filtrée de la manière suivante :
– on donne priorité au egg binaire (bdist) qu’à la distribution source (sdist)
– on garde les packages liés à l’OS, donc si on est sous Windows, les eggs ayant win32 sont gardés
– seul les eggs utilisant la version de Python qu’on est en train d’utiliser sont gardés
– si aucun egg binaire n’est trouvé, alors on recherche une distribution source (tar.gz ou zip)
– il se peut qu’il n’y ait aucun lien direct vers un egg sur cette page, mais un lien vers une ou plusieurs urls où
l’on peut les télécharger (liens contenus dans long_description ou via l’option download_url précisé lors
de la création du egg). Dans ce cas-là, les liens sont suivis pour aller chercher une liste des versions.
Si le package n’a pas été trouvé sur l’index, alors on entame une nouvelle recherche, cette fois parmi tous les
find-links (éventuellement filtré par l’option -H/--allow-hosts) :
$ easy_install --find-links http://pkg.example.com/packages/ monpackage
Vous pouvez par exemple autoriser seulement les connexions vers votre intranet et pypi :
$ easy_install -H *.myintranet.example.com,*.python.org zope.interface
L’option -H/--allow-hosts permet aussi par exemple d’installer un package sans le réseau, en interdissant
toutes les URLs et en spécifiant un dossier somedir où aller chercher le package SomePackage :
$ easy_install -H None -f somedir SomePackage
Au lieu de préciser l’option en ligne de commande, vous pouvez le mettre dans le fichier de configuration
~/.pydistutils.cfg :
[easy_install]
allow_hosts = *.myintranet.example.com
Dans ce cas, seul les packages téléchargeables sur myintranet.example.com pourront être installés.
Il est possible de changer l’index par défaut par lequel les eggs sont recherchés via l’option -i/--index-url.
Pypi possède des miroirs
Voir aussi le projet pour créer et/ou utiliser des miroirs de pypi.
8.4. Packaging Python
93
Plone pour les intégrateurs, Version 1.0.0
Si l’on veut utiliser un miroir ou un index privé par exemple. Nous traiterons le cas d’un index privé avec le produit
PloneSoftwareCenter par la suite.
8.4.2 Télécharger un package sans l’installer
Il est possible de télécharger le code source (sdist) d’un package sans pour autant l’installer :
$ easy_install -b . -e zope.interface
Exécutez easy_install -h pour connaitre la signification des options.
En savoir plus : Documentation EasyInstall
8.4.3 Création d’un environnement isolé avec virtualenv
Il est fréquent de vouloir tester plusieurs versions d’un framework. Admettons que vous ayez zope 3.4 installé
globalement, comment pouvez-vous tester zope 3.5 sans que votre installation de zope 3.4 interfère ? La solution
est de créer un environnement isolé avec virtualenv.
Lisez le tutoriel virtualenv sur grok.zope.org pour savoir comment l’installer et l’utiliser. Revenez ici lorsque c’est
fait.
Si ce n’est déjà fait, installez virtualenv avec Python 2.4 :
$ easy_install-2.4 virtualenv
Bien, vous êtes revenu. Maintenant expliquons comment la magie opère.
Dans Python, vous avez dans sys.path la liste des chemins dans lesquels on peut trouver des packages Python :
$ which python2.4
/usr/bin/python2.4
$ python2.4
>>> import sys
>>> sys.path
[’’, ’/usr/lib/python2.4’, ’/usr/lib/python2.4/plat-linux2’,
’/usr/lib/python2.4/lib-tk’, ’/usr/lib/python2.4/lib-dynload’,
’/usr/local/lib/python2.4/site-packages’,
’/usr/lib/python2.4/site-packages’,
’/usr/lib/python2.4/site-packages/Numeric’,
’/usr/lib/python2.4/site-packages/PIL’,
’/usr/lib/python2.4/site-packages/gst-0.10’,
’/var/lib/python-support/python2.4’,
’/usr/lib/python2.4/site-packages/gtk-2.0’,
’/var/lib/python-support/python2.4/gtk-2.0’]
Créons un environnement nommé myenv :
$ virtualenv myenv --distribute
Ce que fait cette commande peut se résumer plus ou moins à ces commandes :
$ mkdir -p myenv/bin myenv/lib/python2.4/site-packages
$ cp /usr/bin/python2.4 myenv/bin/python
$ cp /usr/bin/python2.4 myenv/bin/python2.4
94
Chapitre 8. Concept de Python eggs
Plone pour les intégrateurs, Version 1.0.0
création de liens symboliques vers les modules de la librairies standard installation de distribute (ou
setuptools à défaut du paramètre --distribute) dans cet environnement, ce qui génère les commandes command :bin/easy_install et bin/easy_install-2.4 (c’est le même exécutable) et la création d’un script
bin/activate.
Notez que python (sans suffixe) est la version 2.5 sous Ubuntu 8.04 et 8.10 :
$ which python
/usr/bin/python
$ python -V
Python 2.5.2
Entrons dans le dossier et activons l’environnement :
$ cd myenv/
$ source bin/activate
Le prompt indique que votre environnement est actif. Jetez un œil au source du fichier bin/activate, il n’y
a rien de magique là dedans, il change seulement la variable d’environnement PATH pour y inclure au début le
dossier myenv/bin. La partie essentielle de ce script est :
$ export PATH="/home/vincentfretin/myenv/bin:$PATH"
Cela a son importance, précédement python était le binaire /usr/bin/python qui est la version 2.5 de
Python sous Ubuntu 8.04 et 8.10. Maintenant c’est le python de l’environnement, qui est un Python 2.4 :
(myenv)$ which python
.../myenv/bin/python
(myenv)$ python -V
Python 2.4.5
Maintenant regardons le sys.path :
(myenv)$ python
>>> import sys
>>> sys.path
[’’,
’/home/vincentfretin/myenv/lib/python2.4/site-packages/setuptools-0.6c11-py2.4.egg’,
’/home/vincentfretin/myenv/lib/python2.4’,
’/home/vincentfretin/myenv/lib/python2.4/plat-linux2’,
’/home/vincentfretin/myenv/lib/python2.4/lib-tk’,
’/home/vincentfretin/myenv/lib/python2.4/lib-dynload’, ’/usr/lib/python2.4’,
’/usr/lib64/python2.4’, ’/usr/lib/python2.4/plat-linux2’,
’/usr/lib/python2.4/lib-tk’, ’/usr/lib64/python2.4/lib-tk’,
’/home/vincentfretin/myenv/lib/python2.4/site-packages’,
’/usr/local/lib/python2.4/site-packages’, ’/usr/lib/python2.4/site-packages’,
’/usr/lib/python2.4/site-packages/Numeric’,
’/usr/lib/python2.4/site-packages/PIL’,
’/usr/lib/python2.4/site-packages/gst-0.10’,
’/var/lib/python-support/python2.4’,
’/usr/lib/python2.4/site-packages/gtk-2.0’,
’/var/lib/python-support/python2.4/gtk-2.0’]
Vous voyez que les chemins vers les dossiers globaux sont toujours inclus mais que les premiers sont ceux de
notre environnement. En effet vous pouvez utiliser la bibliothèque PIL qui est installé globalement :
>>> import PIL
Sous Ubuntu 9.04, PIL n’est pas disponible sous Python 2.4. Ici import PIL est seulement utilisé comme
exemple d’import d’un package installé globalement. Le package virtualenv a aussi été installé globalement,
donc vous pouvez utiliser import virtualenv à la place pour tester.
8.4. Packaging Python
95
Plone pour les intégrateurs, Version 1.0.0
En général vous voulez un environnement isolé des packages extérieurs, c’est le rôle de l’option
--no-site-packages de virtualenv. Nous allons recréer l’environnement avec cette option, tout d’abord
désactivez l’environnement :
(myenv)$ deactivate
deactivate est juste une fonction bash créée lorsque vous avez sourcé bin/activate.
Supprimez votre environnement et recréez le avec l’option --no-site-packages :
$ cd ..
$ rm -rf myenv
$ virtualenv --no-site-packages myenv
Maintenant voyez par vous même la différence :
$ cd myenv/
$ . bin/activate
(myenv)$ python
>>> import sys
>>> sys.path
[’’,
’/home/vincentfretin/myenv/lib/python2.4/site-packages/setuptools-0.6c9-py2.4.egg’,
’/home/vincentfretin/myenv/lib/python2.4’,
’/home/vincentfretin/myenv/lib/python2.4/plat-linux2’,
’/home/vincentfretin/myenv/lib/python2.4/lib-tk’,
’/home/vincentfretin/myenv/lib/python2.4/lib-dynload’, ’/usr/lib/python2.4’,
’/usr/lib64/python2.4’, ’/usr/lib/python2.4/plat-linux2’,
’/usr/lib/python2.4/lib-tk’, ’/usr/lib64/python2.4/lib-tk’,
’/home/vincentfretin/myenv/lib/python2.4/site-packages’]
Le dossier PIL n’est plus là, comme l’atteste l’exception ImportError :
>>> import PIL
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ImportError: No module named PIL
Vous pouvez installer PIL dans cet environnement comme ceci :
easy_install --find-links http://dist.plone.org/thirdparty/ PIL
(L’archive PIL de pypi n’est pas easy installable.)
Ici, nous avons installé virtualenv avec easy_install-2.4, comment créer un environnement avec une autre version
de Python ? virtualenv possède une option -p pour préciser un exécutable python alternatif :
$ virtualenv -p /usr/bin/python --no-site-packages --distribute myenv25
$ cd myenv25
$ . bin/activate
Nous allons utiliser ce nouvel environnement pour installer Fabric qui nécessite Python >= 2.5. Vérifiez que
vous avez la package Ubuntu python2.5-dev ou python2.6-dev d’installé, il est nécessaire pour compiler pycrypto, une dépendance de Fabric. Fabric est un outil pour scripter les deploiements. Nous n’allons pas utiliser
easy_install Fabric ici, mais récupérer l’archive pour l’installer.
Nous téléchargons l’archive avec wget et exécutons ensuite easy_install avec l’archive en paramètre pour installer
le package :
(myenv25)$ wget http://git.fabfile.org/cgit.cgi/fabric/snapshot/fabric-0.9a3.tar.gz
(myenv25)$ easy_install fabric-0.9a3.tar.gz
96
Chapitre 8. Concept de Python eggs
Plone pour les intégrateurs, Version 1.0.0
Nous aurions très bien pu faire directement easy_install http://git.fabfile.org/cgit.cgi/fabric/snapshot
Vous pouvez remarquer que Fabric et ses dépendances ont été installées en eggs zippés :
(myenv25)$
total 1064
-rw-r--r--rw-r--r--rw-r--r--rw-r--r--rw-r--r--rw-r--r--
ls -l lib/python2.5/site-packages/
1
1
1
1
1
1
vincentfretin
vincentfretin
vincentfretin
vincentfretin
vincentfretin
vincentfretin
vincentfretin
306 2009-05-25 11:35 easy-install.pth
vincentfretin 71581 2009-05-25 11:35 Fabric-0.9a3-py2.5.egg
vincentfretin 296831 2009-05-25 11:35 paramiko-1.7.4-py2.5.egg
vincentfretin 358122 2009-05-25 11:35 pycrypto-2.0.1-py2.5-linux-x86_64
vincentfretin 328025 2009-05-25 11:34 distribute-0.6.8-py2.5.egg
vincentfretin
29 2009-05-25 11:34 setuptools.pth
Tous les eggs ne sont pas installés zippés. C’est le mainteneur du package qui décide si son egg est “zip safe” ou
non. Un package n’est par exemple pas zip safe s’il utilise la variable spéciale __file__ dans son code.
Vous vous demandez à quoi servent ces fichiers setuptools.pth et easy-install.pth n’est-ce pas ? Un
petit rappel Python va vous faire du bien alors.
Que contient ces fichiers xyz.pth (pour path) ? Comme son extension le suggère, ces fichiers contiennent une
liste de chemins où l’on peut trouver des packages :
(myenv25)$ cat lib/python2.5/site-packages/setuptools.pth
./distribute-0.6.8-py2.5.egg
(myenv25)$ cat lib/python2.5/site-packages/easy-install.pth
import sys; sys.__plen = len(sys.path)
./distribute-0.6.8-py2.5.egg
./Fabric-0.9a3-py2.5.egg
./paramiko-1.7.4-py2.5.egg
./pycrypto-2.0.1-py2.5-linux-x86_64.egg
import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,’__egginsert’,0);
Comme vous le voyez, la commande easy_install maintient dans le fichier easy-install.pth une liste des
eggs qu’elle a installés.
Au démarrage de Python, tous les packages python (dans le sens d’un dossier contenant un fichier
__init__.py) se trouvant dans lib/python2.5/site-packages/ sont ajoutés au sys.path. Ça c’est
la première étape, et dans notre cas, il n’y a aucun package. La deuxième étape recherche des fichiers xyz.pth,
les lit et inclut les chemins inclus si un package s’y trouve.
La première et dernière ligne du fichier easy-install.pth sont utilisés pour ajouter les eggs au début de
sys.path pour prendre la précédence aux packages éventuellement installés.
8.4.4 Suppression d’un egg
Il n’y a pas de commande uninstall pour désinstaller un egg. Une implémentation est en cours dans distutils2.
Pour le moment, il faut donc désinstaller manuellement et là il faut savoir ce que l’on fait.
La première chose qui vient à l’esprit est de supprimer le egg du site-packages. C’est très bien mais cela ne suffit
pas comme nous allons le voir.
Nous allons désinstaller Fabric pour l’installer d’une autre manière. Nous allons profiter de cette désintallation
pour revenir sur le fichier xyz.pth.
Notez bien que nous avons dans le sys.path setuptools, Fabric et paramiko, dans le même ordre que listé
dans easy-install.pth :
(myenv25)vincentfretin@lelouch:~/myenv25$ python
Python 2.5.2 (r252:60911, Oct 5 2008, 19:29:17)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
8.4. Packaging Python
97
Plone pour les intégrateurs, Version 1.0.0
>>> import sys
>>> sys.path
[’’,
’/home/vincentfretin/myenv25/lib/python2.5/site-packages/setuptools-0.6c11-py2.5.egg’,
’/home/vincentfretin/myenv25/lib/python2.5/site-packages/Fabric-0.9a3-py2.5.egg’,
’/home/vincentfretin/myenv25/lib/python2.5/site-packages/paramiko-1.7.4-py2.5.egg’,
’/home/vincentfretin/myenv25/lib/python2.5/site-packages/pycrypto-2.0.1-py2.5-linux-x86_64.egg’,
’/home/vincentfretin/myenv25/lib/python2.5’, ...]
Maintenant supprimons le egg de Fabric :
(myenv25)vincentfretin@lelouch:~/myenv25$ rm lib/python2.5/site-packages/Fabric-0.9a3-py2.5.egg
Mais nous n’avons pas supprimé l’entrée dans easy-install.pth. Allons nous encore avoir
/home/vincentfretin/myenv25/lib/python2.5/site-packages/Fabric-0.9a3-py2.5.egg
dans le sys.path ? Voyons voir :
(myenv25)vincentfretin@lelouch:~/myenv25$ python
Python 2.5.2 (r252:60911, Oct 5 2008, 19:29:17)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
[’’,
’/home/vincentfretin/myenv25/lib/python2.5/site-packages/setuptools-0.6c9-py2.5.egg’,
’/home/vincentfretin/myenv25/lib/python2.5/site-packages/paramiko-1.7.4-py2.5.egg’,
’/home/vincentfretin/myenv25/lib/python2.5/site-packages/pycrypto-2.0.1-py2.5-linux-x86_64.egg’,
’/home/vincentfretin/myenv25/lib/python2.5’, ...]
Et bien non, Python n’a trouvé aucun package Python ./Fabric-0.9a3-py2.5.egg qui n’existe plus, il ne
l’a donc pas ajouté dans le sys.path.
Pour faire une désintallation propre d’un egg, il faut :
– supprimer le egg
– supprimer l’entrée dans easy-install.pth
– supprimer les éventuels scripts qui ont été générés à l’installation, ici bin/fab.
8.4.5 Methode “originelle” pour installer un package
easy_install fait partie du package distribute / setuptools. Si distribute ou setuptools n’est
pas disponible dans votre environnement, on peut très bien installer un package en l’extrayant et exécutant la
commande python setup.py install :
(myenv25)$ tar xvf fabric-0.9a3.tar.gz
(myenv25)$ cd fabric-0.9a3/
(myenv25)$ python setup.py install
En fait, c’est exactement ce que fait la commande easy_install.
8.4.6 Installation de virtualenvwrapper
virtualenvwrapper est un ensemble de fonctions bash pour gérer vos environnements.
Pour l’installer :
$ sudo easy_install virtualenvwrapper
98
Chapitre 8. Concept de Python eggs
Plone pour les intégrateurs, Version 1.0.0
Éditez ensuite votre ~/.bashrc pour sourcer le fichier /usr/local/bin/virtualenvwrapper.sh.
Sur Ubuntu, j’ai l’habitude de décommenter dans ~/.bashrc les 3 lignes concernant l’inclusion de
~/.bash_aliases. Je met ensuite dans ce fichier tous les alias et autres variables d’environnement que je
veux. Ici nous voulons ces deux lignes :
TMPDIR=/tmp
source /usr/local/bin/virtualenvwrapper.sh
virtualenvwrapper utilise le dossier ~/.virtualenvs par défaut pour créer et chercher les environnements :
$ mkdir ~/.virtualenvs
Démarrez un nouveau terminal, vous avez maintenant à disposition les commandes suivantes :
– workon : affiche la liste des environnements contenu dans ~/.virtualenvs
– workon myenv : active l’environnement myenv
– mkvirtualenv myenv : crée l’environnement myenv avec la commande virtualenv et l’active Tous les paramètres données à mkvirtualenv serons donnés à la commande command :virtualenv.
– rmvirtualenv myenv : supprime l’environnement myenv
– cdvirtualenv : va dans le dossier de l’environnement actif
– cdsitepackages : va dans le dossier site-packages de l’environnement actif
– lssitepackages : liste les eggs installés de l’environnement actif
– cpvirtualenv : copie un environnement existant
Donc avant pour activer un environnement, vous faisiez :
$ cd myenv
$ . bin/activate
Maintenant vous n’avez qu’à taper workon myenv où que vous soyez.
8.5 Passons au développement
8.5.1 Installation de la commande paster
Dans ce qui suit je travaille dans mon environnement myenv, je n’indiquerai plus le “(myenv)” dans le prompt.
Installez le egg PasteScript.
Le egg PasteScript fournit la commande paster avec laquelle on peut créer des squelettes de code.
Pour lister les templates disponibles :
$ paster create --list-templates
Available templates:
basic_package: A basic setuptools-enabled package
paste_deploy:
A web application deployed through paste.deploy
Il n’y a pas beaucoup de templates par défaut.
Installez le egg ZopeSkel qui fournit divers templates et reexécutez la commande :
$ paster create --list-templates
Available templates:
Available templates:
archetype:
A Plone project that uses Archetypes content types
basic_buildout:
A basic buildout skeleton
basic_namespace:
A basic Python project with a namespace package
basic_package:
A basic setuptools-enabled package
nested_namespace: A basic Python project with a nested namespace (2 dots in name)
paste_deploy:
A web application deployed through paste.deploy
plone_basic:
A package for Plone add-ons
8.5. Passons au développement
99
Plone pour les intégrateurs, Version 1.0.0
plone_nested:
recipe:
zope2_basic:
zope2_nested:
A
A
A
A
package for Plone add-ons with a nested namespace
recipe project for zc.buildout
Zope project
nested-namespace Zope package
Ah il y a déjà plus de choix !
Ceux que nous utiliserons par la suite sont basic_namespace, plone_basic, plone_nested.
En fait, vous auriez très bien pu installer uniquement ZopeSkel car PasteScript en est une dépendance.
8.5.2 Création de votre premier egg
Pour créer un squelette, vous choisissez votre template et exécutez :
$ paster create -t nom_de_la_template
Créez votre premier egg :
$ paster create -t basic_namespace
Selected and implied templates:
templer.core#basic_namespace A basic Python project with a namespace package
Enter project name: foo.bar
Variables:
egg:
foo.bar
package: foobar
project: foo.bar
Expert Mode? (What question mode would you like? (easy/expert/all)?) [’easy’]:
Version (Version number for project) [’1.0’]:
Description (One-line description of the project) [’’]:
Creating template basic_namespace
Creating directory ./foo.bar
Copying setup.py_tmpl to ./foo.bar/setup.py
Recursing into src
Creating ./foo.bar/src/
Recursing into +namespace_package+
Creating ./foo.bar/src/foo/
Recursing into +package+
Creating ./foo.bar/src/foo/bar/
Copying __init__.py_tmpl to ./foo.bar/src/foo/bar/__init__.py
Copying __init__.py_tmpl to ./foo.bar/src/foo/__init__.py
Running /home/cedric/.virtualenvs/myenv/bin/python setup.py egg_info
Voyons ce qu’il a généré :
$ tree foo.bar
foo.bar/
|-- CHANGES.txt
|-- CONTRIBUTORS.txt
|-- docs
|
|-- LICENSE.GPL
|
‘-- LICENSE.txt
|-- README.txt
|-- setup.py
‘-- src
|-- foo
|
|-- bar
|
|
‘-- __init__.py
|
‘-- __init__.py
‘-- foo.bar.egg-info
|-- dependency_links.txt
100
Chapitre 8. Concept de Python eggs
Plone pour les intégrateurs, Version 1.0.0
|-|-|-|-|-|-‘--
entry_points.txt
namespace_packages.txt
not-zip-safe
PKG-INFO
requires.txt
SOURCES.txt
top_level.txt
Le dossier foo.bar.egg-info est généré automatiquement avec la commande python setup.py egg_info
(dernière commande exécutée par paster).
Ce dossier ne sera donc pas ajouté au gestionnaire de version comme nous le verrons plus loin.
Le fichier setup.py contient les données que vous avez entrées.
8.5.3 Déclaration des dépendances
L’option install_requires dans setup.py permet d’indiquer des dépendances, ici notre egg dépend de
setuptools.
Les dépendances sont vérifiées à l’installation de l’egg. install_requires est une liste de Requirement.
requirement
::=
nom_egg
[(“>=” | “>” | “<” | “<=” | “==” | ”!=”) version]
En savoir plus : Declaring Dependencies (concepts d’extras)
L’option entry_points sera expliquée plus loin.
8.5.4 Egg en mode développement
Installons tout de suite ce nouvel egg pour pouvoir l’importer.
La première chose a laquelle vous pensez est de faire python setup.py install et vous avez raison !
Mais l’inconvénient dans ce cas-là est qu’à chaque fois que vous allez changer quelque chose à votre package,
vous devrez reexécuter cette commande.
Nous avons une commande develop, qui est bien mieux pour installer un egg tout en le développant. Faites donc
ceci :
$ cd foo.bar
$ python setup.py develop
Cette commande, au lieu de copier le dossier dans site-packages, crée un fichier foo.bar.egg-link
qui n’est autre finalement qu’un lien symbolique multi-plateforme qui pointe vers le dossier de votre egg en
développement.
En savoir plus : “Development Mode”
8.5.5 Le hello world que tout le monde attend
Allez-y maintenant, ouvrez un python et importez votre package :
$ python
>>> import foo.bar
Et le “hello world” me direz vous ? Bien je vois que vous avez l’habitude.
Éditez le fichier foo/__init__.py pour y ajouter :
8.5. Passons au développement
101
Plone pour les intégrateurs, Version 1.0.0
print "Hello"
Réimportez votre module :
$ python
>>> import foo.bar
Hello
Éditez le fichier foo/bar/__init__.py et ajoutez-y :
print "world!"
Réimportez le module :
$ python
>>> import foo.bar
Hello
world!
Et voilà !
En plus l’exemple sert pour faire un petit rappel Python : Face à import foo.bar que fait l’interpréteur
Python ?
Eh bien il regarde dans le sys.path un package foo (dossier foo avec un fichier __init__.py dedans) ou
un module foo (fichier foo.py), dans cet ordre.
Ici un package foo est trouvé, et le contenu du fichier __init__.py est exécuté.
On passe ensuite à bar, un package ou un module est recherché à l’intérieur du package : mod :foo.
Ici un package bar est trouvé, le contenu de son fichier __init__.py est exécuté.
8.5.6 Les espaces de nom ou namespaces
À quoi sert le code dans foo/__init__.py ? Très bonne question !
Créez un egg comme précédemment nommé : file :foo.rab (pas très inspiré), et installez le en mode développé.
Vous l’avez fait sans regarder le texte au dessus, c’est très bien !
Vous avez usé de la flêche haute, avouez le. C’est encore mieux !
Éditez foo.rab/foo/__init__.py :
print "Bonjour"
Éditez foo.rab/foo/rab/__init__.py :
print "le monde"
On y est. Vérifions que foo.bar et foo.rab sont dans notre sys.path et sont bien dans cette ordre :
$ python
>>> import sys
>>> sys.path
[..., ’/home/vincentfretin/src/foo.bar’, ’/home/vincentfretin/src/foo.rab’,
...]
102
Chapitre 8. Concept de Python eggs
Plone pour les intégrateurs, Version 1.0.0
Comme dit plus haut, Python recherche un package nommé foo, il en trouve un, exécute le contenu de
__init__.py et normalement devrait s’arrêter là.
Donc cela devrait donner ceci :
>>> import foo
Hello
car foo.bar étant en premier dans le sys.path.
Au lieu de ça, qu’avons-nous ?
>>> import foo
Bonjour
Hello
Il se peut que vous ayez “Hello Bonjour” comme ordre, c’est assez mystérieux. L’essentiel est que vous ayez les
deux.
Ensuite :
>>> import foo.rab
le monde
>>> import foo.bar
world!
Le code de foo.bar/foo/__init__.py indique que : mod :foo est un espace de nom. Et cela change le
comportement de l’import.
Au lieu de s’arrêter au premier package foo trouvé, la recherche continue et tous les packages foo trouvés sont
exécutés.
Si foo n’était pas déclaré comme espace de nom dans l’egg foo.bar, alors vous auriez eu ceci :
>>> import foo.rab
Traceback (most recent call last)
File "<stdin>", line 1, in ?
ImportError: No module named rab
Vous pouvez faire le test en commentant namespace_packages=[’foo’] du setup.py de foo.bar.
Il faut réexécuter python setup.py egg_info (la commande egg_info est également exécutée lors d’un
install ou d’un develop)
pour mettre à jour les metadonnées du egg situées dans le dossier foo.bar.egg-info. Commentez également
les lignes dans foo.bar/foo/__init__.py.
En temps normal, ne mettez pas de code dans les fichiers __init__.py des packages servant d’espace de nom
comme le dit la documentation de setuptools.
En savoir plus : Namespace Packages
8.6 L’API pkg_resources
setuptools fournit un module pkg_resources avec lequel on peut par exemple récupérer la version d’un egg.
Cet API sert à lire les différents fichiers du dossier .egg-info.
Exemple pour récupérer la version du egg foo.bar installé :
$ python
>>> import pkg_resources
>>> d = pkg_resources.get_distribution("foo.bar")
>>> d.version
’1.0dev’
8.6. L’API pkg_resources
103
Plone pour les intégrateurs, Version 1.0.0
>>> d.location
’/home/vincentfretin/src/foo.bar’
En savoir plus : Documentation PkgResources
8.7 Les entry points
Revenons sur l’option entry_points dans setup.py.
Cette option sert à définir des points d’entrées pour le egg. On peut utiliser cette notion pour réaliser des plugins.
Reprenons les eggs PasteScript et ZopeSkel. Comment PasteScript a fait pour découvrir les nouveaux
templates installés par : mod :ZopeSkel ?
ZopeSkel utilise le système templer pour générer ses templates. Templer définit des entry points pour le groupe
paste.paster_create_template :
$ cdsitepackages
$ cat templer.plone-1.0b1-py2.7.egg-info/entry_points.txt
# -*- Entry points: -*[paste.paster_create_template]
plone_basic = templer.plone:Plone
plone_nested = templer.plone:NestedPlone
archetype = templer.plone:Archetype
où plone_basic est un nom, templer.plone est un module et Plone un callable, ici une classe.
et PasteScript lui fait une recherche des eggs déclarant
paste.paster_create_template avec l’API pkg_resources :
des
entry
points
pour
$ python
>>> import pkg_resources
>>> list(pkg_resources.iter_entry_points(’paste.paster_create_template’))
[...,
EntryPoint.parse(’plone_basic = templer.plone:Plone’),
EntryPoint.parse(’plone_nested = templer.plone:NestedPlone’),
EntryPoint.parse(’archetype = templer.plone:Archetype’),
...]
On peut charger le callable d’un entry point, souvent une classe :
>>> entry_points = list(pkg_resources.iter_entry_points(’paste.paster_create_template’))
>>> ep = entry_points[4]
>>> ep
EntryPoint.parse(’plone_basic = templer.plone:Plone’)
>>> PloneBasic = ep.load()
>>> PloneBasic
<class ’templer.plone.plone.Plone’>
En savoir plus : Dynamic Discovery of Services and Plugins
8.7.1 groupe console_scripts
Le groupe console_scripts est spécial. Il est utilisé lors de l’installation du egg pour générer les scripts dans
le dossier bin.
Pour générer un script bin/fab, le egg Fabric définit dans son setup.py :
104
Chapitre 8. Concept de Python eggs
Plone pour les intégrateurs, Version 1.0.0
entry_points={
’console_scripts’: [
’fab = fabric.main:main’,
]
},
On peut également l’écrire de la manière suivante directement :
entry_points="""
[console_scripts]
fab = fabric.main:main
""",
Dans les deux cas, le fichier entry_points.txt généré sera normalisé comme ceci :
[console_scripts]
fab = fabric.main:main
Concrétement, exécuter la commande fab revient à faire :
$ python
>>> from fabric.main import main
>>> main()
En savoir plus : Automatic Script Creation
8.8 Mise en place d’un Pypi privé avec PloneSoftwareCenter
Créez une instance Plone avec l’id “site” sur une machine servant de serveur (Installation via l’Unified Installer),
nous allons l’appeler devagile, avec la résolution DNS dans /etc/hosts :
10.56.8.47
devagile
Il est très facile de transformer une instance Plone en un Pypi pour votre entreprise en installant le produit Products.PloneSoftwareCenter.
Créez un site Plone avec comme id site, installez le module et ajoutez un élément Software Center nommé products
à la racine du site.
L’URL de ce Pypi sera donc http ://devagile :8080/site/products
8.8.1 Installation de collective.dist pour Python 2.4 et 2.5
Si vous utilisez Python 2.4 ou 2.5, il vous faut installer collective.dist qui introduit deux nouvelles commandes
mregister et mupload pour pouvoir enregister votre egg sur plusieurs serveurs.
Si vous utilisez Python 2.6, remplacez mregister par register, et mupload par upload dans ce qui suit.
En effet le support de serveurs multiples n’a été introduit qu’à partir de la version 2.6 de Python.
8.8.2 Configuration des serveurs
Il faut tout d’abord configurer votre fichier ~/.pypirc :
8.8. Mise en place d’un Pypi privé avec PloneSoftwareCenter
105
Plone pour les intégrateurs, Version 1.0.0
[distutils]
index-servers =
pypi
mycompany
[pypi]
username:user
password:password
[mycompany]
repository:http://devagile:8080/site/products
username:ploneuser
password:password
Sous Windows vous ne pouvez pas créer ce fichier .pypirc avec le gestionnaire de fichiers, mais dans un shell,
vous pouvez.
Dans un shell dos, allez dans C:\Profiles\User, et créez le fichier avec la commande :
edit .pypirc
8.8.3 Enregistrement et upload
Exécutez ensuite :
Avec Python < 2.6
$ python setup.py mregister -r mycompany sdist --formats=zip mupload -r mycompany
Avec Python >= 2.6 :
$ python setup.py register -r mycompany sdist --formats=zip upload -r mycompany
–
–
–
–
mregister permet d’enregistrer le egg sur le serveur
sdist permet de créer une distribution source
mupload transfère sur la distribution source vers le serveur
-r mycompany précise d’enregistrer et de transfèrer sur le serveur mycompany (r pour repository dans
doute). Si cette option n’est pas précisée, c’est le serveur Pypi d’origine.
– --formats=zip, génère une archive au format zip. Par défaut sous Linux, une archive tar.gz est générée, le
module tarfile dans Python < 2.6 semble avoir certains problèmes de lecture de ces archives.
La commande mregister exécute implicitement la commande egg_info. Cette commande génère entre autres le
numéro de version.
Le fichier setup.cfg est lu par cette commande, il configure quelques options liées à la génération du numéro
de version. Créez un fichier setup.cfg qui contient :
$ cat setup.cfg
[egg_info]
tag_build = dev
tag_svn_revision = true
La version générée sera donc de la forme “1.0dev”.
Pour une release stable, on supprime généralement ce fichier pour que la version soit simplement “1.0”.
On peut également laisser le fichier en place et écraser la configuration en ligne de commande comme ceci :
$ python setup.py egg_info -RDb "" register -r mycompany sdist --formats=zip upload -r mycompany
106
Chapitre 8. Concept de Python eggs
Plone pour les intégrateurs, Version 1.0.0
L’option --formats=zip permet de générer une archive zip au lieu d’une archive tar.gz par défaut sous Linux.
Avec python setup.py sdist --help-formats, vous pouvez voir la liste des formats possibles d’archives.
Si vous voulez par exemple créer une archive zip et tar.gz, vous pouvez spécifier l’option
--formats=zip,gztar.
Regardez la signification des options avec :
$ python setup.py egg_info -h
--tag-build (-b)
Specify explicit tag to add to version number
--no-svn-revision (-R)
Don’t add subversion revision ID [default]
--no-date (-D)
Don’t include date stamp [default]
Nous verrons par la suite comment faire une release en bonne et due forme avec le gestionnaire de version subversion.
On peut remplacer sdist par bdist_egg pour générer un egg, une distribution binaire.
La convention est de générer un bdist_egg pour chaque version de Python pour la plateforme Windows si le
egg contient des librairies C à compiler.
Pour les autres OS, la distribution source sera récupérée et les librairies C seront compilées à l’installation.
8.8.4 Broken release
Créez un nouvel environnement testenv :
$ mkvirtualenv testenv
Essayez maintenant d’installer foo.bar 1.0 à partir de votre pypi :
$ easy_install -i http://devagile:8080/site/products/simple foo.bar
Il y a une erreur à l’installation disant qu’il ne trouve pas le fichier CONTRIBUTORS.txt.
La release est cassée car elle ne contient pas le fichier CONTRIBUTORS.txt. Et nous avons de ce fichier pour la
long_description.
Le dossier docs est également manquant car dans setup.py nous avons package=find_packages, ça recherche seulement les dossiers contenant un fichier __init__.py. docs n’étant pas un package, il n’a pas été
inclu dans l’archive.
Pour régler le problème, il faut mettre le code source dans un dépôt subversion et grâce à l’option
include_package_data=True dans setup.py, tous les fichiers subversionnés seront ajoutés à l’archive.
Note : Vous pouvez créer facilement un dépôt subversion comme ceci :
svnadmin create Formation
Et pour faire un checkout :
svn co http://devagile/Formation
Donc on va importer notre code dans le dépôt Formation :
$ svn import foo.bar/ http://devagile/Formation/foo.bar -m "First import of foo.bar"
Attention, le dossier .egg-info a été commité ! Nous allons le supprimer de subversion :
8.8. Mise en place d’un Pypi privé avec PloneSoftwareCenter
107
Plone pour les intégrateurs, Version 1.0.0
$
$
$
$
svn co http://devagile/Formation
cd Formation/foo.bar
svn rm foo.bar.egg-info dist
svn ci -m "Delete egg-info and dist directories"
Nous allons donc maintenant faire une nouvelle release de foo.bar, pour cela incrémentez la version dans
setup.py, mettez 1.1, éditez le fichier docs/HISTORY.txt pour ajouter une information au changelog,
commitez et refaites la release.
Nous allons faire pareil pour foo.rab, mais nous allons tout d’abord configurer l’option global-ignores
dans ~/.subversion/config pour ignorer le dossier .egg-info lors de l’import.
Ouvrez le fichier ~/.subversion/config et configurez global-ignores comme suit :
global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store *.pyc *.pyo .installed.cfg bi
Vous pouvez maintenant importer le code source dans subversion et faire la release.
108
Chapitre 8. Concept de Python eggs
CHAPITRE 9
Introduction à zc.buildout
Author Vincent Fretin
Contributors
Copyright (C) 2010 Vincent Fretin <vincentfretin AT gmail.com>.
Chacun est autorisé à copier, distribuer et/ou modifier ce document suivant les termes de la licence
Paternité-Pas d’Utilisation Commerciale-Partage des Conditions Initiales à l’Identique 2.0 France accessible à
http ://creativecommons.org/licenses/by-nc-sa/2.0/fr
Le code source présent dans ce document est soumis aux conditions de la « Zope Public License », Version 2.1
(ZPL).
THE SOURCE CODE IN THIS DOCUMENT AND THE DOCUMENT ITSELF 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.
–
–
–
–
–
–
–
–
–
–
–
–
–
–
Définition
Introduction
Organisation d’un buildout
Section principale [buildout]
Partage du dossier eggs et downloads
Pinning des versions
Extension buildout.dumppickedversions
Option extends
– Option extends-cache
Recipe collective.recipe.omelette
Utilisation de variable
Repinning et fusion de section de données
Ordre d’installation des parts
L’option develop
Option index et find-links
9.1 Définition
Un buildout est un dossier contenant plusieurs fichiers de configuration permettant de reproduire à l’identique un
environnement de développement ou de production. Paster est l’outil qui permet de générer le code squelette pour
démarrer.
109
Plone pour les intégrateurs, Version 1.0.0
9.2 Introduction
Buildout est un système d’installation permettant d’obtenir le même résultat d’une machine à l’autre. L’installation
est reproductible.
– Qu’est-ce que zc.buildout ?
– Survol de Buildout
zc.buildout permet d’avoir un environnement (pas forcément isolé), mais d’une autre manière que virtualenv.
Une configuration buildout spécifie un ensemble de parts qui se composent :
– d’une recette (recipe)
– et/ou de données de configuration
9.3 Organisation d’un buildout
Un buildout est organisé de la manière suivante :
– buildout.cfg : contient la configuration du buildout
– bootstrap.py : script d’amorçage de buildout utilisé la première fois
– bin/ : dossier contenant les exécutables éventuellement générés par les parts
– src/ : par convention, dossier où sont placés les eggs en développement
– parts/ : dossier où sont stockées les données générées des parts si besoin
– .installed.cfg : fichier caché mémorisant l’état du buildout
– .mr.developer.cfg : fichier caché mémorisant l’état des packages en développement si vous utilisez
l’extension mr.developer.
– eggs/ : dossier contenant les eggs activés ou non. Peut ne pas exister si on utilise un dossier partagé pour
plusieurs buildouts.
– develop-eggs/ : dossier contenant les liens vers les eggs en développement
– extends-cache/ si vous mettez en cache les fichiers de versions téléchargés.
Seuls les fichiers buildout.cfg, bootstrap.py et extends-cache/ ont besoin d’être mis dans une
gestionnaire de versions.
Nous allons prendre comme exemple le buildout.cfg pour installer archgenxml.
Suivez la page d’installation du manuel d’archgenxml2
Créez un dossier archgenxml_buildout/, placez y une copie du fichier bootstrap.py et créez un fichier
buildout.cfg avec le contenu suivant :
[buildout]
parts =
archgenxml
[archgenxml]
recipe = zc.recipe.egg:scripts
eggs = archgenxml
Note : Les versions de zc.buildout >= 1.5.2 permettent d’avoir un environnement isolé du système, cela est
désactivé par défaut pour garder la compatibilité avec les versions antérieures. Pour avoir pleinement cette
fonctionnalité, il faut que vous activiez l’option include-site-packages = false et que vous remplaciez zc.recipe.egg par z3c.recipe.scripts. Si vous utilisez d’autres recipes, il faut qu’elles utilisent aussi
z3c.recipe.scripts en interne. Regardez dans le changelog de ces recipes, s’il est indiqué que la recipe dépend
maintenant d’une version >= 1.5.0, c’est qu’elle a dû être adapté pour utiliser z3c.recipe.scripts.
9.4 Section principale [buildout]
La variable parts contient la liste des parts que buildout doit installer. La convention est de mettre une part par
ligne, indenté de 4 espaces. Il peut y avoir des lignes vides et des commentaires commencant au début de la ligne.
110
Chapitre 9. Introduction à zc.buildout
Plone pour les intégrateurs, Version 1.0.0
Chaque part fournit une variable recipe pour indiquer comment ce part doit être installé, mis à jour et supprimé.
Il se peut qu’une section ne fournisse pas de recipe. Elle sert généralement pour des données de configuration que
d’autres parts utiliseront.
Amorcez le buildout (choisissez bien la version de l’exécutable python) :
$ python bootstrap.py -d
Downloading http://pypi.python.org/packages/source/d/distribute/distribute-0.6.14.tar.gz
...
Creating directory ’/home/vincentfretin/archgenxml_buildout/bin’.
Creating directory ’/home/vincentfretin/archgenxml_buildout/parts’.
Creating directory ’/home/vincentfretin/archgenxml_buildout/eggs’.
Creating directory ’/home/vincentfretin/archgenxml_buildout/develop-eggs’.
Generated script ’/home/vincentfretin/archgenxml_buildout/bin/buildout’.
$ tree
.
|-- bin
|
‘-- buildout
|-- bootstrap.py
|-- buildout.cfg
|-- develop-eggs
|-- eggs
|
|-- distribute-0.6.28-py2.7.egg
|
‘-- zc.buildout-1.5.2-py2.7.egg
‘-- parts
‘-- buildout
L’amorçage (ou bootstrapping) installe distribute et zc.buildout. L’amorçage génère le script
bin/buildout.
Exécutez maintenant :
$ bin/buildout
Getting distribution for ’zc.recipe.egg’.
Got zc.recipe.egg 1.3.2.
Installing archgenxml.
Getting distribution for ’archgenxml’.
Got archgenxml 2.6.
...
Generated script ’/home/vincentfretin/archgenxml_buildout/bin/archgenxml’.
Generated script ’/home/vincentfretin/archgenxml_buildout/bin/agx_argouml_profile’.
Generated script ’/home/vincentfretin/archgenxml_buildout/bin/agx_stereotypes’.
Generated script ’/home/vincentfretin/archgenxml_buildout/bin/agx_taggedvalues’.
Le egg archgenxml et ses dépendances sont téléchargés et installés et divers scripts sont générés à la fin. C’est
la recipe qui dit tout ça.
À première vue, l’exécution de buildout pourrait se résumer à cet algorithme : pour chaque part de l’option parts
de la section [buildout], appeler la recipe associée au part.
Revenons à la ligne recipe = zc.recipe.egg:scripts. zc.recipe.egg est un egg à deux espaces
de nom et le scripts après les deux points est un entry point du groupe zc.buildout.
Si vous ne spécifiez pas de point d’entrée, un point d’entrée nommé default sera alors recherché dans l’egg.
Jetez un œil au setup.py de zc.recipe.egg :
entry_points = {’zc.buildout’: [’default = %s:Scripts’ % name,
’script = %s:Scripts’ % name,
’scripts = %s:Scripts’ % name,
’eggs = %s:Eggs’ % name,
’custom = %s:Custom’ % name,
’develop = %s:Develop’ % name,
]
},
9.4. Section principale [buildout]
111
Plone pour les intégrateurs, Version 1.0.0
Dans ce cas, nous serions arrivé au même résultat si nous avions mis l’une de ces lignes :
recipe
recipe
recipe
recipe
=
=
=
=
zc.recipe.egg
zc.recipe.egg:default
zc.recipe.egg:scripts
zc.recipe.egg:script
L’entry point scripts pointe vers la classe Scripts du package zc.recipe.egg.
Cette classe, comme toute recipe, contient des méthodes install et update. Voir l’API des recettes
Le fichier caché .installed.cfg garde la configuration de la dernière exécution de buildout.
Lorsqu’une section a été supprimée de la configuration, cette partie sera désinstallée lors de la relance de
bin/buildout. Si une section a été mise à jour, cette partie sera réinstallée. Pour les nouvelles sections avec recipe,
les parties seront installées.
Notre algorithme de tout à l’heure est maintenant :
– pour chaque part de l’option parts de la section [buildout] :
– installer la recipe du part ;
– récupérer l’entry point spécifié (default si non spécifié) depuis la recipe ;
– si le part est actuellement installé mais sa configuration a changé, appeler la méthode update() de l’entry
point ;
– si le part n’a pas encore été installé, appeler la méthode install() de l’entry point ;
– si un part existe dans .installed.cfg et n’est plus dans la liste des parts de [buildout], alors le part
est désintallé.
Jetez un œil sur les scripts générés. Rappel : les scripts bin/archgenxml et bin/agx_* sont générés car le
egg archgenxml a des entry points dans le groupe console_scripts. :
bin/archgenxml
#!/usr/bin/python
import sys
sys.path[0:0] = [
’/home/vincentfretin/archgenxml_buildout/eggs/archgenxml-2.6-py2.7.egg’,
...
]
import archgenxml.ArchGenXML
if __name__ == ’__main__’:
archgenxml.ArchGenXML.main()
La première ligne est le shebang, la version du python avec laquelle vous avez fait command :python bootstrap.py
-d au début. archgenxml et toutes ses dépendances sont ajoutés au début du sys.path.
9.5 Partage du dossier eggs et downloads
Lors de l’exécution de buildout, le fichier ~/.buildout/default.cfg est lu, c’est dans ce fichier que nous
pouvons mettre des options qui seront partagées par tous nos buildouts.
Si le dossier ~/.buildout/ n’existe pas, créez le ainsi que les sous-dossiers :
$ mkdir ~/.buildout ~/.buildout/eggs ~/.buildout/downloads \
~/.buildout/configs
Créez le fichier ~/.buildout/default.cfg avec ce contenu :
[buildout]
eggs-directory = /home/vincentfretin/.buildout/eggs
download-cache = /home/vincentfretin/.buildout/downloads
#extends-cache = /home/vincentfretin/.buildout/configs
112
Chapitre 9. Introduction à zc.buildout
Plone pour les intégrateurs, Version 1.0.0
Remplacez ici bien sûr vincentfretin par votre compte. Vous ne pouvez pas utiliser le caractère ~ ici.
À savoir que les valeurs par défaut de ces variables sont :
eggs-directory = ${buildout:directory}/eggs
download-cache = pas précisé, on ne garde pas les archives par défaut
extends-cache = pas de cache par défaut
${buildout:directory} étant le dossier du buildout. C’est pour cela que le dossier eggs était créé dans le
buildout.
Vous pouvez supprimer le dossier eggs de votre buildout, le réamorcer et reexécuter bin/buildout
9.6 Pinning des versions
À chaque fois que vous exécutez bin/buildout, une requête est faite au serveur central pour savoir si nous avons la
dernière version du egg. C’est le comportement par défaut. En effet nous avons l’option newest = true dans
la section [buildout] par défaut.
Vous pouvez faire bin/buildout -N pour ne pas vérifier les mises à jour.
Si vous aviez newest = false dans votre buildout, la commande bin/buildout -n la remettrait à true pour
l’exécution.
Le problème est que votre buildout n’est pas reproductible à l’identique. Pour qu’il soit reproductible à l’identique
il faudrait que votre buildout précise quelles versions des eggs doivent être installées.
C’est là qu’intervient l’option versions de la section [buildout], vous spécifiez dans quelle section vous
avez les informations sur les versions. La convention est de l’appeler également versions. Pour geler (verbe
“to pin” en anglais, “pinned” au participe passé) archgenxml, modifiez votre buildout de cette manière :
[buildout]
versions = versions
parts = archgenxml
[versions]
archgenxml = 2.6
# ...
[archgenxml]
recipe = zc.recipe.egg:scripts
eggs = archgenxml
Mais cela ne suffit pas pour que le buildout soit reproductible car nous n’avons pas gelé les dépendances d’archgenxml.
9.7 Extension buildout.dumppickedversions
zc.buildout peut être étendu avec des extensions. Il y en a une particulièrement intéressante qui va vous sortir
la liste des eggs qui ne sont pas gelés avec leur version.
Une extension s’ajoute avec l’option extensions de la section [buildout] Ajoutez donc l’extension
buildout.dumppickedversions à votre fichier buildout.cfg :
[buildout]
extensions = buildout.dumppickedversions
# ...
9.6. Pinning des versions
113
Plone pour les intégrateurs, Version 1.0.0
Relancez bin/buildout et à la fin de l’exécution vous verrez apparaitre la liste des versions à geler. Ajoutez-les
tous à votre section versions, et reexécutez bin/buildout, il ne devrait plus avoir de versions.
Il existe aussi une option allow-picked-versions = false disponible dans le cœur de
zc.buildout qui permet de stopper le buildout si un egg n’est pas gelé. Cette option et l’extension
buildout.dumppickedversions sont mutuellement exclusives.
Attention : Cette extension n’est plus compatible avec buildout 2. La fonctionnalité a été intégré dans
le cœur. Il suffit de préciser l’option show-picked-version = true à la place de extensions =
buildout.dumppickedversions.
9.8 Option extends
Il est possible d’étendre le fichier buildout.cfg. Vous verrez souvent un fichier deployment.cfg ou
development.cfg qui étend le fichier buildout.cfg de base.
Créez un fichier development.cfg :
[buildout]
extends = buildout.cfg
parts = omelette
[omelette]
recipe = collective.recipe.omelette
eggs = archgenxml
L’option extends dit de lire le fichier buildout.cfg, et les options que l’on spécifiera par la suite seront
écrasées.
Par défaut, buildout cherche un fichier buildout.cfg, l’option -c permet d’indiquer un fichier alternatif.
Relancez la machinerie buildout avec ce fichier :
$ bin/buildout -c development.cfg
Uninstalling archgenxml.
Installing omelette.
Oh que s’est-il passé ? Vous avez écrasé l’option parts, il n’y a donc plus que le part omelette à installer.
Vous vouliez garder aussi le part archgenxml, rectifiez ça en transformant le = par +=, ce qui donne parts
+= omelette.
Toutes les options supportant une liste fonctionnent ainsi (parts, eggs, develop).
Relancez buildout. Là les deux parts sont bien installées.
Remarque
imaginez toujours que vous avez implicitement extends = ~/.buildout/default.cfg dans votre
buildout.cfg de base, à partir duquel vous étendez d’autres configurations, ici c’est le fichier
buildout.cfg.
Vous pouvez récupérer une version mis à plat de la configuration avec la commande suivante :
$ bin/buildout -c development.cfg annotate
...
[buildout]
parts=
archgenxml
omelette
/home/vincentfretin/archgenxml_buildout/buildout.cfg
114
Chapitre 9. Introduction à zc.buildout
Plone pour les intégrateurs, Version 1.0.0
+= /home/vincentfretin/archgenxml_buildout/development.cfg
...
Vous voyez bien ici que l’option parts a été mis à plat, c’est la concaténation de l’option trouvée dans
buildout.cfg et de development.cfg.
9.8.1 Option extends-cache
L’option extends-cache disponible depuis la version 1.4.0 de zc.buildout permet de mettre en cache les
fichiers référencés dans l’option extends.
Prenons l’exemple suivant :
extends = http://dist.plone.org/release/4.2/versions.cfg
Le fichier versions.cfg sera mis en cache dans le dossier ~/.buildout/configs/, le fichier créé étant
la somme md5 de l’url.
Une fois mis en cache, il est possible de relancer le buildout en mode hors ligne avec la commande bin/buildout
-o.
9.9 Recipe collective.recipe.omelette
On ne fait pas d’omelette sans casser des eggs. Cette recipe permet de mettre à plat les eggs :
[omelette]
recipe = collective.recipe.omelette
eggs = archgenxml
Cette recipe génère une arborescence dans parts/omelette/ contenant archgenxml et toutes ses dépendances
directes ou indirectes :
$ tree parts/omelette/
parts/omelette
|-- archgenxml -> /home/vincentfretin/.buildout/eggs/archgenxml-2.5-py2.6.egg/archgenxml
|-- easy_install.py -> /usr/local/lib/python2.6/dist-packages/distribute-0.6.14-py2.6.egg/easy_ins
|-- i18ndude -> /home/vincentfretin/.buildout/eggs/i18ndude-3.2-py2.6.egg/i18ndude
|-- pkg_resources.py -> /usr/local/lib/python2.6/dist-packages/distribute-0.6.14-py2.6.egg/pkg_res
|-- plone
|
|-- __init__.py
|
‘-- i18n -> /home/vincentfretin/.buildout/eggs/plone.i18n-2.0-py2.6.egg/plone/i18n
|-- setuptools -> /usr/local/lib/python2.6/dist-packages/distribute-0.6.14-py2.6.egg/setuptools
|-- site.py -> /usr/local/lib/python2.6/dist-packages/distribute-0.6.14-py2.6.egg/site.py
|-- stripogram -> /home/vincentfretin/.buildout/eggs/stripogram-1.5-py2.6.egg/stripogram
|-- xmiparser -> /home/vincentfretin/.buildout/eggs/xmiparser-1.5-py2.6.egg/xmiparser
‘-- zope
|-- __init__.py
|-- browser -> /home/vincentfretin/.buildout/eggs/zope.browser-1.3-py2.6.egg/zope/browser
|-- component -> /home/vincentfretin/.buildout/eggs/zope.component-3.10.0-py2.6.egg/zope/compo
|-- configuration -> /home/vincentfretin/.buildout/eggs/zope.configuration-3.7.2-py2.6.egg/zop
|-- contenttype -> /home/vincentfretin/.buildout/eggs/zope.contenttype-3.5.1-py2.6.egg/zope/co
|-- documenttemplate -> /home/vincentfretin/.buildout/eggs/zope.documenttemplate-3.4.2-py2.6.e
|-- event -> /home/vincentfretin/.buildout/eggs/zope.event-3.5.0_1-py2.6.egg/zope/event
|-- exceptions -> /home/vincentfretin/.buildout/eggs/zope.exceptions-3.6.1-py2.6.egg/zope/exce
|-- i18n -> /home/vincentfretin/.buildout/eggs/zope.i18n-3.7.4-py2.6.egg/zope/i18n
|-- i18nmessageid -> /home/vincentfretin/.buildout/eggs/zope.i18nmessageid-3.5.3-py2.6-linux-x
|-- interface -> /home/vincentfretin/.buildout/eggs/zope.interface-3.6.1-py2.6-linux-x86_64.eg
|-- location -> /home/vincentfretin/.buildout/eggs/zope.location-3.9.0-py2.6.egg/zope/location
|-- proxy -> /home/vincentfretin/.buildout/eggs/zope.proxy-3.6.1-py2.6-linux-x86_64.egg/zope/p
|-- publisher -> /home/vincentfretin/.buildout/eggs/zope.publisher-3.12.4-py2.6.egg/zope/publi
9.9. Recipe collective.recipe.omelette
115
Plone pour les intégrateurs, Version 1.0.0
|-|-|-‘--
schema -> /home/vincentfretin/.buildout/eggs/zope.schema-3.7.0-py2.6.egg/zope/schema
security -> /home/vincentfretin/.buildout/eggs/zope.security-3.7.4-py2.6-linux-x86_64.egg/
structuredtext -> /home/vincentfretin/.buildout/eggs/zope.structuredtext-3.5.0-py2.6.egg/z
tal -> /home/vincentfretin/.buildout/eggs/zope.tal-3.5.2-py2.6.egg/zope/tal
25 directories, 5 files
Cela permet d’avoir les packages à plat, ce qui facilite la recherche, exemple :
$ find -L parts/omelette -name "interfaces.py"
$ grep -r "register" parts/omelette
Si vous développez avec Eclipse/Pydev, vous pouvez ajouter le répertoire parts/omelette/ au PYTHONPATH du projet, ceci permet l’exploration du code en mode “hypertexte” (ctrl+clic sur un symbole) et l’auto
completion intelligente de fonctionner correctement.
9.10 Utilisation de variable
Vous avez écrit “archgenxml” à deux endroits, une fois dans la recipe zc.recipe.egg et une autre fois dans la
recipe collective.recipe.omelette. Il est plus intéressant de l’indiquer une seule fois dans une variable
et d’utiliser cette variable ensuite dans les recipes.
Une convention est de définir une variable eggs dans la section [buildout] et de récupérer cette variable avec
${buildout:eggs}.
Voici ce que donnent les deux fichiers une fois reécrits.
buildout.cfg
[buildout]
versions = versions
parts = archgenxml
eggs = archgenxml
[versions]
archgenxml = 2.5
distribute = 0.6.14
xmiparser = 1.5
zc.buildout = 1.5.2
zc.recipe.egg = 1.3.2
zope.contenttype = 3.5.1
zope.i18nmessageid = 3.5.3
zope.tal = 3.5.2
Unidecode = 0.04.1
i18ndude = 3.2
ordereddict = 1.1
plone.i18n = 2.0
pytz = 2010l
stripogram = 1.5
zope.browser = 1.3
zope.component = 3.10.0
zope.configuration = 3.7.2
zope.documenttemplate = 3.4.2
zope.event = 3.5.0-1
zope.exceptions = 3.6.1
zope.i18n = 3.7.4
zope.interface = 3.6.1
zope.location = 3.9.0
zope.proxy = 3.6.1
zope.publisher = 3.12.4
zope.schema = 3.7.0
116
Chapitre 9. Introduction à zc.buildout
Plone pour les intégrateurs, Version 1.0.0
zope.security = 3.7.4
zope.structuredtext = 3.5.0
[archgenxml]
recipe = zc.recipe.egg:scripts
eggs = ${buildout:eggs}
development.cfg
[buildout]
extends = buildout.cfg
parts += omelette
[omelette]
recipe = collective.recipe.omelette
eggs = ${buildout:eggs}
Vous pouvez référencer n’importe quelle variable de la section que vous souhaitez avec
${nomdesection:variable}. Vous pouvez référencer une variable de la même section avec juste
${:variable}.
9.11 Repinning et fusion de section de données
Vous voyez que la recipe collective.recipe.omelette n’est pas gelé. Faites donc les modifications
suivantes dans development.cfg :
[buildout]
# ...
versions = vers
[vers]
collective.recipe.omelette = 0.9
Relancez buildout. Vous voyez que seul collective.recipe.omelette est gelé maintenant car l’option
versions a été écrasée.
Renommez vers en versions et relancez le buildout.
Tous les eggs sont gélés. En effet la section versions de buildout.cfg et la section versions de
development.cfg ont fusionné.
En conclusion, nommez toujours versions la section contenant les versions.
Mais maintenir deux listes est source d’erreur. Créez un fichier versions.cfg qui contient une section
[versions] (pas de section [buildout]), et dites à buildout.cfg d’étendre versions.cfg. Relancez buildout pour voir que tout fonctionne.
9.12 Ordre d’installation des parts
L’ordre d’installation des parts n’est pas forcément l’ordre donné dans l’option parts de [buildout]. Et une
part peut très bien être installée si elle n’est pas listée dans parts.
Modifiez votre buildout.cfg comme ceci :
[buildout]
# ...
parts = zopeskel archgenxml
[archgenxml]
# ...
9.11. Repinning et fusion de section de données
117
Plone pour les intégrateurs, Version 1.0.0
packages = ZopeSkel
[zopeskel]
recipe = zc.recipe.egg
eggs = ${archgenxml:packages}
Dans cet exemple, il n’y aucune raison particulière pour installer une part avant l’autre. C’est juste pour l’exercice.
L’ordre d’installation sera [archgenxml], puis [zopeskel]. Si maintenant vous supprimez la part
[archgenxml] de parts, elle sera toujours installée car la part [zopeskel] en dépend, faisant référence à
une de ses variables.
9.13 L’option develop
Note : Cette partie dépend du chapitre Concept de Python eggs.
L’option develop permet d’indiquer quels eggs sont en mode développement.
Créez un dossier src/ et déplacez y vos deux eggs foo.bar et foo.rab.
Ajoutez foo.bar à l’omelette et relancez bin/buildout -c development.cfg. Buildout tente d’aller
chercher foo.bar sur Pypi et échoue.
Nous allons donc lui dire où le trouver.
Ajoutez à la section [buildout] de development.cfg :
[buildout]
# ...
find-links +=
http://devagile:8080/site/products/simple
develop = src/foo.bar
Relancez bin/buildout -c development.cfg.
Le egg foo.bar est en mode développement :
$ ls -l develop-eggs/
total 12
-rw-r--r-- 1 vincentfretin vincentfretin 57 2009-05-26 18:20 foo.bar.egg-link
-rw-r--r-- 1 vincentfretin vincentfretin 32 2009-05-26 15:38 setuptools.egg-link
Nous pouvons également utiliser un wildcard dans l’option develop. Mettez develop = src/*, du coup les
deux eggs foo.bar et foo.rab sont en développement.
9.14 Option index et find-links
Note : Cette partie dépend du chapitre Concept de Python eggs.
L’option index permet de spécifier un autre index que celui par défaut, par exemple un pypi proxy avec
collective.eggproxy.
L’option find-links permet d’indiquer des liens supplémentaires où l’on peut trouver les eggs utilisés dans le
buildout.
Nous allons maintenant installer foo.bar = 1.1, la release qu’il y a sur notre pypi.
Supprimez donc l’option develop et dans development.cfg, ajoutez :
118
Chapitre 9. Introduction à zc.buildout
Plone pour les intégrateurs, Version 1.0.0
[buildout]
# ...
find-links += http://devagile:8080/site/products/simple
Dans buildout.cfg, ajoutez foo.bar à la liste des eggs :
[buildout]
# ...
eggs =
archgenxml
foo.bar
Enfin, ajoutez foo.bar = 1.1 dans versions.cfg.
9.14. Option index et find-links
119
Plone pour les intégrateurs, Version 1.0.0
120
Chapitre 9. Introduction à zc.buildout
CHAPITRE 10
Installation et création d’une instance
Plone
– Savoir
– Installation via l’Unified Installer
– Installation via un template buildout
– Installation sous Ubuntu/Debian
– Installation sur Windows
– Installation sous Mac OSX
– Exercice
Plusieurs types d’installation sont possibles, soit en utilisant un “template” de configuration, soit en utilisant un
unified installer.
10.1 Savoir
La récupération des archives et leur installation, la création d’un buildout et la compilation de Zope.
Plone est disponible en plusieurs versions et selon différents modes.
Note à propos des combinaisons de versions de Plone, Python et Zope :
– Plone 3.3 utilise Python 2.4, Zope 2.10.
– Plone 4 utilise Python 2.6 et Zope 2.12.
– Plone 4.1 et 4.2 utilisent Zope 2.13, Python 2.7 ou 2.6
10.1.1 Installation via l’Unified Installer
C’est la solution la plus simple.
Le unified installer est un paquet qui contient toutes les sources, bibliothèques et outils nécessaires à l’exécution
de Plone.
Il contient aussi un script d’installation qui permet de configurer Plone.
Il contient le mécanisme buildout qui permettra de facilement modifier la configuration de Plone pour ajouter des
modules tierces.
Pour l’installer, il suffit de récupérer le paquet sur http ://plone.org/products/plone et d’exécuter ou d’extraire le
paquet selon sa plateforme.
Commandes à exécuter :
121
Plone pour les intégrateurs, Version 1.0.0
$
$
$
$
$
$
wget http://launchpad.net/plone/3.3/3.3.X/+download/Plone-3.3.X-UnifiedInstaller.tgz
tar xvzf Plone-3.3rc3-UnifiedInstaller.tgz
cd Plone-3.3rc3-UnifiedInstaller
./install.sh --with-python=/usr/bin/python2.4 standalone
cd ~/Plone/zinstance
bin/plonectl start
Le mode standalone crée une seule instance. Vous pouvez remplacer standalone par zeo pour créer deux
clients avec un zeoserver.
Si vous lancez le script en root, il créera un utilisateur plone et installera Python, Zope et Plone dans
/usr/local/Plone. Python ne sera pas compilé si vous utilisez l’option --with-python.
Pour plus d’informations, lisez le fichier README.txt dans l’archive et la documentation Installing Plone 3 with
the Unified Installer sur plone.org
L’inconvénient de cette solution est que les paquets unified installer sont réalisés pour les versions stables ou beta
de Plone. Les impatients doivent suivre la procédure d’installation par buildout.
10.1.2 Installation via un template buildout
Buildout est un outil qui permet de créer et déployer des configurations de projets Python.
Il est possible à partir d’un outil nommé paster de créer un squelette de configuration pour buildout. Cet outil sera
aussi détaillé par la suite, il se repose sur un mécanisme de patrons (template) propre à chaque projet.
Pour installer une version de Plone donnée (depuis la version 2.5), il suffit donc de créer une configuration pour la
version de Plone voulue en utilisant paster puis de compléter cette configuration pour enfin la construire.
L’intérêt de cette méthode est de permettre l’installation de version en cours de développement ou en vue d’automatiser le déploiement sur plusieurs serveurs.
Installation sous Ubuntu/Debian
Installez tout d’abord quelques packages de développement qui seront nécessaires pour compiler PIL (Imaging)
et python-libxml2 :
$ apt-get install libxml2-dev libjpeg62-dev libfreetype6-dev zlib1g-dev
– libxml2-dev pour compiler python-libxml2
– libjpeg62-dev libfreetype6-dev zlib1g-dev pour compiler PIL
Dans Ubuntu Jaunty Jackalope 9.04 et suivants, les versions de Python installés par défaut sont 2.5 et 2.6.
Et les packages python-imaging et python-libxml2 de la distribution ne sont compilés que pour ces versions.
Il n’y a donc plus de support de ces packages pour Python 2.4. C’est pourquoi ces deux bibliothèques seront
compilées à partir du buildout.
Voir le billet de Maurits van Rees à ce sujet
Continuez sur le chapitre Création d’un buildout Plone avec ZopeSkel.
Installation sur Windows
Cette section est une mise à jour pour Plone 4 et une francisation de http ://plone.org/documentation/kb/usingbuildout-on-windows
Beaucoup de données vont être téléchargées vous devez donc avoir une connexion rapide.
Vous devez être à l’aise avec Windows et sa console Dos.
Nous réaliserons l’installation de Plone 4, mais l’installation de Plone 3 est la même à la différence qu’au lieu
d’utiliser Python2.6 vous utiliserez Python2.4 :
122
Chapitre 10. Installation et création d’une instance Plone
Plone pour les intégrateurs, Version 1.0.0
Python
Installer Python via le msi installer en le téléchargeant depuis le site http ://python.org, sélectionner “install for all
users” qui créera le répertoire c:\Python26 par défaut.
Changer la variable d’environnement path pour que Windows puisse automatiquement associer la commande
python à l’environnement :
– Python 2.6. Pour cela ouvrez Le panneau de configuration → Les Propriétés système → Variables d’environnement → Path → Modifier
– Ajoutez y en fin ;c:\Python26;c:\Python26\Scripts.
– Vérifier que vos modifications sont bien prises en compte en ouvrant une invite de commandes en saisissant
python -V qui doit vous afficher la version de Python.
Distribute
– Télécharger le gestionnaire de paquet Python distribute à l’adresse http ://pythondistribute.org/distribute_setup.py ce qui permettra de récupérer les bibliothèques tierces nécessaire à
Plone.
– Exécuter le dans l’environnement Python correspondant à votre distribution Plone :
c:\Python26\python.exe distribute_setup.py
pywin32
– Installer l’extension pywin32 qui permettra d’utiliser les applications Windows dans Python. Elle est disponible à l’adresse http ://sourceforge.net/projects/pywin32/files. Installer la version la plus récente proposée pour
Python 2.6.
PIL
– Installer PIL la bibliothèque de traitement d’image dont a besoin Plone pour retailler les images importées,
disponible à l’adresse http ://effbot.org/downloads :
http ://effbot.org/downloads/PIL-1.1.7.win32-py2.6.exe
Des
installeurs
pour
PIL
et
votre
http ://www.pythonware.com/products/pil/
version
de
Python
sont
disponibles
ici
:
Des installeurs pour les bindings Python libxml2 et libxslt pré-compilés sont mis à votre disposition ici :
http ://users.skynet.be/sbi/libxml-python/
Subversion
Installation de subversion. Subversion est un système de gestion de version qui permet de conserver et de réaliser
des différences entre les évolutions d’un programme.
La communauté Plone l’utilise pour gérer le code source de Plone.
Ainsi, nous récupèrerons les fichiers nécessaires à la configuration du buildout.
– Nous allons donc le télécharger et l’installer :
http ://subversion.tigris.org/files/documents/15/45953/Setup-Subversion-1.6.2.msi
– Puis nous ajoutons à notre variable d’environnement Path le chemin vers subversion :
c:\Program Files\Subversion\bin
– Vérifier en entrant la commande svn –version dans Invite de commandes que vous avez bien une version 1.6.2
10.1. Savoir
123
Plone pour les intégrateurs, Version 1.0.0
F IGURE 10.1 – Modification du path
124
Chapitre 10. Installation et création d’une instance Plone
Plone pour les intégrateurs, Version 1.0.0
MinGW
Installation de MinGW. MinGW est un portage du compilateur gcc pour Windows. Nous pourrons ainsi compiler
le code C de Zope.
– Récupérer le sur http ://sourceforge.net/projects/mingw/files/
– Exécuter
– Choisir download and install
– Accepter la licence
– Prendre la version actuelle
– Cocher MinGW base tools et MinGW Make
– Installer MinGW dans c:\MinGW et faire suivant
– MinGW télécharge les outils nécessaires
– Ajouter C:\MinGW\bin au Path
– Copier cc1.exe et collect2.exe du répertoire c:\MinGW\libexec\gcc\mingw32\3.4.5 dans
C:\MinGW\bin
– Vérifier en entrant gcc –version dans l’invite de commande
– Vérifier qu’il existe un fichier libpython26.a dans C:\Python26\libs sinon suivez la procédure décrite à http ://www.python.org/doc/2.4.1/inst/tweak-flags.html#SECTION000622000000000000000
– Si vous utilisez Python depuis une installation de Plone, vous devez copier
– Plone\Python\PC\pyconfig.h vers Plone\Python\Include
Configuration de Distutils pour utiliser MinGW
Nous allons créer un fichier de configuration qui permettra à distutils de savoir qu’il doit compiler les fichiers avec
MinGW.
Enregistrez les lignes suivantes dans C:\Python26\Lib\distutils\distutils.cfg :
[build]
compiler=mingw32
Installation de paster
Paster va nous permettre de créer le squelette de déploiement de notre site Plone. Il sera détaillé dans le chapitre
qui lui est consacré.
Pour installer Paster il suffit de faire easy_install PasteScript
Pour vérifier qu’il a bien été installé nous pouvons afficher les patrons de projets existant par défaut :
C:\>paster create --list-templates
Available templates:
basic_package: A basic setuptools-enabled package
paste_deploy:
A web application deployed through paste.deploy
Qui n’affiche que deux types de patron.
Nous allons ajouter les patrons liés aux projets Zope avec la commande easy_install ZopeSkel et vérifier les
patrons disponibles :
C:\>paster create --list-templates
Available templates:
archetype:
A Plone project that uses Archetypes content types
basic_namespace:
A basic Python project with a namespace package
basic_package:
A basic setuptools-enabled package
basic_zope:
A Zope project
kss_plugin:
A project for a KSS plugin
nested_namespace:
A basic Python project with a nested namespace (2 dots
in name)
10.1. Savoir
125
Plone pour les intégrateurs, Version 1.0.0
paste_deploy:
plone:
plone2.5_buildout:
plone2.5_theme:
plone2_theme:
plone3_buildout:
plone3_portlet:
plone3_theme:
plone_app:
dots in name)
plone_hosting:
plone_pas:
recipe:
silva_buildout:
A
A
A
A
A
A
A
A
A
web application deployed through paste.deploy
project for Plone products
buildout for Plone 2.5 projects
theme for Plone 2.5
theme for Plone 2.1
buildout for Plone 3 installation
Plone 3 portlet
theme for Plone 3
project for Plone products with a nested namespace (2
Plone hosting: buildout with ZEO and any Plone version
A project for a Plone PAS plugin
A recipe project for zc.buildout
A buildout for Silva projects
Installation de Plone 4
Nous allons procéder à l’installation de Plone en créant un buildout spécifique.
Pour cela saisissez la commande paster create -t plone3_buildout monplone4. Pour l’instant on utilise le patron de Plone 3 pour un site Plone 4. En indiquant une version supérieure ou égale à 4, la génération du fichier
buildout.cfg sera différente d’un Plone 3. Répondez aux questions comme ceci :
Expert mode ? expert
Plone version : 4.0b1-1
Zope2 Install Path :
Plone Products Directory :
Initial Zope Username [’admin’] :
Initial User Password : admin
HTTP Port [’8080’] : 9080
debug mode |’off’] :
verbose mode [’off’] :
Nous avons volontairement changé le port de Plone pour pouvoir faire cohabiter plusieurs versions ensemble.
La plupart de ces variables peuvent être changées par la suite.
L’exécution a pour conséquence de créer l’arborescence suivante :
C:\Documents and Settings\utlisateur>dir monplone4
Le volume dans le lecteur C n’a pas de nom.
Le numéro de série du volume est BC6D-1497
Répertoire de C:\Documents and Settings\utlisateur\monplone4
15/03/2010
15/03/2010
15/03/2010
15/03/2010
15/03/2010
15/03/2010
15/03/2010
15/03/2010
23:26
<REP>
.
23:26
<REP>
..
23:26
3 901 bootstrap.py
23:26
2 285 buildout.cfg
23:26
<REP>
products
23:26
10 856 README.txt
23:26
<REP>
src
23:26
<REP>
var
3 fichier(s)
17 042 octets
5 Rép(s)
8 233 197 568 octets libres
Nous allons générer les scripts de génération :
C:\Documents and Settings\utlisateur>cd monplone4
C:\Documents and Settings\utlisateur\monplone4>python bootstrap.py
Creating directory ’C:\\Documents and Settings\\utlisateur\\monplone4\\bin’
126
Chapitre 10. Installation et création d’une instance Plone
Plone pour les intégrateurs, Version 1.0.0
Creating directory ’C:\\Documents and Settings\\utlisateur\\monplone4\\parts’
Creating directory ’C:\\Documents and Settings\\utlisateur\\monplone4\\eggs’
Creating directory ’C:\\Documents and Settings\\utlisateur\\monplone4\
\develop-eggs’
Generated script ’C:\\Documents and Settings\\utlisateur\\monplone4\\bin\
\buildout’
Nous allons provoquer la récupération, la compilation et l’installation de Zope et Plone :
C:\Documents and Settings\utlisateur\monplone4>.\bin\buildout.exe
Getting distribution for ’plone.recipe.distros’.
zip_safe flag not set; analyzing archive contents...
plone.__init__: module references __path__
plone.recipe.__init__: module references __path__
Got plone.recipe.distros 1.5.
Getting distribution for ’plone.recipe.zope2instance==4.0a4’.
Got plone.recipe.zope2instance 4.0a4.
Getting distribution for ’Zope2==2.12.3’.
...
Generated script ’C:\\Documents and Settings\\utlisateur\\monplone4\\bin\
\instance’.Installing zopepy.
Generated interpreter ’C:\\Documents and Settings\\utlisateur\\monplone4\
\bin\\zopepy’.
Si tout ce passe bien nous avons un répertoire bin qui contient les lanceurs.
Pour démarrer Plone :
C:\Documents and Settings\utlisateur\monplone4>bin\instance.exe fg
Création de l’instance
Connectez vous à l’adresse http ://localhost :8080, on vous propose de créer un site Plone. Allez y.
Remarques
L’installation de plone via buildout pour Windows, n’est pas recommandée par la communauté en raison de sa
complexité.
Pour Windows, il vaut mieux passer par unified installer qui possèdera une installation de Python, un PIL, un
Zope, et un buildout prêt à l’emploi.
Ce qui correspond à une installation réussie des étapes précédentes...
Dans les deux cas, l’ajout des modules à Plone (anciennement appelés produit) se fait par ajout d’un egg.
Les eggs sont désormais la forme standard des paquets contenant les modules d’extensions de Plone.
Nous détaillerons les eggs dans un autre chapitre.
Donc l’ajout d’un egg se fait par déclaration du nom du egg voulu dans le fichier buildout.cfg à la section
eggs.
En lançant la commande bin\buildout.exe, le egg sera téléchargé, et au prochain démarrage de Plone, il y sera
accessible dans la liste des modules du menu de configuration de Plone.
Installation sous Mac OSX
Sous Mac OSX, installez Python 2.4 soit avec le bundle Python 2.4 .dmg proposé en téléchargement, soit en
utilisant MacPorts,
Si vous avez installé Python avec MacPorts, pas de problème :
10.1. Savoir
127
Plone pour les intégrateurs, Version 1.0.0
$ sudo port install py-pil
$ sudo port install py-libxml2
$ sudo port install py-libxslt
Autrement,
vous
pouvez
trouver
une
version
http ://pythonmac.org/packages/py25-fat/index.html
pré-compilée
statique
de
PIL
ici
:
Et vous devrez compilez les binders libxml2 et libxslt ceci sur votre poste comme indiqué ici : http ://jamesclarke.net/notes/libxml2
Suivez ensuite la procédure pour Ubuntu/Debian.
10.2 Exercice
Nous allons créer l’instance de test qui sera utilisée dans les exercices suivants.
128
Chapitre 10. Installation et création d’une instance Plone
CHAPITRE 11
Création d’un buildout Plone avec
ZopeSkel
Author Vincent Fretin
Contributors
Version 1.0.0
Copyright (C) 2010 Vincent Fretin <vincentfretin AT ecreall.com>.
Chacun est autorisé à copier, distribuer et/ou modifier ce document suivant les termes de la licence
Paternité-Pas d’Utilisation Commerciale-Partage des Conditions Initiales à l’Identique 2.0 France accessible à
http ://creativecommons.org/licenses/by-nc-sa/2.0/fr
Le code source présent dans ce document est soumis aux conditions de la « Zope Public License », Version 2.1
(ZPL).
THE SOURCE CODE IN THIS DOCUMENT AND THE DOCUMENT ITSELF 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.
– Création du buildout
– Installation de produits tierces
– Création d’un policy package contenant la configuration du site Plone
– Création du policy package
– Installation de Products.Collage à l’installation de formation.policy
– Déclaration de formation.policy comme plugin Plone
– Installation de collective.ckeditor à l’installation de formation.policy
– Configuration de ckeditor pour tous les nouveaux utilisateurs
– À propos des versions
– Releaser le policy package
– Repasser au développement
– Utilisation de mr.developer pour gérer les composants en développement
– Fabric
– Ressources
Note : Ce chapitre utilise un dépôt subversion créé dans le chapitre La gestion des sources avec subversion ainsi
qu’un Pypi privé créé via Mise en place d’un Pypi privé avec PloneSoftwareCenter.
129
Plone pour les intégrateurs, Version 1.0.0
11.1 Création du buildout
Créez les répertoires buildouts et packages sur le dépôt subversion :
$ svn mkdir http://devagile/Formation/buildouts
$ svn mkdir http://devagile/Formation/packages
Commandes :
$ paster create -t basic_buildout plone4 --svn-repository=http://devagile/Formation/buildouts/
Selected and implied templates:
templer.buildout#basic_buildout A basic buildout skeleton
Variables:
egg:
plone4
package: plone4
project: plone4
Running:
svn mkdir ...
Running svn co ...
Expert Mode? (What question mode would you like? (easy/expert/all)?) [’easy’]:
Creating template basic_buildout
Copying buildout.cfg_tmpl to ./plone4/buildout.cfg
Note : Avec l’option –svn-directory, un bug connu de Paste-1.7.3 et ZopeSkel-2.16 produit l’erreur suivante à la
fin du processus :
IOError : No egg-info directory found
Vous pouvez simplement l’ignorer.
Vous allez éditer le fichier buildout.cfg avant d’amorcer le buildout.
Remplacez le fichier buildout.cfg par :
[buildout]
parts =
instance
zopepy
extends =
http://dist.plone.org/release/4.2/versions.cfg
versions.cfg
versions = versions
find-links =
http://dist.plone.org/release/4.2
eggs = Pillow
develop =
[instance]
recipe = plone.recipe.zope2instance
user = admin:admin
http-address = 8080
eggs =
Plone
${buildout:eggs}
environment-vars =
zope_i18n_compile_mo_files true
zcml =
[zopepy]
recipe = zc.recipe.egg
130
Chapitre 11. Création d’un buildout Plone avec ZopeSkel
Plone pour les intégrateurs, Version 1.0.0
eggs = ${instance:eggs}
interpreter = zopepy
scripts = zopepy
Pillow est un fork de PIL (Python Imaging Library).
Créez un fichier versions.cfg que vous utiliserez pour geler les versions des modules, pour l’instant vide :
[versions]
Si vous voulez travailler sur la dernière version du fichier versions.cfg de Plone, vous pouvez le télécharger comme
ceci :
$ wget -O versions-plone.cfg http://dist.plone.org/release/4.2/versions.cfg
et changez votre buildout.cfg pour que l’option extends ressemble à ceci :
extends =
versions-plone.cfg
versions.cfg
Amorcez et lancez buildout :
$ cd plone4
$ python bootstrap.py -d
$ bin/buildout
$ ls -F
bin/ bootstrap.py buildout.cfg
$ ls parts
buildout instance
$ ls bin
buildout instance zopepy
develop-eggs/
parts/
var/
versions.cfg
– instance : script pour contrôler l’instance zope
– zopepy : interpréteur python avec l’ensemble des eggs dans le sys.path
Démarrez l’instance avec bin/instance fg et connectez vous à http ://localhost :8080 pour créer votre site
Plone.
Note : Commitez votre buildout
$ svn add versions.cfg
$ svn ci -m"Created initial buildout structure"
11.2 Installation de produits tierces
Prenons le produit FCKeditor comme exemple.
Stoppez l’instance avec Ctrl+C.
Ajoutez collective.ckeditor dans l’option eggs de la section [instance] et reexécutez le buildout :
$ bin/buildout
Démarrez l’instance :
$ bin/instance fg
11.2. Installation de produits tierces
131
Plone pour les intégrateurs, Version 1.0.0
Pour les produits n’étant pas dans l’espace de nom (namespace en anglais) Products, il faut également l’ajouter
dans l’option zcml.
À moins que le produit se proclame plugin Plone comme c’est le cas des modules créés avec la commande paster
que vous verrez dans la suite. Dans ce cas-là les fichiers zcml seront inclus grâce à z3c.autoinclude.
11.3 Création d’un policy package contenant la configuration du
site Plone
Vous allez créer un policy package contenant la configuration du site Plone.
Dans ce policy package, nous allons aussi dire d’installer automatiquement les produits Products.Collage
et collective.ckeditor lors de l’installation du produit.
Nous allons ensuite configurer FCKeditor comme éditeur par défaut pour les utilisateurs nouvellement créés.
11.3.1 Création du policy package
Créez le policy package :
$ cd /tmp/
$ paster create -t plone_basic formation.policy \
--svn-repository=http://devagile/Formation/packages
Selected and implied templates:
templer.core#basic_namespace A basic Python project with a namespace package
templer.plone#plone_basic
A package for Plone add-ons
Expert Mode? (What question mode would you like? (easy/expert/all)?) [’easy’]:
Version (Version number for project) [’1.0’]:
Description (One-line description of the project) [’’]: Projet exemple pour la formation integrate
Register Profile (Should this package register a GS Profile) [False]: True
$ cd formation.policy
$ svn rm --force formation.policy.egg-info
$ svn ci -m "Add initial structure for formation.policy"
Le template plone_basic hérite du template basic_namespace, il ajoute en plus un fichier
configure.zcml.
Vous allez utiliser la propriété svn:externals pour faire une sorte de checkout de votre nouveau package dans
le dossier src :
$ cd ~/workspace/plone4/
$ mkdir src
$ svn add src
$ cd src
$ vim EXTERNALS.txt
formation.policy http://devagile/Formation/packages/formation.policy/trunk
$ svn propset svn:externals -F EXTERNALS.txt .
$ svn up
$ svn add EXTERNALS.txt
$ svn ci -m "Set svn:externals on src directory to install formation.policy"
Ajoutez Products.Collage et collective.ckeditor en dépendances de formation.policy dans
le fichier src/formation.policy/setup.py (option install_requires).
Lorsque vous êtes dans le dossier src, la commande svn stat vous renvoie les changements faits dans les externals,
ici les changements de formation.policy s’il y en a.
132
Chapitre 11. Création d’un buildout Plone avec ZopeSkel
Plone pour les intégrateurs, Version 1.0.0
La commande svn up sera également faite dans les différents externals. La seule exception est la commade svn ci
exécutée à partir du dossier src ou plus en amont, les fichiers modifiés ou ajoutés dans les externals ne seront pas
commités.
Il faut vraiment être à l’intérieur de l’external, ici le dossier formation.policy pour que le commit des
changements soit réalisé.
Ceci dit, commitez le changement fait au fichier setup.py.
Editez buildout.cfg pour ajouter formation.policy :
[buildout]
#...
develop += src/formation.policy
[instance]
#...
eggs =
#...
formation.policy
zcml =
formation.policy
Exécutez bin/buildout.
L’ajout de formation.policy dans l’option zcml = ... génère un ZCML slug, fichier XML contenant
une seule ligne :
parts/instance/etc/package-includes/001-formation.policy-configure.zcml
<include package="formation.policy" file="configure.zcml" />
En fait au démarrage de l’instance Zope, le fichier parts/instance/etc/site.zcml est lu, ce qui entraine
la lecture de tous les fichiers situés dans le dossier package-includes, ainsi que les fichiers meta.zcml,
configure.zcml et overrides.zcml des produits dans l’espace de nom Products.
La chaine de lecture est donc celle-ci :
– parts/instance/etc/site.zcml
– parts/instance/etc/package-includes/001-formation.policy-configure.zcml
– src/formation.policy/src/formation/policy/configure.zcml
Ces fichiers ZCML sont les fichiers de configuration utilisés par la ZCA (Zope Component Architecture) pour
enregistrer les composants au démarrage.
11.3.2 Installation de Products.Collage à l’installation de formation.policy
Vous allez maintenant
formation.policy.
dire
à
Plone
d’installer
Products.Collage
lorsque
vous
installez
Ouvrez le fichier src/formation.policy/src/formation/policy/configure.zcml, vous avez
normalement ceci :
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:five="http://namespaces.zope.org/five"
xmlns:i18n="http://namespaces.zope.org/i18n"
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
i18n_domain="formation.policy">
<five:registerPackage package="." initialize=".initialize" />
<genericsetup:registerProfile
name="default"
title="formation.policy"
11.3. Création d’un policy package contenant la configuration du site Plone
133
Plone pour les intégrateurs, Version 1.0.0
directory="profiles/default"
description="Installs the formation.policy package"
provides="Products.GenericSetup.interfaces.EXTENSION"
/>
<!-- -*- extra stuff goes here -*- -->
</configure>
La directive <five:registerPackage ..../> signale à Zope que c’est un module. Cette ligne est importante vu que nous ne sommes pas dans l’espace de nom Products.
La directive <genericsetup:registerProfile .../> permet d’enregistrer un nouveau profil d’extension (option provides) avec le nom default (option name). Les fichiers du profil se trouvent dans le dossier
profiles/default. (option directory).
Dans profiles/default, éditez le fichier metadata.xml comme ceci :
<?xml version="1.0"?>
<metadata>
<version>1000</version>
<dependencies>
<dependency>profile-Products.Collage:default</dependency>
</dependencies>
</metadata>
Le produit Products.Collage utilise bien un profil donc nous pouvons l’installer de cette manière.
Jetez un œil à la seule documentation qui existe sur le support des dépendances de produits dans metadata.xml.
Notez que la best practice est maintenant d’utiliser un entier pour la version du profile : 1000, 1001, 1002 et 2000,
2001 pour une branche parallèle. ArchGenXML ne respecte pas encore cette convention, il faut au moins deux
entiers séparés par un point, ex : 1.0. Ce sera sans doute corrigé dans une prochaine version.
Dans la chaine profile-Products.Collage:default, nous avons le préfixe profile-, le package
au sens Python Products.Collage, le caractère : et le nom du profil à charger default. Ici default
est le name donné lors du genericsetup:registerProfile dans le fichier configure.zcml de
Products.Collage.
11.3.3 Déclaration de formation.policy comme plugin Plone
Plone 3.3 inclut un nouveau système de plugin. Un produit peut être déclaré plugin Plone.
Dans ce cas les fichiers meta.zcml, configure.zcml et overrides.zcml du produit seront lus au démarrage, comme pour les produits dans l’espace de nom Products.
Il n’est plus nécessaire d’ajouter le produit dans l’option zcml de la section [instance] dans
buildout.cfg.
Pour
cela
vérifiez
que
le
egg
src/formation.policy/setup.py :
est
déclaré
comme
plugin
Plone,
avec
dans
entry_points="""
[z3c.autoinclude.plugin]
target = plone
"""
Supprimez formation.policy de l’option zcml de la section [instance] dans buildout.cfg.
Et relancez bin/buildout qui va supprimer le fichier parts/instance/etc/package-includes/001-formation.p
La commande regénère également les metadonnées associées aux eggs en développement, concrètement il regénére le fichier src/formation.policy/formation.policy.egg-info/entry_points.txt qui
déclare le egg comme plugin Plone.
134
Chapitre 11. Création d’un buildout Plone avec ZopeSkel
Plone pour les intégrateurs, Version 1.0.0
À quel moment est lu le fichier configure.zcml de formation.policy ? Il n’y a rien de magique, la
chaine de lecture est maintenant :
– parts/instance/etc/site.zcml
– lecture des fichiers configure.zcml de tous les produits dans l’espace de nom Products
– ~/.buildout/eggs/Products.CMFPlone-4.2.0.1-py2.7.egg/Products/CMFPlone/configure.zcml
qui contient les lignes :
<!-- include plone plugins with z3c.autoinclude -->
<includePlugins
zcml:condition="not-have disable-autoinclude"
package="plone"
file="configure.zcml"
/>
Note : includePlugins
includePlugins est une nouvelle directive fournie par z3c.autoinclude. Ici tous les eggs ayant un
entry point dans le groupe z3c.autoinclude.plugin sont recherchés. Nous avons dans cette directive
package="plone" donc seul les entry points avec target = plone sont gardés. Pour chaque egg, le fichier
configure.zcml (option file de la directive) est lu.
– src/formation.policy/src/formation/policy/configure.zcml
Vous avez le même principe pour les fichiers meta.zcml et overrides.zcml, jetez un œil dans
Products/CMFPlone/meta.zcml et Products/CMFPlone/overrides.zcml.
11.3.4 Installation de collective.ckeditor à l’installation de formation.policy
Pour dépendre de collective.ckeditor, nous ne pouvons pas utiliser cette méthode car
collective.ckeditor utilise un profil.
Plone depuis sa versions 3.3 inclut le package z3c.autoinclude qui permet de ne pas se répéter. Vous pouvez
utiliser la directive :
<includeDependencies package="." />
Cette directive recupère la liste des dépendances du egg. Petit rappel, elle le récupère à partir du fichier
src/formation.policy/src/formation.policy.egg-info/requires.txt qui lui a été généré à partir des informations de setup.py.
Pour chaque dépendance dans l’ordre déclaré, elle va inclure dans l’ordre les fichiers meta.zcml,
configure.zmcl et overrides.zcml s’ils existent.
11.3.5 Configuration de ckeditor pour tous les nouveaux utilisateurs
Vous allez configurer ckeditor comme éditeur par défaut (seulement effectif pour les nouveaux utilisateurs).
Tout d’abord, dans Configuration du site, Modules, activez formation.policy.
Allez dans Configuration du site, ZMI, portal_setup, Snapshots. Créez un snapshot.
Retournez à la racine de la ZMI et cliquez sur portal_memberdata, cliquez sur l’onglet Properties.
Éditez la propriété wysiwyg_editor, mettez la valeur CKEditor.
Retournez dans portal_setup, Snapshots. Recréez un snapshot. Cliquez maintenant sur l’onglet Comparison et
comparez vos deux snapshots. Vous voyez bien que la propriété wysiwyg_editor a été modifiée dans le fichier
memberdata_properties.xml.
Maintenant vous allez exporter cette configuration dans votre policy package. Cliquez sur portal_setup dans le
fil d’arianne, et cliquez sur l’onglet Export, sélectionnez le step MemberData properties, et cliquez sur Export
selected steps.
11.3. Création d’un policy package contenant la configuration du site Plone
135
Plone pour les intégrateurs, Version 1.0.0
Téléchargez l’archive tar.gz proposée, extrayez son contenu dans un dossier temporaire et copiez le fichier
memberdata_properties.xml dans le dossier profiles/default de votre policy package.
Éditez le fichier pour ne laisser que la propriété qui vous intéresse. Vous devez donc avoir au final un fichier
profiles/default/memberdata_properties.xml avec ce contenu :
<?xml version="1.0"?>
<object name="portal_memberdata" meta_type="PlonePAS MemberData Tool">
<property name="wysiwyg_editor" type="string">CKEditor</property>
</object>
Vous pouvez exporter de cette façon presque la totalité des configurations des tools Plone.
Pour être sûr que l’import fonctionne bien, remettez TinyMCE dans wysiwyg_editor en ZMI.
Comme vous avez ajouté un fichier dans le profil, incrémentez la version dans metadata.xml, nous avons donc
la version 1001.
Maintenant si vous redémarrez l’instance et que vous allez dans Configuration du site, Modules, vous pouvez y
lire :
– formation.policy 1.0 Ce module a été mis à jour. L’ancienne version du profil est 1000. La nouvelle version du
profil est 1001. Il n’y a pas de procédure de mise à jour pour ce module. Merci de consulter la documentation
du module pour la mise à jour, ou contacter l’auteur du module.
Il faut en effet écrire un procédure de migration de la version 1000 vers la version 1001.
Ajoutez dans configure.zcml :
<genericsetup:upgradeDepends
title="formation.policy 1000 to 1001"
description="Configure FCKeditor as default wysiwyg editor"
profile="formation.policy:default"
source="1000"
destination="1001"
import_steps="memberdata-properties"
/>
Note : Liste des import steps :
typeinfo, tinymce_settings, atcttool, actions, skins, factorytool, placeful_workflow, componentregistry, controlpanel, placeful_marker, jsregistry, action-icons, cmfeditions_various, reference_catalog, viewlets, content, propertiestool, various, portlets, content_type_registry, plone-final, kssregistry, ploneopenid-various, update-workflowrolemap, sharing, uid_catalog, workflow, cssregistry, contentrules, cookie_authentication, catalog, difftool, plonecontent, toolset, properties, jquerytools-various, tinymce_various, browserlayer, plone-difftool, memberdataproperties, kss_mimetype, caching_policy_mgr, archetypetool, mailhost, rolemap, various-calendar, qiproducts,
archetypes-various
Si vous redémarrez l’instance, vous aurez :
– formation.policy 1.0 Ce module a été mis à jour. L’ancienne version du profil est 1000. La nouvelle version du
profil est 1001. Mettre à jour : formation.policy
Vous n’avez plus qu’à cliquer sur le bouton pour mettre à jour votre module. L’option wysiwyg_editor devrait
maintenant être FCKeditor.
Note : Commitez vos changements :
$ svn add formation/policy/profiles/default/memberdata_properties.xml \
formation/policy/profiles/default/products.xml
$ svn ci -m "Added configuration"
136
Chapitre 11. Création d’un buildout Plone avec ZopeSkel
Plone pour les intégrateurs, Version 1.0.0
11.4 À propos des versions
Le panneau de configuration Modules accessible via Configuration du site est une interface à portal_quickinstaller
et portal_setup.
Elle permet d’installer les produits n’ayant pas de profile avec portal_quickinstaller et les produits avec profile
avec portal_setup.
Les versions affichées sont celles des eggs. La version est récupérée via le module pkg_resources fourni par
setuptools comme vu précédemment.
La version du egg et du profil peuvent être différentes. Il est même conseillé dès le départ d’utiliser des versions
différentes pour la version du produit/egg, et la version du profil.
La version du egg est une version de la forme 1.0.0, 1.0.1, 1.1.0 etc. Si vous modifiez du code Python ou des
templates, incrémentez cette version.
La version du profile est un simple entier qui est incrémenté à chaque fois qu’un fichier est modifié ou ajouté dans
le dossier du profile. Vous incrémenterez généralement aussi la version du egg.
11.5 Releaser le policy package
Maintenant que vous avez un policy package qui fait quelque chose, il est peut-être temps de réaliser une release
pour pouvoir l’utiliser en production. En effet il n’est pas conseillé d’utiliser des produits en mode développement
en production.
La première chose à faire et d’éditer le changelog dans le fichier CHANGES.txt.
Ce fichier texte est au format reST (reStructuredText). Il faut respecter certaines conventions d’écriture pour que
ce fichier puisse être généré ensuite en HTML sur Pypi.
– le soulignage d’un titre doit aller exactement jusqu’au bout du titre.
– les listes doivent avoir une ligne vide au début et à la fin
Pour cette première release, vous allez seulement spécifier la date de la release. Remplacez juste unreleased par
2009-06-11. Remplacez également la puce de la liste, l’étoile par un tiret qui est la convention dans les produits
Plone.
Votre fichier doit ressembler à ceci :
Changelog
=========
1.0 (2009-06-11)
---------------- Initial release
La version dans setup.py doit également être 1.0.
Commitez :
$ svn ci -m "Prepare release"
Maintenant vous allez faire un tag, c’est-à-dire une copie d’une branche qui sera gelée, faire un checkout de ce tag
et pousser la release :
$
$
$
$
$
svn cp http://devagile/Formation/packages/formation.policy/trunk http://devagile/Formation/packa
cd /tmp
svn co http://devagile/Formation/packages/formation.policy/tags/1.0
cd 1.0/
python setup.py register -r mycompany sdist --formats=zip upload -r mycompany
11.4. À propos des versions
137
Plone pour les intégrateurs, Version 1.0.0
Retournez ensuite dans le trunk, incrémentez la version dans setup.py, donc ici 1.1. Et éditez le fichier
CHANGES.txt comme ceci :
Changelog
=========
1.1 (unreleased)
---------------1.0 (2009-06-11)
---------------- Initial release
Et commitez :
$ svn ci -m "Update version after release"
Pour plus d’informations sur la manière de faire une release, voyez les liens suivants :
– http ://grok.zope.org/documentation/how-to/releasing-software
– http ://plone.org/documentation/tutorial/how-to-upload-your-package-to-plone.org
Note : Toutes ces étapes peuvent être faites avec une seule commande fullrelease. Pour cela installez le package
zest.releaser dans votre environnement :
$ workon myenv
(myenv)$ easy_install zest.releaser
Démarrez votre instance Plone où vous avez installé votre pypi. Pour releaser votre package :
(myenv)$ cd src/formation.policy
(myenv)$ fullrelease
La commande fullrelease exécute séquentiellement les commandes prerelease, release et postrelease.
Vous allez dorénavant utiliser cette version releasée plutôt que le egg en développement.
Supprimez formation.policy de l’option develop de la section [buildout] dans buildout.cfg.
Ajoutez aussi le lien vers le Pypi dans find-links :
[buildout]
find-links +=
# ...
http://devagile:8080/site/products/simple
Précisez la version formation.policy = 1.0 dans versions.cfg.
L’external ne sera plus utilisé dans la suite, donc supprimez le également :
$ svn rm src/EXTERNALS.txt
$ svn propdel svn:externals src/
$ svn ci -m "Removed external"
11.6 Repasser au développement
Maintenant vous voulez repasser le egg formation.policy en mode développement pour travailler dessus. Il
faut :
– supprimer la version dans versions.cfg
– ajouter le egg dans l’option develop de buildout.cfg
– reconfigurer l’external pour récupérer le egg dans le dossier src
138
Chapitre 11. Création d’un buildout Plone avec ZopeSkel
Plone pour les intégrateurs, Version 1.0.0
Passer du mode développement au mode production et vice-versa génère beaucoup de bruit dans les logs svn, mais
surtout il faut sans cesse répéter les mêmes actions.
Nous allons utiliser dans la suite une extension buildout nommée mr.developer qui s’occupe de réaliser les 3
étapes décrites ci-dessus en une commande.
11.7 Utilisation de mr.developer pour gérer les composants en développement
L’extension pour zc.buildout mr.developer permet de gérer les composants en développement, et de commuter
facilement d’un composant en développement à sa version “releasée” et inversement.
Transformez le fichier buildout.cfg :
extends =
# ...
sources.cfg
extensions =
# ...
mr.developer
Créez le fichier sources.cfg avec ce contenu :
[buildout]
always-checkout = force
auto-checkout =
formation.policy
[sources]
formation.policy = svn http://devagile/Formation/packages/formation.policy/trunk
Exécutez bin/buildout et mr.developer va s’occuper de faire un checkout de formation.policy dans le
dossier src.
L’extension s’occupe aussi de passer en mode développement formation.policy et de supprimer
formation.policy de versions.cfg pour que ce soit bien la version en développement qui soit utilisée. Cela est fait de manière interne, les fichiers ne sont pas touchés.
mr.developer génère le script bin/develop qui est un script à tout faire.
Exécutez bin/develop help pour obtenir la liste des commandes, qui ressemblent beaucoup à subversion.
bin/develop stat vous liste les checkouts du dossier src, vous dit s’ils sont actifs ou non (c’est-à-dire en mode
développement ou non) et s’ils sont dans l’option auto-checkout ou non. Exécutez bin/develop help stat pour
obtenir la légende.
bin/develop co plonetheme.formation fait un checkout dans le dossier src, et active le egg (le met en mode
développement).
bin/develop activate plonetheme.formation suivi de bin/buildout permet de passer le egg en mode développement.
bin/develop deactivate plonetheme.formation suivi de bin/buildout permet de désactiver le mode développement et d’utiliser la version spécifiée dans versions.cfg.
bin/develop up -vf permet de mettre à jour tous les checkouts. L’option -v permet d’afficher les messages de
subversion. L’option -f permet de forcer un svn up si le checkout est dans un état pas clean.
L’idée est d’ajouter dans auto-checkout les eggs qui ont été modifiés après leur dernière release. Comme ceci
lorsqu’il est temps de livrer votre travail en production, vous savez exactement quels sont les eggs dont vous devez
faire une release.
11.7. Utilisation de mr.developer pour gérer les composants en développement
139
Plone pour les intégrateurs, Version 1.0.0
11.8 Fabric
Créez un environnement isolé Python >= 2.5 avec Fabric d’installé :
$ mkvirtualenv -p /usr/bin/python2.6 --no-site-packages fab
(fab)$ easy_install Fabric
Création d’un script Fabric pour la maintenance de l’instance Plone à distance. Créez un fichier fabfile.py à
la racine de votre buildout :
from fabric.api import run, sudo, env, hosts
env.user = "anthony"
env.hosts = [’devagile’]
def update():
"""Update the checkout of the buildout
"""
run("cd /home/anthony/workspace/plone4; svn up")
def restart():
"""Restart the instance
"""
run("/home/anthony/workspace/plone4/bin/instance restart")
def stop():
"""Stop the instance
"""
run("/home/anthony/workspace/plone4/bin/instance stop")
def start():
"""Start the instance
"""
run("/home/anthony/workspace/plone4/bin/instance start")
def buildout():
"""Run bin/buildout
"""
run("cd /home/anthony/workspace/plone4; bin/buildout")
def up_and_restart():
"""Update the checkout and restart the instance
"""
update()
restart()
def full_up_and_restart():
"""Do the actions stop, update, buildout, start
"""
stop()
update()
buildout()
start()
Pour afficher la liste des commandes disponibles :
$ fab --list
Available commands:
buildout
full_up_and_restart
restart
140
Run bin/buildout
Do the actions stop, update, buildout, start
Restart the instance
Chapitre 11. Création d’un buildout Plone avec ZopeSkel
Plone pour les intégrateurs, Version 1.0.0
start
stop
up_and_restart
update
Start the instance
Stop the instance
Update the checkout and restart the instance
Update the checkout of the buildout
Pour redémarrer l’instance :
$ fab restart
Pour préciser un autre host qui va donc écraser le host configuré globalement dans le fichier :
$ fab stop:host=ailleurs
Vous pouvez aussi créer des commandes avec des paramètres, exécutez fab -h pour consulter la liste des options.
Pour plus de détails, consulter la documentation de Fabric
11.9 Ressources
– http ://plone.org/documentation/tutorial/buildout
– http ://www.sixfeetup.com/swag/buildout-quick-reference-card
11.9. Ressources
141
Plone pour les intégrateurs, Version 1.0.0
142
Chapitre 11. Création d’un buildout Plone avec ZopeSkel
CHAPITRE 12
Déploiement et backup
Author Vincent Fretin
Contributors Thomas Desvenain
Version 1.0.0
Copyright (C) 2010 Vincent Fretin <vincentfretin AT ecreall.com>.
Chacun est autorisé à copier, distribuer et/ou modifier ce document suivant les termes de la licence
Paternité-Pas d’Utilisation Commerciale-Partage des Conditions Initiales à l’Identique 2.0 France accessible à
http ://creativecommons.org/licenses/by-nc-sa/2.0/fr
Le code source présent dans ce document est soumis aux conditions de la « Zope Public License », Version 2.1
(ZPL).
THE SOURCE CODE IN THIS DOCUMENT AND THE DOCUMENT ITSELF 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.
–
–
–
–
–
–
–
–
–
–
–
Définition
Savoir
Profil de déploiement
Supervisor
Support des backups
Cron job pour zeopack et backup
Configuration d’Apache
– Activation de la compression
Configuration des DNS
Installation et configuration de plone.app.caching
– Installation
– Le panneau de configuration de la gestion de cache
– Configuration
– Tester
Ressources
Exercice
12.1 Définition
Le déploiement d’un site Plone requiert des options particulières. Par exemple, nous voulons être sûr qu’une
configuration d’un buildout produit la même chose aujourd’hui ou dans un an.
143
Plone pour les intégrateurs, Version 1.0.0
Vous avez également des environnements différents, donc vous aurez un fichier de configuration par environnement (développement, intégration, production, ...). Chaque fichier principal development.cfg,
deployment.cfg, deployment-backup.cfg étant une extension d’une configuration de base
buildout.cfg intégrant tous les modules applicatifs.
12.2 Savoir
–
–
–
–
–
–
–
Profil buildout de déploiement
Mettre en place un backup de la ZODB
Apache
Varnish
HAproxy
plone.app.caching
Supervisor
12.3 Profil de déploiement
Rappel
Vous pouvez réviser vos connaissances sur buildout en relisant le chapitre Création d’un buildout Plone avec
ZopeSkel.
Vous pouvez récupérer l’exemple complet de buildout sur le collective :
$ git clone git://github.com/collective/collective.trainingmanual.git
$ cd collective.trainingmanual/examples/buildout
Le buildout.cfg du chapitre précédent est légèrement modifié :
buildout.cfg
[buildout]
extends =
http://dist.plone.org/release/4.2.4/versions.cfg
sources.cfg
checkouts.cfg
versions.cfg
tests.cfg
parts +=
instance1
zopepy
backup
omelette
extensions =
mr.developer
buildout.dumppickedversions
versions = versions
allow-hosts =
pypi.python.org
effbot.org
find-links =
#
http://devagile:8080/site/products/simple
http://dist.plone.org/release/4.2.4
eggs +=
Pillow
144
Chapitre 12. Déploiement et backup
Plone pour les intégrateurs, Version 1.0.0
[instance1]
recipe = plone.recipe.zope2instance
user = admin:admin
http-address = 8280
eggs =
#
formation.policy
${buildout:eggs}
environment-vars =
PYTHON_EGG_CACHE ${buildout:directory}/tmp
TMPDIR ${buildout:directory}/tmp
zope_i18n_compile_mo_files true
zcml =
event-log-custom =
<logfile>
level info
path ${buildout:directory}/var/log/${:_buildout_section_name_}.log
max-size 1MB
old-files 720
</logfile>
<logfile>
level error
path ${buildout:directory}/var/log/error.log
max-size 1MB
old-files 720
</logfile>
access-log-custom =
<logfile>
path ${buildout:directory}/var/log/${:_buildout_section_name_}-Z2.log
max-size 1MB
old-files 720
</logfile>
mailinglogger =
# <mailing-logger>
#
level error
#
flood-level 10
#
smtp-server localhost:9025
#
from [email protected]
#
to [email protected]
#
subject [Error on MyApp] [%(hostname)s] %(line)s
# </mailing-logger>
[zopepy]
recipe = zc.recipe.egg
eggs = ${instance1:eggs}
interpreter = zopepy
scripts = zopepy
[backup]
recipe = collective.recipe.backup
keep = 2
keep_blob_days = 14
full = false
gzip = true
[omelette]
recipe = collective.recipe.omelette
eggs =
${instance1:eggs}
${test:eggs}
Créez un fichier deployment.cfg :
deployment.cfg
12.3. Profil de déploiement
145
Plone pour les intégrateurs, Version 1.0.0
[buildout]
extends =
buildout.cfg
parts +=
zeoserver
instance1
instance2
instance3
instance4
varnish-build
varnish-conf
varnish
haproxy
haproxy-conf
supervisor
munin1
munin2
munin3
munin4
eggs +=
plone.app.caching
[hosts]
zeoserver
instance1
instance2
instance3
instance4
varnish
haproxy
supervisor
=
=
=
=
=
=
=
=
127.0.0.1
127.0.0.1
127.0.0.1
127.0.0.1
127.0.0.1
127.0.0.1
127.0.0.1
127.0.0.1
[ports]
zeoserver
instance1
instance2
instance3
instance4
varnish
haproxy
supervisor
=
=
=
=
=
=
=
=
8100
9880
9881
9882
9883
8000
5501
9001
[users]
zope
varnish
haproxy
= vincentfretin
= vincentfretin
= vincentfretin
[zeoserver]
recipe = plone.recipe.zeoserver
zeo-address = ${hosts:zeoserver}:${ports:zeoserver}
[instance1]
shared-blob = on
zeo-client = true
zeo-address = ${zeoserver:zeo-address}
effective-user = ${users:zope}
zodb-cache-size = 30000
zeo-client-cache-size = 128MB
zserver-threads = 1
http-address = ${hosts:instance1}:${ports:instance1}
[instance2]
146
Chapitre 12. Déploiement et backup
Plone pour les intégrateurs, Version 1.0.0
<= instance1
http-address = ${hosts:instance2}:${ports:instance2}
#ftp-address = 9821
[instance3]
<= instance1
http-address = ${hosts:instance3}:${ports:instance3}
[instance4]
<= instance1
http-address = ${hosts:instance4}:${ports:instance4}
[supervisor]
recipe = collective.recipe.supervisor
port = ${ports:supervisor}
user = admin
password = admin
plugins = superlance
supervisord-conf = ${buildout:directory}/etc/supervisord.conf
serverurl = http://${hosts:supervisor}:${ports:supervisor}
programs =
10 zeoserver ${zeoserver:location}/bin/runzeo ${zeoserver:location} true ${users:zope}
20 instance1 ${buildout:bin-directory}/instance1 [console] ${instance1:location} true
30 instance2 ${buildout:bin-directory}/instance2 [console] ${instance2:location} true
40 instance3 ${buildout:bin-directory}/instance3 [console] ${instance3:location} true
50 instance4 ${buildout:bin-directory}/instance4 [console] ${instance4:location} true
60 haproxy ${buildout:bin-directory}/haproxy [-f ${buildout:directory}/etc/haproxy.conf -db] t
70 varnish (autorestart=true) ${buildout:bin-directory}/varnish ${varnish:location} true
eventlisteners =
#
memmon TICK_60 ${buildout:bin-directory}/memmon [-p instance1=600MB -p instance2=600MB -p ins
#
crashmail PROCESS_STATE ${buildout:bin-directory}/crashmail [-m [email protected]]
[varnish-build]
recipe = zc.recipe.cmmi
url = ${varnish:download-url}
[varnish-conf]
recipe = collective.recipe.template
input = ${buildout:directory}/templates/varnish.vcl.in
output = ${buildout:directory}/etc/varnish.vcl
[varnish]
recipe = plone.recipe.varnish
daemon = ${buildout:parts-directory}/varnish-build/sbin/varnishd
bind = ${hosts:varnish}:${ports:varnish}
#backends = ${haproxy-conf:bind}
config = ${varnish-conf:output}
cache-size = 256M
user = ${users:varnish}
mode = foreground
[haproxy]
recipe = plone.recipe.haproxy
#cpu = i686
target = linux26
pcre = 1
[haproxy-conf]
recipe = collective.recipe.template
input = ${buildout:directory}/templates/haproxy.conf.in
output = ${buildout:directory}/etc/haproxy.conf
maxconn = 32000
ulimit-n = 65536
12.3. Profil de déploiement
147
Plone pour les intégrateurs, Version 1.0.0
user = ${users:haproxy}
group = ${users:haproxy}
bind = ${hosts:haproxy}:${ports:haproxy}
[munin1]
recipe = zc.recipe.egg
eggs = munin.zope
scripts = munin=munin1
arguments = ip_address=’${hosts:instance1}’, http_address=’${ports:instance1}’, user="${instance1:
[munin2]
recipe = zc.recipe.egg
eggs = munin.zope
scripts = munin=munin2
arguments = ip_address=’${hosts:instance2}’, http_address=’${ports:instance2}’, user="${instance2:
[munin3]
recipe = zc.recipe.egg
eggs = munin.zope
scripts = munin=munin3
arguments = ip_address=’${hosts:instance3}’, http_address=’${ports:instance3}’, user="${instance3:
[munin4]
recipe = zc.recipe.egg
eggs = munin.zope
scripts = munin=munin4
arguments = ip_address=’${hosts:instance4}’, http_address=’${ports:instance4}’, user="${instance4:
Vous allez créer un utilisateur zope qui servira pour lancer le proxy cache varnish, le load balancer HAproxy et
les instances zope.
$ sudo adduser zope
Note : Si vous avez installé un Plone en root avec l’unified installer, vous pouvez utiliser le compte plone au lieu de
créer un compte zope. Pour cela remplacer zope par plone dans la section [users] du fichier deployment.cfg.
Note : Il faut que les fichiers appartiennent à l’utilisateur zope ou plone ou vous aurez des problèmes pour
démarrer le zeoserver par exemple. Donc vérifiez que les fichiers ont bien le bon propriétaire :
$ sudo chown -R zope:zope votre_buildout
Relancez le buildout en tant qu’utilisateur zope avec bin/buildout -c deployment.cfg.
12.4 Supervisor
Le buildout génère le fichier etc/supervisord.conf.
Tous les processus sont gérés par supervisor.
Pour lancer supervisor, lancez le daemon en tant que super utilisateur qui lancera tous les processus ayant autostart=true (par defaut) :
$ sudo bin/supervisord
(varnish et haproxy ont besoin d’être démarrés en root pour activer certaines options. Les processus sont ensuite
forkés pour utiliser l’utilisateur zope)
Vous pouvez voir l’état des processus avec :
148
Chapitre 12. Déploiement et backup
Plone pour les intégrateurs, Version 1.0.0
$ bin/supervisorctl status
Pour redémarrer un processus par exemple instance1 :
$ bin/supervisorctl restart instance1
Pour stopper : stop, pour démarrer : start.
Pour tout redémarrer :
$ bin/supervisorctl restart all
Pour arrêter supervisor et donc tous les processus :
$ bin/supervisorctl shutdown
12.5 Support des backups
Les backups sont configurés dans la section backup.
[backup]
recipe = collective.recipe.backup
keep = 2
keep_blob_days = 14
full = false
gzip = true
[omelette]
recipe = collective.recipe.omelette
eggs =
${instance1:eggs}
${test:eggs}
Vous avez par défaut les options suivantes :
location = ${buildout-directory}/var/backups
snapshotlocation = ${buildout-directory}/var/snapshotbackups
Plus d’informations sur les options de la recipe
Pour exécuter la sauvegarde toutes les nuits, vous pouvez ajouter un cron job (crontab -e), ici à 3h du matin :
00 3 * * *
/home/zope/MyProject/bin/backup -q
Vous allez voir dans la suite une configuration de buildout qui s’occupe de créer le cron job à votre place.
Pour faire une restauration :
$ bin/restore
Si vous voulez faire un backup de la production pour travailler ensuite en local, utilisez plutôt la commande :
$ bin/snapshotbackup
qui créera une sauvegarde dans le dossier var/snapshotbackups/, utile pour ne pas perturber les sauvegardes normales qui se font la nuit. Vous récupérez ensuite la sauvegarde (les fichiers .fsz et .dat)
via scp et vous placez la sauvegarde dans votre dossier var/snapshotbackups/ en local et exécutez
bin/snapshotrestore en local.
12.5. Support des backups
149
Plone pour les intégrateurs, Version 1.0.0
12.6 Cron job pour zeopack et backup
Voici un exemple de configuration qui étend deployment.cfg pour réaliser un pack de la database avec la
commande bin/zeopack et faire un backup avec la commande bin/backup vue précédemment.
Il synchronise également les dossiers backup/ et log/ sur un autre serveur.
Tout cela est réalisé par un job cron à 4h du matin.
deployment-backup.cfg
[buildout]
extends = deployment.cfg
parts +=
backup-template
backup-schedule
zeopack-schedule
[backup-template]
recipe = collective.recipe.template
inline =
#!/bin/bash
${buildout:bin-directory}/backup -q
rsync -a --delete ${backup:location}/ [email protected]:/home/save/Plone/backups/
rsync -aH --delete ${backup:blobbackuplocation}/ [email protected]:/home/save/Plone/bl
output = ${buildout:bin-directory}/backup.sh
mode = 755
[backup-schedule]
recipe = z3c.recipe.usercrontab
times = 0 4 * * *
command = ${backup-template:output}
# every sunday
[zeopack-schedule]
recipe = z3c.recipe.usercrontab
times = 0 1 * * 0
command = ${buildout:bin-directory}/zeopack -B ${buildout:directory}/var/blobstorage/
Dans cet exemple, la synchronisation se fait sur le serveur de secours/backup serveur1.example.com avec le login
save. Il vous faut préalablement partager une clé publique entre ces deux serveurs pour que la commande rsync
ne demande aucun mot de passe.
Pour utiliser cette configuration, exécutez bin/buildout -c deployment-backup.cfg. Le cron job sera automatiquement ajouté dans le crontab de l’utilisateur.
12.7 Configuration d’Apache
Création d’un certificat autosigné :
$ sudo mkdir -p /etc/apache2/ssl/
$ sudo make-ssl-cert /usr/share/ssl-cert/ssleay.cnf \
/etc/apache2/ssl/server.crt
/etc/apache2/sites-available/devagile :
NameVirtualHost 127.0.0.1
<VirtualHost 127.0.0.1:80>
ServerName devagile
ServerAdmin [email protected]
150
Chapitre 12. Déploiement et backup
Plone pour les intégrateurs, Version 1.0.0
ErrorLog /var/log/apache2/devagile_error.log
TransferLog /var/log/apache2/devagile_access.log
LogLevel warn
RewriteEngine On
RewriteRule ^/(.*) https://ssl.devagile/$1 [NC,R=301,L]
</VirtualHost>
/etc/apache2/sites-available/ssl.devagile (dans la RewriteRule, changez Plone par le nom de
votre site plone) :
NameVirtualHost 127.0.0.1:443
<VirtualHost 127.0.0.1:443>
ServerName ssl.devagile
ServerAdmin [email protected]
ErrorLog /var/log/apache2/devagile_error.log
TransferLog /var/log/apache2/devagile_access.log
LogLevel warn
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/server.crt
#SSLCertificateKeyFile /etc/apache2/ssl/server.key
RewriteEngine On
RewriteRule ^/(.*) http://localhost:8000/VirtualHostBase/https/%{SERVER_NAME}:443/Plone/Virtua
<IfModule mod_proxy.c>
<Proxy proxy:http://localhost:8000>
Order deny,allow
Allow from localhost
</Proxy>
</IfModule>
</VirtualHost>
Activez les sites :
$ a2ensite devagile
$ a2ensite ssl.devagile
Activez les modules :
$
$
$
$
$
a2enmod
a2enmod
a2enmod
a2enmod
a2enmod
ssl
dav
proxy
proxy_http
rewrite
12.7.1 Activation de la compression
Activez le module deflate :
$ a2enmod deflate
et éditez le fichier de configuration /etc/apache2/mods-enabled/deflate.conf (ce n’est plus nécessaire avec Ubuntu 10.04 et plus) :
<IfModule mod_deflate.c>
# these are known to be safe with MSIE 6
AddOutputFilterByType DEFLATE text/html text/plain text/xml
# everything else may cause problems with MSIE 6
12.7. Configuration d’Apache
151
Plone pour les intégrateurs, Version 1.0.0
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/x-javascript application/javascript application/
AddOutputFilterByType DEFLATE application/rss+xml
</IfModule>
Redémarrez Apache :
$ /etc/init.d/apache2 restart
12.8 Configuration des DNS
Pour configurer vos DNS ou pour tester en local, éditez /etc/hosts :
127.0.0.1 devagile ssl.devagile
Redémarrez Firefox pour qu’il relise le fichier.
Vous accéderez à votre site à partir de maintenant avec l’adresse http ://devagile.
12.9 Installation et configuration de plone.app.caching
plone.app.caching propose une interface graphique pour gérer les règles de cache HTTP pour Plone 4. Il
est construit sur z3c.caching, plone.caching et plone.cachepurging.
12.9.1 Installation
plone.app.caching est livré avec Plone mais n’est pas activé. Vous avez donc juste à activer le module dans la
gestion des modules.
12.9.2 Le panneau de configuration de la gestion de cache
Une fois activé vous allez trouver au niveau de la configuration de votre site un lien pour configurer les règles de
cache de votre site.
Cette interface graphique est constituée de trois onglets :
1. Changer la configuration (Change settings) : pour gérer le comportement du cache HTTP
2. Importer une configuration (Import settings) : vous permet d’importer des politiques de cache prédéfinies
3. RAM cache : fournit des informations statistiques sur le cache en RAM et son éventuelle purge.
152
Chapitre 12. Déploiement et backup
Plone pour les intégrateurs, Version 1.0.0
12.9.3 Configuration
Dans notre exemple, nous avons un cache proxy varnish derrière Apache. Pour configurer cette chaine, faire ce
qui suit :
– Cliquer sur Import settings, sélectionner With caching proxy, cliquer sur Import
– Retourner dans Change settings, dans Global settings, cocher Enable caching
– Dans l’onglet Caching proxies, cocher Enable purging
– Ajouter http ://127.0.0.1 :8000 dans les Caching proxies.
– Cocher Virtual host rewriting takes place front of the caching proxy car les adresses sont réécrites par Apache
avec le RewriteRule.
– Dans Externally facing domains, mettre https ://ssl.devagile :443
– Cliquer sur Save
Le mieux après est d’exporter cette configuration dans formation.policy. Pour cela aller dans portal_setup,
export, Export the configuration registry schemata. Ajouter le fichier registry.xml dans votre dossier
profiles/default/. Eventuellement nettoyer ce fichier, seules les clés commencant par plone.app.caching
nous intéressent.
Pour aller plus loin : http ://pypi.python.org/pypi/plone.app.caching
12.9.4 Tester
Vous pouvez tester que votre configuration fonctionne bien en inspectant les requêtes HTTP avec l’extension
Firebug de Firefox par exemple.
12.10 Ressources
– Varnish Guru Meditation on timeout
– Plone Scaling and Performance par Elizabeth Leddy
Apache et Zope, VirtualHostMonster :
– http ://plone.org/documentation/tutorial/plone-apache/vhm/
– http ://plone.org/documentation/how-to/plone-with-apache
– http ://www.zope.org/Documentation/Books/ZopeBook/2_6Edition/VirtualHosting.stx
– http ://wiki.zope.org/zope2/ZopeAndApache
– http ://doc.ubuntu-fr.org/tutoriel/securiser_apache2_avec_ssl
Erreurs PosKey dans vos ZODB storages :
– Checking your ZODB storages for PosKey errors
12.11 Exercice
Geler toutes les versions des eggs utilisés dans le buildout.
Ajout de la recipe collective.recipe.backup dans le buildout pour réaliser un backup régulier de la base de données.
12.10. Ressources
153
Plone pour les intégrateurs, Version 1.0.0
154
Chapitre 12. Déploiement et backup
CHAPITRE 13
Zope External Editor
–
–
–
–
Activation du lien “Modifier avec une application externe”
Installation du client External Editor sous Ubuntu
Installation du client External Editor sous Windows
Problèmes de cache avec l’External Editor
13.1 Activation du lien “Modifier avec une application externe”
L’option Activer la fonctionalité d’éditeur externe doit être coché depuis Configuration du site, puis Edition. Cette
fonctionalité requiert l’installation d’une application sur le poste des utilisateurs. Ils devront aussi l’activer dans
leurs préférences personnelles.
Pour forcer l’utilisation de l’éditeur externe par tous vos utilisateurs, allez dans la Configuration du site, ZMI,
portal_memberdata, cliquez sur l’onglet Properties, et cochez l’option ext_editor.
Cela activera le lien Modifier avec une application externe à côté des liens Envoyer cette page et Imprimer sur les
documents.
Note :
Il y a un bogue dans Plone 3.3.2 qui empêche ce lien de fonctionner. Éditez
~/.buildout/eggs/Plone-3.3.2-py2.4.egg/Products/CMFPlone/skins/plone_scripts/external_ed
et remplacez ’%s/externalEdit_/%s.zem’ par ’%s/externalEdit_/%s’.
13.2 Installation du client External Editor sous Ubuntu
Le système de package d’Ubuntu propose une ancienne version de zopedit. Nous allons quand même l’installer
car il associe le type mime application/x-zope-edit à /usr/bin/zopeedit Nous allons ensuite remplacer le script par
une nouvelle version.
Installez donc zopeedit via le système de packages :
$ sudo apt-get install zopeedit
TODO TODO TODO TODO
http://www.atreal.net/solutions/atrealxnet/collective.zopeedit_1.0.0_all.deb/view
$ sudo dpkg -i collective.zopeedit_1.0.0_all.deb
Ensuite récupérer la dernière version du script Python zopeedit.py sur http ://plone.org/products/zopeexternaleditor-client
155
Plone pour les intégrateurs, Version 1.0.0
et remplacez /usr/bin/zopeedit par celui-ci :
$ sudo cp zopeedit.py /usr/bin/zopeedit
Supprimez éventuellement l’ancien fichier ~/.zope-external-edit et exécutez zopedit dans un terminal
pour recréer un fichier de configuration.
Depuis la version 0.9.11pre1, le support du versionnement des documents est supporté, mais désactivé par défaut.
Pour activer le versionnement des documents, éditez le fichier ~/.zope-external-edit et remplacez :
# Create a new version when the file is closed ?
# version_control = 0
par :
# Create a new version when the file is closed ?
version_control = 1
13.3 Installation du client External Editor sous Windows
Téléchargez la dernière version de l’installateur à partir de http ://plone.org/products/zope-externaleditor-client et
exécutez le.
13.4 Problèmes de cache avec l’External Editor
Le problème suivant peut survenir : l’utilisateur clique sur Modifier avec une application externe, il l’édite, sauvegarde et lorsqu’il reclique sur le lien, il récupère l’ancienne version. Il peut y avoir deux raisons à cela. Le
navigateur n’a pas redemandé le fichier, il l’a pris de son cache. Ou bien le proxy cache a retourné une version
cachée du fichier.
Il semble que l’on ne puisse pas utiliser Cache-Control :no-cache à cause de IE. Voir http ://support.microsoft.com/support/kb/articles/q316/4/31.asp
Pour être sûr que le navigateur redemande toujours le fichier, il faut ajouter le header expires à la requête. Vous
pouvez faire cela avec le module expires d’apache.
Activez le module comme ceci :
$ a2enmod expires
Et configurer apache pour que les fichiers avec le type mime application/x-zope-edit expirent au bout d’une seconde :
$ sudo vi /etc/apache2/httpd.conf
Ajoutez les lignes :
ExpiresActive On
ExpiresByType application/x-zope-edit A1
et rechargez apache :
$ sudo /etc/init.d/apache2 reload
Vous aurez les headers suivants de positionnés :
Cache-Control: max-age=1
Expires: (last modified date +1s)
156
Chapitre 13. Zope External Editor
Plone pour les intégrateurs, Version 1.0.0
Si vous avez le proxy cache varnish, configurez le pour ne pas mettre en cache les fichiers qui possède le type
mime application/x-zope-edit. En effet par défaut le fichier est caché pendant 120s, qui est le défaut ttl (time to
live).
Pour désactiver cela, ajoutez dans votre varnish.vcl, dans vcl_fetch la règle suivante :
if (obj.http.Content-Type == "application/x-zope-edit") {
pass;
}
L’utilisateur doit posséder les permissions WebDAV Lock items et WebDAV Unlock items pour pouvoir verrouiller
le document via External Editor.
13.4. Problèmes de cache avec l’External Editor
157
Plone pour les intégrateurs, Version 1.0.0
158
Chapitre 13. Zope External Editor
CHAPITRE 14
Monitoring avec Munin
– Plugins Zope
– Plugins Varnish
– Ressources
Installez le serveur et le client Munin :
$ apt-get install munin munin-node
À l’installation il active les plugins en fonction de ce qui installé :
apache_processes cpu df df_inode entropy forks if_err_eth0 if_err_eth1 if_eth0 if_eth1 interrupts
Vous aurez les plugins mysql si vous avez mysql-server d’installé. Les plugins actifs sont des liens symboliques
dans /etc/munin/plugins/.
Éditez /etc/munin/munin.conf pour changer host.domain.com (ce n’est pas nécessaire dans Ubuntu 12.04) :
# a simple host tree
[host.domain.com]
address 127.0.0.1
use_node_name yes
Activer d’autres modules si vous le souhaitez :
$ cd /etc/munin/plugins
$ ln -s /usr/share/munin/plugins/fail2ban
$ ln -s /usr/share/munin/plugins/smart_ smart_sda
Tous les fichiers dans /var/lib/munin et /var/log/munin doivent appartenir à l’utilisateur munin (à exécuter seulement si vous n’avez pas de stats) :
$ chown -R munin:munin /var/lib/munin /var/log/munin
Reexécutez cette commande si vous n’avez toujours pas de stats après 15 minutes.
Redémarrez munin-node pour reprendre en compte la configuration :
$ /etc/init.d/munin-node restart
159
Plone pour les intégrateurs, Version 1.0.0
14.1 Plugins Zope
Exemple de buildout de deploiement avec munin :
[buildout]
extends = buildout.cfg
parts +=
zeoserver
instance1
instance2
munin1
[hosts]
zeoserver
instance1
instance2
= 127.0.0.1
= 127.0.0.1
= 127.0.0.1
[ports]
zeoserver
instance1
instance2
= 8100
= 9880
= 9881
[instance-settings]
eggs =
${instance:eggs}
munin.zope
zcml =
${instance:zcml}
munin.zope
products = ${instance:products}
user = ${instance:user}
zodb-cache-size = 8000
zeo-client-cache-size = 300MB
debug-mode = off
zope2-location = ${zope2:location}
zeo-client = true
zeo-address = ${zeoserver:zeo-address}
effective-user = ${users:zope}
environment-vars = ${instance:environment-vars}
zserver-threads = 2
[instance1]
recipe = collective.recipe.zope2cluster
instance-clone = instance-settings
http-address = ${hosts:instance1}:${ports:instance1}
[instance2]
recipe = collective.recipe.zope2cluster
instance-clone = instance-settings
http-address = ${hosts:instance2}:${ports:instance2}
[munin1]
recipe = zc.recipe.egg
eggs = munin.zope
scripts = munin=munin1
arguments = ip_address=’${hosts:instance1}’, http_address=’${ports:instance1}’, user=’${instance1:
[munin2]
recipe = zc.recipe.egg
eggs = munin.zope
scripts = munin=munin2
arguments = ip_address=’${hosts:instance2}’, http_address=’${ports:instance2}’, user="${instance2:
160
Chapitre 14. Monitoring avec Munin
Plone pour les intégrateurs, Version 1.0.0
Installez les liens symboliques :
$ sudo ./bin/munin1 install /etc/munin/plugins instance1
installed symlink /etc/munin/plugins/instance1_zopecache_plonesite
installed symlink /etc/munin/plugins/instance1_zopememory_plonesite
installed symlink /etc/munin/plugins/instance1_zodbactivity_plonesite
installed symlink /etc/munin/plugins/instance1_zopethreads_plonesite
$ sudo ./bin/munin2 install /etc/munin/plugins instance2
installed symlink /etc/munin/plugins/instance2_zopecache_plonesite
installed symlink /etc/munin/plugins/instance2_zopememory_plonesite
installed symlink /etc/munin/plugins/instance2_zodbactivity_plonesite
installed symlink /etc/munin/plugins/instance2_zopethreads_plonesite
Redémarrez munin-node pour reprendre en compte la configuration :
$ /etc/init.d/munin-node restart
14.2 Plugins Varnish
Il existe des plugins munin pour Varnish. Voyez la page sur pypi pour les instructions :
http ://pypi.python.org/pypi/munin.varnish
Les plugins utilisent la commande varnishstat. Cette commande est disponible si vous avez le package
libncurses5-dev lors de la compilation de Varnish.
14.3 Ressources
–
–
–
–
http ://www.debianadmin.com/monitor-servers-and-clients-using-munin-in-ubuntu.htm
http ://www.debianhelp.co.uk/munin.htm
http ://www.debuntu.org/how-to-monitoring-a-server-with-munin
http ://www.debuntu.org/how-to-monitoring-a-server-with-munin-p2
14.2. Plugins Varnish
161
Plone pour les intégrateurs, Version 1.0.0
162
Chapitre 14. Monitoring avec Munin
CHAPITRE 15
PloneFormGen
– Présentation de PloneFormGen
– Qu’est ce que PloneFormGen ?
– Qu’est-ce que l’on peut faire avec PloneFormGen ?
– Installation de PloneFormGen
– Création d’un formulaire
– Les différents composants d’un formulaire
– Les différents types de champs
– Champ de type Checkbox
– Champ de type date et heure
– Champ de type decimal Number
– Champ de type conteneur pour groupe de champs
– Champ de type saisie multiple
– Champ de type sélection multiple
– Champ de type mot de passe
– Champ de type Rating-Scale Field
– Champ de type Rich Label Field
– Champ de type texte mis en forme
– Champ de type sélection
– Champ de type texte court
– Champ de type zone de texte
– Champ de type Whole Number Field
– Les adaptateurs pour scripts
– Les expéditeurs de méls
– Les enregistreurs de données
– La page de remerciement
– Exercice : Réalisation d’un formulaire de sondage
– Composition du formulaire
– Création de l’enregistreur pour récupérer les données au format CSV
– Création d’un script remplissant une base de données.
15.1 Présentation de PloneFormGen
15.1.1 Qu’est ce que PloneFormGen ?
PloneFormGen est un produit permettant la création en ligne de formulaire pour Plone.
On trouvera de la documentation sur http ://plone.org/products/ploneformgen/documentation
163
Plone pour les intégrateurs, Version 1.0.0
15.1.2 Qu’est-ce que l’on peut faire avec PloneFormGen ?
Outre la création à travers le web des formulaires, on pourra stocker les informations qui y seront saisies en vue
de les réutiliser et de les exporter au format csv.
De plus la possibilité de créer des adaptateurs appelant des scripts Python en fin de saisie permettent par exemple
de créer des instances de n’importe quel type de contenu et de les remplir à partir des informations préalablement
saisies.
15.1.3 Installation de PloneFormGen
Pour installer PloneFormGen le plus simple est de l’ajouter à son buildout.
Si vous ne savez pas ce qu’est un buildout vous pouvez lire le chapitre Introduction à zc.buildout et Création d’un
buildout Plone avec ZopeSkel.
Pour cela ajouter Products.PloneFormGen à la section egg de la partie instance :
[instance]
# ...
eggs =
# ...
Products.PloneFormGen
Refaites votre buildout, démarrez, puis ajoutez le produit.
15.1.4 Création d’un formulaire
La création d’un formulaire commence par la création d’un Formulaire dans la liste Ajout d’un élément.
Vous obtenez alors :
Le formulaire est un répertoire qui permet de définir votre formulaire et qui contiendra les éléments qui vont le
constituer.
Remarquez également la barre des propriétés qui va permettre d’accéder à la définition du comportement du
formulaire (onglet Overrides).
Saisissez un titre et une description.
Vous pouvez changer le nom des boutons de soumission ou d’annulation.
Par défaut le comportement d’un formulaire personnalisé est d’envoyer un mail avec les informations saisies par
les utilisateurs. Ce comportement est réalisé par un “adaptateur d’action” nommé “Gestionnaire de mél”. Par la
suite nous verrons comment remplacer cet adaptateur par celui que nous aurons créé.
Vous pourrez aussi définir une page de remerciement qui viendra remplacer celle par défaut qui se contente d’afficher les valeurs saisies dans le formulaire.
Pour des raisons de confidentialité vous pourrez forcer la saisie des informations via une connexion chiffrée à
condition d’avoir configuré votre serveur pour qu’il gère le ssl et donc d’avoir un certificat X509.
Vous pouvez ensuite saisir le prologue et l’épilogue du formulaire.
Enregistrez.
Vous êtes alors redirigé vers votre formulaire qui affiche le titre, la description, le prologue, les champs de saisie
“Votre adresse mél”, “Sujet”, et “Commentaires”, le bouton “Envoyer” et pour finir votre épilogue.
Nous verrons comment ajouter d’autres champs et supprimer ceux existants par défaut.
Si vous avez correctement configuré le mailhost de votre instance Plone, le résultat des formulaires sera envoyé
par mél à destination du contact “Adresse d’expéditeur des courriels pour le site” (modifiable en cliquant sur
Configuration du site puis Envoi de courriels).
164
Chapitre 15. PloneFormGen
Plone pour les intégrateurs, Version 1.0.0
F IGURE 15.1 – Ajout d’un formulaire personnalisé.
15.1. Présentation de PloneFormGen
165
Plone pour les intégrateurs, Version 1.0.0
F IGURE 15.2 – Vue d’un formulaire.
Après avoir appuyé sur Envoyer l’utilisateur est redirigé sur la page de remerciement qui récapitule les valeurs
entrées.
15.1.5 Les différents composants d’un formulaire
Cliquez sur l’onglet édition de votre formulaire puis cliquez sur l’onglet Overrides des propriétés.
F IGURE 15.3 – Onglets d’accès aux propriétés d’un formulaire
Vous accédez alors à la page suivante :
Le champ “Action de validation personnalisée” permet d’exécuter un script personnalisé qui sera appelé après
l’action associée au formulaire (par défaut l’envoi de mél).
Le champ “Action personnalisée du formulaire” permet d’exécuter un script personnalisé en lieu et place de l’envoi
de mél.
Le champ “Script de configuration du formulaire” permet d’exécuter un script avant l’affichage du formulaire pour
par exemple remplir les champs avec des valeurs calculées.
Le champ “Script post-validation” permet d’exécuter un script ayant pour objectif de valider la cohérence des
valeurs saisies les une vis-à-vis des autres ou vis à vis de données extérieures.
Le champ “Injection de contenu d’entête” permet de compléter la page html avec par exemple des liens vers des
ressources css ou javascripts.
La case à cocher “CSRF Protection” permet d’éviter les liens html ou l’insertion de javascript lors de la saisie des
valeurs du formulaire.
166
Chapitre 15. PloneFormGen
Plone pour les intégrateurs, Version 1.0.0
F IGURE 15.4 – Paramétrage du comportement d’un formulaire
15.1. Présentation de PloneFormGen
167
Plone pour les intégrateurs, Version 1.0.0
Plus d’informations sur l’overrides : http ://plone.org/products/ploneformgen/documentation/tutorial/customizingploneformgen
Pour ajouter des champs ou des actions il suffit de cliquer sur l’un des types disponibles depuis le menu Ajout
d’un élément.
F IGURE 15.5 – Ajout d’un champ ou d’une action
Nous allons détailler les éléments de formulaire ci-après.
L’édition graphique et le placement se font après avoir cliqué sur l’onglet QuickEdit.
F IGURE 15.6 – Icône d’accès à la vue de paramétrage
On obtient alors une vue ressemblant à :
Les colonnes “Delete” permettent de supprimer les composants, les colonnes “Edit” permettent d’éditer le composant désigné par la ligne où nous avons cliqué. La colonne “Order” permet par drag and drop de déplacer les
champs pour en changer l’ordre alors que la colonne “Enable” permet d’activer ou non une action ou un page de
remerciement.
168
Chapitre 15. PloneFormGen
Plone pour les intégrateurs, Version 1.0.0
F IGURE 15.7 – Paramétrage des éléments du formulaire
15.1. Présentation de PloneFormGen
169
Plone pour les intégrateurs, Version 1.0.0
15.1.6 Les différents types de champs
Champ de type Checkbox
L’ajout d’une checkbox permet de créer une checkbox.
F IGURE 15.8 – Formulaire de paramétrage d’un champ de type checkbox
Signification des champs :
– Le label du champ correspond au nom du champ il doit être explicite,
– l’aide doit permettre à l’utilisateur de savoir à quoi sert ce checkbox,
– le champ obligatoire s’il est coché oblige l’utilisateur à se prononcer,
– la valeur par défaut (cochée ou non)
– la chaîne de caractères affichée si la checkbox est cochée,
– la chaîne de caractères affichée si la checkbox n’est pas cochée.
Comme pour le formulaire les champs possèdent une propriété “Overrides”.
170
Chapitre 15. PloneFormGen
Plone pour les intégrateurs, Version 1.0.0
F IGURE 15.9 – Propriétés overrides des champs de type checkbox
15.1. Présentation de PloneFormGen
171
Plone pour les intégrateurs, Version 1.0.0
“Expression par défaut” permet de remplir le champ à partir d’une expression TALES évaluée lors du rendu du
formulaire, dans le cas du checkbox le résultat doit être “checked” ou la chaine vide “”.
“Validateur personnalisé” permet de saisir une expression TALES validant la saisie, attention généralement le test
ne concerne que la valeur du champ et non la cohérence du formulaire qui est réalisé dans le test de post validation.
“Enabling Expression” permet de griser ou non le champ à l’affichage en fonction du résultat de l’expression
TALES saisie.
Champ de type date et heure
L’ajout d’un champ date et heure permet de créer une zone de saisie année, mois, jour, heure, minute pouvant être
saisie par calendrier.
La valeur par défaut est saisie sous la forme AAAA MM JJ HH mm où les séparateurs peuvent être ‘ ‘, ‘/’, ‘-‘, ‘.’.
Champ de type decimal Number
Il permet de créer des champs de saisie de nombre flottant.
Champ de type conteneur pour groupe de champs
Il permet de créer un dossier qui contiendra des champs et les groupera visuellement à l’écran.
Remarquer que l’édition des champs contenus par le groupe nécessite de passer par la vue Contenus.
Champ de type saisie multiple
Il permet de créer une zone de saisie de lignes de texte.
Les propriétés Overrides offre en plus un champ “Server-Side Variable” qui permet d’utiliser le contenu du champ
pour passer des valeurs aux adaptateurs d’actions.
Champ de type sélection multiple
Overrides permet via le champ “Vocabulaire des options” de définir une expression TALES permettant de définir
le dictionnaire.
Champ de type mot de passe
Lors de la saisie les lettres seront remplacés par des ‘*’.
Champ de type Rating-Scale Field
Champ de type Rich Label Field
Ce champ permet de faire de la mise en forme.
Champ de type texte mis en forme
Champ de type sélection
Overrides permet via le champ “Vocabulaire des options” de définir une expression TALES permettant de définir
le dictionnaire.
172
Chapitre 15. PloneFormGen
Plone pour les intégrateurs, Version 1.0.0
Champ de type texte court
Champ de type zone de texte
Champ de type Whole Number Field
15.1.7 Les adaptateurs pour scripts
Les adaptateurs de scripts permettent de réaliser des actions sous forme de code Python.
Certaines restrictions de sécurité sont présentes, il n’est donc pas possible d’importer toutes les bibliothèques du
langages.
F IGURE 15.10 – Édition de l’adaptateur de script
Le champ “proxy role” permet d’exécuter le script avec le rôle Administrateur.
Le champ “corps du script” permet de saisir le code Python.
La propriété Overrides permet de définir une “Condition d’exécution” qui si elle n’est pas vérifiée empêche l’exécution du script.
Exemple d’adaptateur créant un document à partir des données saisies :
#
#
#
#
#
#
#
#
#
#
Available parameters:
fields = HTTP request form fields as key value pairs
request = The current HTTP request.
Access fields by request.form["myfieldname"]
ploneformgen = PloneFormGen object
Return value is not processed -- unless you
return a dictionary with contents. That’s regarded
as an error and will stop processing of actions
and return the user to the form. Error dictionaries
15.1. Présentation de PloneFormGen
173
Plone pour les intégrateurs, Version 1.0.0
# should be of the form {’field_id’:’Error message’}
from Products.CMFCore.utils import getToolByName
portal = getToolByName(ploneformgen, ’portal_url’).getPortalObject()
putils = getToolByName(ploneformgen, ’plone_utils’)
title = fields[’topic’]
masaisie = fields[’ma-saisie’]
id=putils.normalizeString(title)
portal.invokeFactory(’Document’, id=id ,title=title,
text=u"\n".join(masaisie))
link=portal[id].absolute_url()
request.RESPONSE.redirect(link)
15.1.8 Les expéditeurs de méls
@TODO
15.1.9 Les enregistreurs de données
@TODO
15.1.10 La page de remerciement
@TODO
15.2 Exercice : Réalisation d’un formulaire de sondage
15.2.1 Composition du formulaire
@TODO
15.2.2 Création de l’enregistreur pour récupérer les données au format CSV
@TODO
15.2.3 Création d’un script remplissant une base de données.
@TODO
174
Chapitre 15. PloneFormGen
CHAPITRE 16
Le theming Plone avec Diazo
Contents :
16.1 Diazo
Author Éric Bréhault (Makina Corpus)
Created 2013-04-17
Version 1.0
16.1.1 Introduction
Avant Diazo, la mise en place d’un design spécifique pour un site Plone se faisait en dérivant le thème de base de
Plone afin d’en modifier certains éléments :
– les images (par exemple le logo, ou le favicon),
– les CSS,
– les templates (template principal, template de portlets ou de viewlets).
Cela impliquait de changer de nombreux fichiers de déclaration, et souvent de ré-écrire certains fichiers Python.
Autrement dit, il fallait rentrer dans le coeur de Plone.
Diazo propose une approche extérieure : il se comporte comme un proxy web (autrement dit un service qui reçoit
des URLs en entrée et renvoi le contenu HTML d’une page produite par un autre système en retour) mais il est
capable d’appliquer dynamiquement un design sur le contenu qu’il renvoie.
16.1.2 Principe
Le design est fourni sous forme d’une arborescence HTML statique classique :
– un ou plusieurs fichiers HTML,
– des images,
– des CSS,
– des JS.
L’application de ce design aux contenus Plone est définie par un fichier de règles nommé rules.xml.
Ce fichier de règles permet de mettre en correspondance des éléments du contenu dynamique (par exemple le titre
du contenu Plone) avec des éléments du thème, c’est-à-dire le modèle HTML statique, (par exemple tel tag H1
ayant l’identifiant “content-title”).
175
Plone pour les intégrateurs, Version 1.0.0
16.1.3 Éditeur en ligne de Diazo
Depuis la version 4.3, Plone propose un éditeur en ligne pour modifier le thème Diazo.
Se rendre dans la Configuration du site, puis dans Modules.
Installer Diazo theme support.
Aller ensuite dans Theming.
On peut créer un nouveau thème et il existe également un exemple minimal qui peut être copié.
Lorqu’on édite un thème, on dispose d’un navigateur qui permet de gérer les fichiers disponibles, et d’un éditeur
texte.
176
Chapitre 16. Le theming Plone avec Diazo
Plone pour les intégrateurs, Version 1.0.0
On dispose également de 2 inspecteurs qui permettent de voir les pages du thème en HTML statiques et les pages
Plone et d’y sélectionner à la souris les éléments qu’on veut mettre en correspondance :
– un clic permet de pointer un élément,
– la touche Esc permet de pointer son père,
– la touche Enter place l’élement dans la sélection courante,
– le bouton Build rule permet de créer une règle à partir des sélections.
16.1.4 Les directives
Le fichier rules.xml peut contenir les directives suivantes.
<theme />
Cette directive applique une page de thème. Exemple :
<theme href="index.html" />
16.1. Diazo
177
Plone pour les intégrateurs, Version 1.0.0
On peut rendre y ajouter des conditions afin de choisir quand utiliser telle ou telle page de thème. Exemple :
<theme href="index.html" css:if-content=".section-front-page" />
<theme href="detail.html" css:if-not-content=".section-front-page" />
Les attributs possibles pour <theme/> sont :
– css:if-content et css:if-not-content qui permettent de tester un sélecteur CSS sur le contenu
Plone,
– if-content et if-not-content qui permettent de tester un sélecteur XPath sur le contenu Plone,
– if qui permet de tester une variable Plone (voir plus loin), par exemple :
<theme href="theme-two-left.html" if="$have_left_portlets"/>
– if-path qui permet de tester des conditions sur la requête courante, exemple :
<theme href="calendrier.html" if-path="/events"/>
Note : pour plus de détails sur les conditions, voir plus bas.
<notheme />
Cette directive désactive le thème diazo. Exemple :
<notheme css:if-content=".template-overview-controlpanel" />
Les attributs possibles pour <notheme/> sont :
– css:if-content et css:if-not-content,
– if-content et if-not-content,
– if,
– if-path.
<replace />
Cette directive remplace un élément du thème par le contenu Plone. Exemple :
<replace theme="/html/head/title" content="/html/head/title"/>
Les attributs possibles pour <replace /> sont :
– theme ou css:theme pour désigner l’élément cible dans le thème HTML,
– content ou css:content pour désigner l’élément source dans le contenu Plone,
– theme-children ou css:theme-children, qui permet de remplacer non pas l’élément désigné, mais
tous les tags qu’il contient,
– content-children ou css:content-children, qui permet d’utiliser non pas l’élément désigné, mais
tous les tags qu’il contient,
– attributes qui permet de remplacer des attributs plutôt que le contenu. Exemple :
<replace theme="/html/body" content="/html/body" attributes="class"/>
–
–
–
–
–
css:if-content et css:if-not-content,
if-content et if-not-content,
if,
if-path,
method (voir plus bas).
<before /> et <after />
Ces deux directives ont un comportement similaire à <replace /> mais plutôt que remplacer l’élément ciblé,
elles vont faire une insertion avant ou après la cible (selon le cas).
Les attributs possibles sont les mêmes que pour <replace /> sauf method.
178
Chapitre 16. Le theming Plone avec Diazo
Plone pour les intégrateurs, Version 1.0.0
<append /> et <prepend />
Ces deux directives ont un comportement similaire à <replace /> mais plutôt que remplacer l’élément ciblé,
elles vont faire une insertion à l’intérieur de l’élement cible à la fin ou au début (selon le cas).
Les attributs possibles sont les mêmes que pour <replace /> sauf method.
<drop />
Cette directive supprime des éléments du thème ou du contenu. Exemples :
<drop css:content="#portal-content .documentByLine" />
<drop css:theme=".lorem-ipsum" />
Note : une même commande <drop /> ne peut pas supprimer à la fois dans le contenu et dans le thème.
Les attributs possibles pour <drop /> sont :
– theme ou css:theme,
– content ou css:content,
– theme-children ou css:theme-children,
– content-children ou css:content-children,
– attributes,
– css:if-content et css:if-not-content,
– if-content et if-not-content,
– if,
– if-path.
<strip />
Cette directive supprime des élements sans supprimer leur contenu. Exemple :
<strip css:content=".portletWrapper" />
va supprimer les tags div de classe portletWrapper mais les tags dl des portlets seront préservés.
Les attributs possibles sont les mêmes que pour <drop />.
<merge />
Cette directive fusionne pour un attribut donné les valeurs provenant du thème et celles provenant du contenu
Plone. Exemple :
<merge attributes="class" css:theme="body" css:content="body" />
Les attributs possibles sont :
– attributes, qui définit les attributs concernés (séparés par des espaces),
– separator, qui indique le séparateur à utiliser pour fusionner les valeurs (par défaut, c’est un espace),
– theme ou css:theme,
– content ou css:content,
– css:if-content et css:if-not-content,
– if-content et if-not-content,
– if,
– if-path.
16.1. Diazo
179
Plone pour les intégrateurs, Version 1.0.0
<copy />
Cette directive permet de copier un attribut venant du contenu Plone sur un élément du thème.
Note : À la différence, de <replace attributes />, <copy /> va fonctionner même si l’attribut n’existe
pas sur l’élément cible (et s’il existe, il est remplacé).
Exemple :
<copy attributes="class" css:theme="body" css:content="body"/>
Les attributs possibles sont :
– attributes, qui définit les attributs concernés (séparés par des espaces),
– theme ou css:theme,
– content ou css:content,
– css:if-content et css:if-not-content,
– if-content et if-not-content,
– if,
– if-path.
16.1.5 L’ordre d’éxecution
Dans certains cas, l’ordre d’éxecution peut avoir des conséquence sur résultat, il est donc bon de le connaître.
L’ordre est le suivant :
1. les directives <notheme />,
2. les directives <theme />,
3. les directives <before /> utilisant theme (et non pas theme-children),
4. les directives <drop /> sont éxécutées ensuite,
5. les directives <replace /> utilisant theme (et non pas theme-children),
6. les directives <strip />,
7. toutes les directives s’appliquant aux attributs,
8. les directives <before />, <replace /> et <after /> utilisant theme-children,
9. les directives <after /> utilisant theme (et non pas theme-children).
Note : si on ajoute method="raw" sur une directive <replace />, on peut utiliser un morceau du contenu
Plone même s’il appartient à un élément supprimé par un <drop />.
16.1.6 Cas des règles sans correspondance
Si une règle utilise un theme (ou css:theme) ne correspondant à aucun élément dans le thème, la règle est
ignorée.
En revanche, si une règle utilise un content (ou css:content) ne correspondant à aucun élément dans le
contenu, la règle sera appliqué (et le contenu sera simplement considéré comme vide).
16.1.7 Les conditions
Conditions sur le contenu
if-content permet d’indiquer une expression XPath, si cette expression trouve une correspondance dans le
contenu, la règle sera appliquée.
180
Chapitre 16. Le theming Plone avec Diazo
Plone pour les intégrateurs, Version 1.0.0
css:if-content fonctionne de la même manière, mais en utilisant une expression CSS plutôt qu’XPath.
Exemple :
<drop css:theme="#publicite" css:if-content=".userrole-authenticated"/>
signifie que l’élément publicite sera supprimé si la classe userrole-authenticated est présente (autrement
dit si l’utilisateur est connecté).
Si on laisse if-content vide, cela revient à utiliser la même valeur que celle de content (ou
css:content). Exemple :
<after css:theme="#topnews dt" css:content=".portlet-topnews dd"
css:if-content=""/>
est équivalent à :
<after css:theme="#topnews dt" css:content=".portlet-topnews dd"
css:if-content=".portlet-topnews dd"/>
Si plusieurs règles concernent le même élement du thème mais ont des conditions différentes, cela va être interprêté
comme un bloc if ... then ... else .... Exemple :
<replace theme-children="/html/body/h1" content="/html/body/h1/text()" if-content="/html/body/h1"/
<replace theme-children="/html/body/h1" content="//h1[@id=’first-heading’]/text()" if-content="//h
<replace theme-children="/html/body/h1" content="/html/head/title/text()" />
va renseigner le tag H1 du body de la façon suivante :
– si le contenu dispose d’un tag h1 comme fils immédiat du body, on en prend le texte,
– sinon, on prend n’importe quel h1 dont l’id est ‘first-heading’,
– et s’il n’y en a pas non plus, on prend la valeur du title.
Conditions sur le chemin de la page
L’attribut if-path permet de conditionner l’application d’une règle en fonction du chemin de la page la page
demandée.
Si la valeur commence par /, on cherche la correspondance à partir du début du chemin. Par exemple :
<drop css:theme="#search" if-path="/blog" />
va s’appliquer pour /blog, /blog/, et /blog/recent.
Si la valeur se termine par /, on cherche la correspondance à partir de la fin du chemin. Par exemple :
<drop css:theme="#search" if-path="recent/" />
va s’appliquer pour /blog/recent/, et /actualites/interne/recent.
Pour une correspondance exacte, il faut mettre / au début et à la fin. Par exemple :
<drop css:theme="#search" if-path="/blog/" />
va s’appliquer pour /blog, et /blog/, mais pas /blog/recent.
S’il n’y a de / ni à la fin ni au début, la correspondance se fait sur n’importe quelle partie du chemin. Par exemple :
<drop css:theme="#search" if-path="interne/recent" />
va
s’appliquer
pour
/interne/recent,
/actualites/interne/recent/images.
/actualites/interne/recent,
et
On peut indiquer plusieurs conditions en les séparant par des espaces :
16.1. Diazo
181
Plone pour les intégrateurs, Version 1.0.0
<drop css:theme="#search" if-path="/blog /agenda" />
Conditions sur des variables
Le fichier manifest.cfg permet de définir des variables dans la section [theme:parameters]. Exemple :
[theme:parameters]
have_left_portlets = python:context.restrictedTraverse(’@@plone’).have_portlets(’plone.leftcolumn’
have_right_portlets = python:context.restrictedTraverse(’@@plone’).have_portlets(’plone.rightcolum
have_both_portlets = python:context.restrictedTraverse(’@@plone’).have_portlets(’plone.leftcolumn’
lang = python:context.restrictedTraverse("@@plone_portal_state/language")()
Note : les modifications du fichier manifest.cfg ne sont pas prises en compte lorsqu’on utilise l’éditeur en
ligne. Il faut les saisir dans l’onglet Paramètres avancés.
L’attribut if (ou if-not) permet d’utiliser ces variables en les préfixant par un $ :
<theme href="theme-two-left.html" if="$have_left_portlets"/>
<theme href="index-fr.html" if="$lang = ’fr’"/>
Groupement et encapsulation de conditions
On peut regrouper des règles dans des balises <rules /> afin de leur appliquer des conditions communes :
<rules
xmlns="http://namespaces.plone.org/diazo"
xmlns:css="http://namespaces.plone.org/diazo/css"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<rules css:if-content=".portlet-alerte">
<after css:theme-children="#header" css:content=".portlet-alerte #message"/>
<before css:theme-children="#main" css:content=".portlet-alerte #warning-icon"/>
</rules>
...
</rules>
Et on peut également mettre ces balises <rules /> en cascade :
<rules css:if-content=".section-Members">
<rules css:if-content=".portlet-alerte">
<after css:theme-children="#header" css:content=".portlet-alerte #message"/>
</rules>
<rules css:if-content=".portlet-todo">
<after css:theme-children="#header" css:content=".portlet-todo #message"/>
</rules>
</rules>
Conditions sur <theme />
On peut fournir plusieurs directives <theme /> :
<theme href="news.html" css:if-content=".section-news"/>
<theme href="members.html" css:if-content=".section-Members"/>
<theme href="index.html"/>
182
Chapitre 16. Le theming Plone avec Diazo
Plone pour les intégrateurs, Version 1.0.0
Les différentes conditions sont testées dans l’ordre où elles sont fournies, et c’est la première qui donne une
correspondance qui est retenue.
En revanche les directives <notheme /> ont toujours la priorité sur les directives <theme /> quel que soit
l’ordre.
Toutes les règles sont appliquées quelle que soit la directive <theme /> retenue sauf si on utilise l’encapsulation :
<rules css:if-content=".section-news">
<theme href="news.html"/>
<copy css:content="h2.articleheading" css:theme="h1"/>
</rules>
16.1.8 Modification du thème à la volée
On peut utiliser une règle pour injecter non pas du contenu mais du HTML statique :
<after theme-children="/html/head" if="$isUserBirthday">
<style type="text/css">
* { font-family: Comic Sans MS; }
</style>
</after>
On peut aussi modifier les éléments du thème. Par exemple :
<replace css:theme="#details">
<dl id="details">
<xsl:for-each css:select="table#details > tr">
<dt><xsl:copy-of select="td[1]/text()"/></dt>
<dd><xsl:copy-of select="td[2]/node()"/></dd>
</xsl:for-each>
</dl>
</replace>
va convertir un tableau en une liste de dt/dd.
Note : dans cet exemple on utilise css:select directement dans l’expression XSL car le pré-compilateur
Diazo va faire la conversion en XPath.
16.1.9 Modification du contenu à la volée
On peut modifier le contenu en utilisant la directive <replace /> :
<replace css:content="div#portal-searchbox input.searchButton">
<button type="submit">
<img src="images/search.png" alt="Search" />
</button>
</replace>
16.1.10 Modification du résultat par <xsl />
Une fois toutes les règles appliquées, le rendu final peut encore être modifié par des directives <xsl />. Par
exemple :
<xsl:template match="input/@type[.=’submit’]">
<xsl:attribute name="class">btn</xsl:attribute>
</xsl:template>
16.1. Diazo
183
Plone pour les intégrateurs, Version 1.0.0
va mettre class="btn" sur les inputs de type submit (btn étant la classe CSS Bootstrap pour les boutons, c’est
un moyen intéressant de satisfaire le markup d’un framework comme Bootstrap sans devoir modifier de l’intérieur
le markup produit par Plone).
Pour ajouter une classe :
<xsl:template match="div/@class[contains(., ’summary’)]">
<xsl:attribute name="class">draggable <xsl:value-of select="."/></xsl:attribute>
</xsl:template>
va ajouter la classe draggable à tous les div portant la classe summary.
Autre exemple, pour transformer les portlets Plone dont le markup est :
<dl>
<dt>titre</dt>
<dd>un item</dd>
<dd>un autre item</dd>
</dl>
en un markup plus simple tel que :
<div>
<h6>titre</h6>
<div>
un item
un autre item
</div>
</div>
(notamment parce qu’il est utile d’avoir un wrapper du contenu du portlet en entier, pour le rendre collapsible par
exemple).
Cette transformation sera assurée par le template xsl suivant :
<xsl:template match="dl[@class[contains(., ’portlet’)]]">
<div class="portlet">
<h6 class="portlet-header">
<xsl:copy-of select="./dt/*" />
</h6>
<xsl:apply-templates select="./dd" />
</div>
</xsl:template>
Note : les directives <xsl /> doivent être placées à la racine de la balises <rules /> principale, et elles sont
appliquées de façon inconditionnelle.
16.1.11 Factorisation
On peut ré-utiliser des règles dans différents thèmes Diazo en utilisant la balise <xi:include />. Exemple :
<xi:include href="standard-rules.xml" />
16.1.12 Insertion de contenu externe
Normalement le contenu est fourni par la page Plone correspondant à l’URL demandée.
Mais en utilisant l’attribut href, on peut demander à une règle d’utiliser une autre page :
184
Chapitre 16. Le theming Plone avec Diazo
Plone pour les intégrateurs, Version 1.0.0
<append css:theme="#right-column" css:content="#content" href="/Plone/Members" />
On peut même aller chercher une page servie par un autre serveur si on active le mode réseau dans les Paramètres
avancés de Diazo :
<append css:theme="#right-column" css:content="#current" href="http://www.plone.org/" />
Note : cela rend le site courant dépendant d’un service extérieur, c’est donc relativement risqué, car si ce serveur
externe n’est pas disponible, le thème est cassé.
On peut utiliser des méthodes d’insertion plus robustes si on dispose d’un frontal web proposant SSI ou ESI :
<after css:theme-children="#left-column" css:content="#portlet"
href="/extra.html" method="ssi"/>
<after css:theme-content="#left-column" css:content="#portlet"
href="/extra.html" method="esi"/>
Insertion d’un fichier HTML du thème
Avec cette même approche, on peut inclure un fichier HTML statique du thème en utilisant son chemin propre :
<append css:theme="#right-column"
css:content="body"
href="/Plone/++theme++montheme/footer.html" />
16.1.13 Bonnes pratiques et techniques standards
Utiliser un framework CSS
Diazo facilite énormément l’adoption d’un framework CSS puisqu’il suffit de déposer les fichiers du framework
directement dans le dossier des ressources statiques du thème.
L’intérêt d’utiliser un framework CSS (comme 960, Bootstrap, Foundation) a déjà été largement démontré, et ne
fait pas l’objet de ce document.
Plone en tant que back-office
Avec Diazo, les fonctionnalités de gestion de contenu de Plone sont utilisées comme un back-office qui alimente
la couche de rendu.
Ainsi on va par exemple ajouter des portlets non pas pour les afficher en tant que portlets mais comme fournisseurs
de contenu à tel élément du thème Diazo.
Un exemple typique est l’utilisation de collective.portlet.sitemap pour fournir les entrées d’un menu
déroulant.
De même, on peut utiliser collective.masonry pour créer des conteneurs de portlets qui permettront l’alimenter tel ou tel bloc du modèle HTML.
Supprimer les commentaires et le Lorem Ipsum
Il peut être utilise de mettre dans les modèles HTML du thème des commentaires ou du texte de remplissage afin
que son affichage en statique soit plus représentatif qu’un markup complètement vierge.
Mais bien entendu on ne souhaite pas les voir apparaître lors du rendu des contenus.
Une technique simple consiste à mettre une classe (par exemple drop) sur ces éléments :
16.1. Diazo
185
Plone pour les intégrateurs, Version 1.0.0
<div id="main-content" class="cell width-1">
<p class="drop">
Suave, mari magno turbantibus aequora ventis,
e terra magnum alterius spectare laborem;
non quia vexari quemquamst jucunda voluptas,
sed quibus ipse malis careas quia cernere suavest.
</p>
</div>
Et on les élimine grâce à une règle de ce type :
<drop css:theme=".drop" />
Cela permet également de supprimer temporairement certaines partie du design.
Supprimer les paragraphes vides
L’éditeur TinyMCE laisse parfois des balises <p/> vides. Cette règle permet de les éliminer :
<drop content="p[not(*) and (not(normalize-space()) or text() = ’ ’)]"/>
Les éléments du <head/>
Le tag <head/> produit par Plone contient de nombreux éléments importants voire obligatorei pour un bon
comportement du site. En général on reprend les éléments suivants :
<replace css:theme="title" css:content="title" />
<before css:theme-children="head" css:content="base" />
<before theme-children="/html/head" content="/html/head/meta" />
<before theme-children="/html/head" content="/html/head/link | /html/head/style | /html/head/comme
<before theme-children="/html/head" content="/html/head/script" />
Note : on ne peut malheureusement pas mettre les scripts à la fin du body car cela casse un bon nombres de scripts
inline.
Accessoirement, on peut souhaiter éliminer le viewport (et s’appuyer sur le comportement du framework CSS
retenu) :
<drop content=’/html/head/meta[@name="viewport"]’/>
On peut aussi alimenter les meta de réseaux sociaux comme Facebook ou Twitter (à moins d’utiliser un module
Plone qui s’en charge bien entendu) :
<after theme-children="/html/head/meta">
<meta property="og:image" content="http://www.monsite.fr/++theme++montheme/images/logo.png" />
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@moncomptetwitter">
</after>
Le snippet javascript pour les statistiques
Le snippet javascript renseigné dans la configuration du site Plone (pour les statistiques GoogleAnalytics, ou
Piwic, ou autre) n’est pas injecté dans le <head/> de Plone donc les règles précédentes ne le traite pas.
Il faut ajouter :
<after theme-children="/html/body" content="/html/body/div[@id=’visual-portal-wrapper’]/div/script
186
Chapitre 16. Le theming Plone avec Diazo
Plone pour les intégrateurs, Version 1.0.0
Créer un tag englobant
Dans cet exemple, on place le titre et la description dans un <div /> englobant :
<replace css:content-children="#content" css:theme-children="#content"/>
<before css:theme-children="#content">
<div id="wrapper">
<xsl:apply-templates css:select=".documentFirstHeading" mode="raw"/>
<xsl:apply-templates css:select=".documentDesciption" mode="raw"/>
</div>
</before>
<drop css:content=".documentFirstHeading"/>
<drop css:content=".documentDesciption"/>
Explications :
– le <before /> insère le tag <div /> et 2 appels xsl permettent d’y ajouter le titre et la description,
– les <drop /> évitent que le titre et la description soient répétés (puisqu’ils figurent dans #content),
– le mode="raw" est nécessaire car les <drop /> sont appliqués avant le <before
css:theme-children /> (en XSLT, le mode raw permet qu’un noeud soit traité plusieurs fois).
Ajouter ou modifier des attributs
Pour un ajout :
<xsl:template match="a">
<xsl:copy>
<xsl:attribute name="target">_blank</xsl:attribute>
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
Explications :
– on copie l’élement,
– on y ajoute l’attribut (ici target),
– on recopie ensuite les attributs existants (y compris target s’il était déjà défini),
– puis on insère les noeuds fils
Pour une modification :
<xsl:template match="img/@src[not(contains(., ’@@’))]">
<xsl:attribute name="src"><xsl:value-of select="." />/@@/images/image/thumb</xsl:attribute>
</xsl:template>
Autre exemple, supprimer une classe CSS (sans supprimer les autres) :
<xsl:template match="form/@class[contains(., ’enableFormTabbing’)]">
<xsl:attribute name="class"><xsl:value-of select="concat(substring-before(., ’enableFormTabbin
</xsl:template>
Debugging
Lorsqu’on fait fonctionner Zope en mode debug (à priori quand on l’a lancé avec bin/ploncectl fg), on
peut ajouter des commandes diazo dans l’url :
– ?diazo.debug=1 (par exemple http://localhost:8080/Plone?diazo.debug=1) va afficher à
l’écran les traces d’éxécution de Diazo (les erreurs, les règles appliquées (en vert), les règles écratées (en rouge))
16.1. Diazo
187
Plone pour les intégrateurs, Version 1.0.0
– ?diazo.off=1 (par exemple http://localhost:8080/Plone?diazo.off=1) va désactiver
Diazo, de manière par exemple à pouvoir inspecter la page non thémée plus facilement.
Accès spécial non-thémé
La configuration avancée de Diazo (Configuration du site / Theming / Advanced Settings) permet de déclarer des
noms de domaine pour lesquels Diazo ne sera pas activer.
Par défaut, il y a 127.0.0.1.
Ainsi on peut, si on le souhaite, fournir aux conributeurs un accès “back-office” sans theming.
16.2 Produit de skin
Author Éric Bréhault (Makina Corpus)
Created 2013-04-17
Version 1.0
16.2.1 Introduction
La création d’un thème Diazo dans l’éditeur en ligne n’est pas une solution très solide, car même si on est en
mesure d’exporter le design dans une archive (et donc de pouvoir en faire une sauvegarde, ou bien de faire un
déploiement d’un serveur de développement vers un serveur de production), il est plus sain de gérer son thème
dans un véritable produit Plone (qui pourra être géré dans Git ou SVN, qui pourra facilement être déployé par
buildout, etc.).
D’autre part, cela permet d’aller au-delà de ce que propose Diazo, comme par exemple, surcharger des composants
de Plone, créer des viewlets, des portlets, changer les attributs du profil utilisateur, etc.
188
Chapitre 16. Le theming Plone avec Diazo
Plone pour les intégrateurs, Version 1.0.0
16.2.2 Créer un produit pour son thème Diazo
Créer le module
Pour créer un produit de thème vierge, on va utiliser ZopeSkel qui permet d’initialiser des modules Python en se
basant sur un modèle.
On va utiliser le modèle standard plone.
Aller dans src/, et lancer la commande :
$ ../bin/zopeskel plone
Donner un nom au module (par exemple : nomprojet.theme). Et garder les choix par défaut sauf pour :
Register Profile (Should this package register a GS Profile) [False]: True
Le module est créé dans src/nomprojet.theme.
Ajouter ce nouveau module dans buildout.cfg :
develop =
...
src/nomprojet.theme
eggs =
...
nomprojet.theme
Et faire tourner le buildout :
$ bin/buildout -Nv
Ajouter le thème Diazo
Créer un dossier pour les ressources Diazo :
$ mkdir src/nomprojet.theme/nomprojet/theme/static
Télécharger le thème créé avec l’éditeur en ligne Diazo et le dé-zipper dans ce dossier.
Modifier le configure.zcml pour déclarer le dossier static :
<configure
...
xmlns:plone="http://namespaces.plone.org/plone"
>
...
<plone:static name="nomprojet.theme" directory="static" type="theme" />
...
</configure>
16.2. Produit de skin
189
Plone pour les intégrateurs, Version 1.0.0
Compléter le profile GenericSetup
Dans src/nomprojet.theme/nomprojet/theme/profiles/default/, il faut :
– Ajouter la dépendance avec plone.app.theming dans metadata.xml :
<?xml version="1.0"?>
<metadata>
<version>1000</version>
<dependencies>
<dependency>profile-plone.app.theming:default</dependency>
</dependencies>
</metadata>
– Déclarer le thème, en créant theme.xml :
<?xml version="1.0"?>
<theme>
<name>nomprojet.theme</name>
<enabled>true</enabled>
</theme>
On peut alors lancer Zope, et installer le nouveau produit pour activer le thème.
16.2.3 Surcharger la skin de Plone
Diazo permet de contrôler le rendu global du site.
Mais si on souhaite modifier le rendu d’éléments situés en profondeur qui ne sont pas forcément accessibles par un
sélecteur CSS précis ou bien une image (par exemple, le portrait par défaut des membres, defaultUser.png)
qui sont fournis par la skin de Plone, il faut surcharger la skin de Plone.
Note : On peut le faire depuis la ZMI en allant dans ./portal_skins et en utilisant le bouton Customize
qui place la ressource dans le dossier custom.
Pour les surcharger dans les sources de notre produit de thème, la méthode est la suivante :
Créer un dossier src/nomprojet.theme/nomprojet/theme/skins/nomprojet_custom
et y placer les ressources désirées.
Déclarer ce dossier dans le configure.zcml :
<configure
...
xmlns:cmf="http://namespaces.zope.org/cmf"
>
...
<cmf:registerDirectory name="nomprojet_custom"/>
</configure>
Et le placer en première position par rapport aux autres layer de skins en créant
src/nomprojet.theme/nomprojet/theme/profiles/default/skins.xml :
<?xml version="1.0"?>
<object name="portal_skins" allow_any="False" cookie_persistence="False" default_skin="nompro
<object name="nomprojet_custom"
meta_type="Filesystem Directory View"
directory="nomprojet.theme:skins/nomprojet_custom"/>
<skin-path name="nomprojet.theme" based-on="Sunburst Theme">
190
Chapitre 16. Le theming Plone avec Diazo
Plone pour les intégrateurs, Version 1.0.0
<layer name="nomprojet_custom"
insert-after="custom"/>
</skin-path>
</object>
On peut alors relancer Zope et ré-installer le produit depuis la configuration du site, et les éléments
du dossier nomprojet_custom prendront la main sur la skin de Plone (ou sur celle de tout autre
produit installé).
16.2.4 Surcharger des BrowserViews de Plone avec jbot
De très nombreux composants de l’IHM de Plone sont fournis non pas par une skin mais par des BrowserViews.
C’est le cas notamment des viewlets (qu’on peut voir lorsqu’on appelle l’url ./@@manage-viewlets).
Note : Pour les surcharger depuis la ZMI, on peut aller dans ./portal_view_customizations.
Pour les surcharger dans les sources de notre produit de thème, la méthode la plus simple est d’utiliser z3c.jbot
(Just a Bunch of Templates).
Tout d’abord il faut l’ajouter dans buildout.cfg :
eggs =
...
z3c.jbot
Et faire tourner le buildout :
$ bin/buildout -Nv
Ensuite créer un dossier src/nomprojet.theme/nomprojet/theme/static/overrides.
Déclarer ce dossier comme dossier jbot en :
– modifiant le configure.zcml :
<configure
...
xmlns:browser="http://namespaces.zope.org/browser"
>
...
<include package="z3c.jbot" file="meta.zcml" />
<interface name="nomprojet.theme"
interface="nomprojet.theme.interfaces.IThemeSpecific"
type="zope.publisher.interfaces.browser.IBrowserSkinType"
/>
<browser:jbot directory="static/overrides" />
</configure>
– créant interfaces.py :
from plone.theme.interfaces import IDefaultPloneLayer
class IThemeSpecific(IDefaultPloneLayer):
"""Marker interface that defines a Zope 3 browser layer and a plone skin marker.
"""
– et déclarant la layer dans le profil en créant src/nomprojet.theme/nomprojet/theme/profiles/default/brows
16.2. Produit de skin
191
Plone pour les intégrateurs, Version 1.0.0
<?xml version="1.0"?>
<layers>
<layer name="nomprojet.theme" interface="nomprojet.theme.interfaces.IThemeSpecific"/>
</layers>
Ensuite il faut placer dans le dossier src/nomprojet.theme/nomprojet/theme/static/overrides
les templates qu’on veut surcharger en les renommant avec leur chemin complet vers l’original.
Par exemple, pour surcharger colophon.pt de plone.app.layout, sachant que ce template se trouve dans
viewlets, il faut le nommer plone.app.layout.viewlets.colophon.pt.
Il faut ensuite relancer Zope et ré-installer le produit depuis la configuration du site.
16.2.5 Gérer les registres CSS et JS
Pour des raisons de performances, il est toujours préférable de minimiser le nombre de JS et de CSS chargés par
les pages de son site.
Cela réduit le nombre de requêtes, et cela optimise l’effet de cache.
Pour cela, Plone propose deux registres, portal_javascript et portal_css, qui permettent de :
– déclarer les ressources qu’on souhaite charger,
– les ordonner,
– éventuellement, fournir des conditions qui déterminent quand on doit charger la ressources.
À partir de ces informations, Plone va injecter les tags correspondants (<script>, <link>, etc.) dans le
<head> des pages produites, et si Zope ne tourne pas en mode debug, les différents fichiers vont être (autant
que possible) regroupées et compressés.
Il est donc important que les CSS et JS principaux du produit de thème soient gérés par ce biais.
Il faut va donc les enlever des modèles HTML (pour ne pas les charger en double).
Puis, les déclarer dans ces registres.
Pour cela, il faut créer un fichier src/nomprojet.theme/nomprojet/theme/profiles/default/jsregistry.xml
<?xml version="1.0"?>
<object name="portal_javascripts">
<javascript id="++theme++nomprojet.theme/js/theme.js"
cacheable="True"
compression="none"
cookable="True"
enabled="True"
expression="request/HTTP_X_THEME_ENABLED | nothing"
inline="False"
insert-after="++resource++collective.js.leaflet/leaflet.js"
/>
</object>
Et un fichier src/nomprojet.theme/nomprojet/theme/profiles/default/cssregistry.xml :
<?xml version="1.0"?>
<object name="portal_css">
<stylesheet
id="++theme++nomprojet.theme/css/theme.css"
applyPrefix="1"
media=""/>
<stylesheet
192
Chapitre 16. Le theming Plone avec Diazo
Plone pour les intégrateurs, Version 1.0.0
id="++theme++nomprojet.theme/bootstrap/css/bootstrap.css"
applyPrefix="1"
media=""/>
</object>
Il faut ensuite relancer Zope, et ré-installer le produit depuis la configuration du site.
Note : l’expression request/HTTP_X_THEME_ENABLED | nothing renvoie True uniquement si on utilise Diazo (cele permet de ne charger la ressource que lorsque le thème Diazo est actif et pas quand affiche Plone
en direct).
Il faut prendre garde à l’ordre des ressources et aux conditions : les ressources sont concaténées les unes après les
autres dans l’ordre où elles sont placées tant que leurs conditions sont les mêmes.
Si une ressource a une condition différente, cela va fermer le regroupement courant et créer un nouveau groupe.
Donc si on veut avoir le moins de ressources à charger à la fin, il faut veiller à :
– mettre le moins de conditions que possible,
– si on en met, essayer d’en avoir le moins de différentes que possibles,
– et ré-ordonnancer de manière à ce que les conditions identiques soient consécutives.
En ce qui concerne les JS ou CSS qui ne sont pas utilisés globalement mais uniquement dans un modèle HTML
spécifique, il peut être au contraire pertinent de ne pas les mettre dans les registres et de les laisser en dur dans le
modèle HTML en question.
Note : quand on utilise un framework CSS responsive, il est souvent nécessaire de désactiver la
CSS mobile.css de Plone qui risque de produire de mauvais résultats . Pour cela on ajoute ceci à
cssregistry.xml :
<stylesheet id="mobile.css" enabled="False" />
16.2. Produit de skin
193
Plone pour les intégrateurs, Version 1.0.0
194
Chapitre 16. Le theming Plone avec Diazo
CHAPITRE 17
Ecrire des scripts Plone : bases
Author Thomas Desvenain
Created 2013-02-28
Version 0.1.0
– Introduction
– Mon premier script
– Créer un script
– Le script par défaut
– Mon premier script
– Renvoyer un script en HTML
– Naviguer dans les documents par script
– Comment connaître la liste des méthodes disponibles sur un objet ?
– Protéger le script
– Suivi des modifications sur un script
– Créer et gérer des contenus par script
– On continue notre script
– Copier des contenus
– Publier des contenus
– Les tools
– Déplacer des contenus
– Modifier des contenus / retrouver la valeur d’un champ
– Supprimer des contenus
– Connaître et exploiter les informations utilisateur
– Accéder aux propriétés de l’utilisateur
– Mettre en forme les dates / les vues standard
– Modifier les propriétés de l’utilisateur
– Exporter en csv des informations utilisateurs
– Récupérer les rôles d’un utilisateur
– Vérifier un privilège de l’utilisateur connecté
– Utiliser le catalogue de Plone
– Une première requête catalogue
Copyright (C) 2013 Thomas Desvenain <thomas.desvenain AT gmail.com>.
Chacun est autorisé à copier, distribuer et/ou modifier ce document suivant les termes de la licence
Paternité-Pas d’Utilisation Commerciale-Partage des Conditions Initiales à l’Identique 2.0 France accessible à
http ://creativecommons.org/licenses/by-nc-sa/2.0/fr
Le code source présent dans ce document est soumis aux conditions de la « Zope Public License », Version 2.1
(ZPL).
195
Plone pour les intégrateurs, Version 1.0.0
THE SOURCE CODE IN THIS DOCUMENT AND THE DOCUMENT ITSELF 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.
17.1 Introduction
Zope permet aux utilisateurs d’écrire en ligne des scripts. L’idée de départ était de permettre de réaliser de véritables applications en ligne. L’idée est devenue obsolète car elle ne permettait pas une qualité de déploiement et
d’organisation du code telle qu’on peut l’avoir aujourd’hui avec les eggs. Il reste que grâce à cela on a hérité de
fonctions disponibles suffisamment étendues pour rendre de grands services à un webmaster.
Ce chapitre permettra à un développeur débutant de comprendre comment écrire de petits scripts pour traiter du
contenu d’un site Plone.
A la fin de cette formation, une personne qui n’a que quelques bases de programmation sera capable de réaliser
des tâches scriptées comme par exemple :
-
déplacer toutes les actualités créées dans le site dans un seul et même dossier,
créer des sous-dossiers dans un ensemble de dossiers,
compter le nombre de documents récemment ajoutés dans une partie du site,
produire un fichier csv reprenant le titre, l’auteur et la date de création de tous les document
etc.
Ce sera l’occasion d’aborder des notions essentielles telles que :
-
la structure de la ZODB,
les tools,
les types de contenu,
le catalogue de Plone.
Dans le chapitre suivant : Ecrire des templates Plone : bases, nous valoriserons visuellement des données et des
indicateurs extraits à l’aide de scripts dans une template.
17.2 Mon premier script
Nous allons écrire un premier script qui affiche simplement une “Table des matières” de votre site, en affichant la
liste des dossiers à la racine, et la liste des sous-dossiers.
17.2.1 Créer un script
Warning : Attention ! Comme pour toute opération, ne testez jamais vos scripts en production, essayez-les
d’abord sur un serveur de tests !
Pour créer un script, vous avez besoin d’aller dans la ZMI : : - connectez-vous en administrateur, - allez dans la
configuration du site, - cliquez sur Interface d’administration de Zope (ZMI)
Vous entrez dans le backoffice de Zope : la Zope Management Interface. A partir de là, vous pouvez naviguer dans
vos données, et consulter les ‘tools’ (sur lesquels nous reviendrons plus tard).
Vous pouvez ajouter ici votre premier script. Pour cela, sélectionnez Script dans la sélection d’ajout, en haut à
droite, et cliquez sur ‘Add’.
Appelez le script ‘table_of_contents’ et ajoutez-le.
Vous arrivez sur une page d’édition permettant d’éditer le code du script.
196
Chapitre 17. Ecrire des scripts Plone : bases
Plone pour les intégrateurs, Version 1.0.0
Note : Pour éditer vos scripts, nous vous conseillons d’utiliser Zope External Editor. Une fois celui-ci installé,
vous éditez le script en cliquant sur le crayon à côté du nom du script. Vous bénéficiez ainsi de tous les avantages
d’un éditeur de texte (notamment la coloration syntaxique), largements supérieurs à un simple textarea pour vous
aider à saisir vos lignes de code...
17.2.2 Le script par défaut
Par défaut, un script par défaut est créé qui affiche simplement des informations sur le script lui-même. Vous
pouvez le tester en cliquant sur l’onglet “test” (pour plus de commodité ouvrez-le dans une nouvelle fenêtre).
Nous allons commenter ce script.
from Products.PythonScripts.standard import html_quote
La première chose que vous notez, c’est qu’il est possible de réaliser des imports. Attention, les imports possibles
sont réservés à certains modules, classes et fonctions. Pour des raisons de sécurité, en effet, seule une partie de
l’API de zope est disponible en ligne. Les modules python en dehors de Zope ainsi que de nombreuses fonctions
de Zope sont indisponibles. Vous êtes ainsi assurés, par exemple, que les managers de vos sites n’auront pas accès
à des fonctions du système (os, sys, etc). Quand vous essayerez d’utiliser ou d’importer un élément non autorisé,
vous aurez une erreur “Privilèges insuffisants”
request = container.REQUEST
response = request.response
Un certain nombre de noms sont disponibles de base dans un script. Ils concernent des éléments permettant de
retrouver le contexte du script :
– container : le conteneur du script,
– context : le contexte d’exécution du script (cf plus loin),
– script : l’objet script lui-même.
print "This is the", script.meta_type, ’"%s"’ % script.getId(),
...
return printed
return printed fait que le script va renvoyer l’ensemble du texte qui a été imprimé durant l’exécution du
script.
17.2.3 Mon premier script
Nous allons écrire un premier script permettant d’afficher une table des matières du site.
folders = container.values()
for folder in folders:
if folder.portal_type == ’Folder’:
print folder.Title(), "\n"
for element in folder.values():
print "
", element.Title(), "\n"
return printed
Vous savez peut-être déjà que dans Zope, les éléments du site (documents, dossiers, etc) sont également des objets,
des instances de classes qui fournissent des méthodes. Ces méthodes permettent de retrouver des informations sur
le contenu de l’objet ou d’effectuer des traitements.
Ici, la méthode “Title” permet de récupérer le titre du document ou du dossier.
Les données d’un élément sont, quant à elles, des attributs de cet objet.
17.2. Mon premier script
197
Plone pour les intégrateurs, Version 1.0.0
17.2.4 Renvoyer un script en HTML
Sachez que votre script peut renvoyer du HTML. A priori vous n’aurez jamais besoin de cela car vous écrirez une
template. Vous pouvez néanmoins tester le script suivant :
folders = container.values()
for folder in folders:
if folder.portal_type == ’Folder’:
print "<h1>", folder.Title(), "</h1>"
print "<ul>"
for element in folder.values():
print "<li>", element.Title(), "</li>"
print "</ul>"
return printed
Votre script peut aussi renvoyer tout autre format texte, comme par exemple un fichier csv. Nous verrons un
exemple plus loin. Mais la plupart du temps, un script sert à renvoyer une structure python : une liste d’objets, un
dictionnaire, etc. Dans ce chapitre, à des fins illustratives nous écrivons des scripts qui retournent du texte, mais
dès que nous saurons écrire des templates, nous utiliserons les scripts de manière plus habituelle.
17.2.5 Naviguer dans les documents par script
La méthode values() permet de récupérer la liste des contenus d’un dossier. La méthodes keys() permet de
récupérer la liste des identifiants des contenus du dossier. Les dossiers se comportent comme des dictionnaires et
comme des objets. Si vous avez un dossier ‘documents’ dans le container, vous pouvez y accéder par l’expression :
container[’documents’] ou container.documents. Ainsi, le bloc de code suivant est strictement
identique au précédent.
for folder_id in container.keys():
if container[folder_id].portal_type == ’Folder’:
print container[folder_id].Title(), "\n"
for subfolder_id in container[folder_id].keys():
print "
", container[folder_id][subfolder_id].Title(), "\n"
return printed
Note : sur un objet, la méthode getParentNode() et l’attribut aq_parent permettent de récupérer le parent.
17.2.6 Comment connaître la liste des méthodes disponibles sur un objet ?
Il est indispensable d’apprendre à retrouver quelles sont les méthodes disponibles sur un objet. Il existe pour cela
un module : Products.DocFinderTab, qui ajoute, dans la ZMI, un onglet ‘Doc’ sur chaque objet. Cet onglet permet
de retrouver la liste des classes de base de l’objet et les méthodes disponibles.
17.2.7 Protéger le script
Warning : Très important ! Le script que vous venez de créer est disponible pour tous les utilisateurs du site,
même non connectés. Il est extrêmement dangereux de ne pas protéger un script, en particulier si celui-ci opère
des traitements sur .
Pour exécuter un script, il faut avoir la permission ‘View’ sur l’objet. Allez dans l’onglet ‘Security’ de votre script,
ligne ‘View’ et sélectionnez ‘Manager’ uniquement.
198
Chapitre 17. Ecrire des scripts Plone : bases
Plone pour les intégrateurs, Version 1.0.0
17.2.8 Suivi des modifications sur un script
L’onglet History, sur un script, vous permet d’afficher la liste des modifications effectuées, de réaliser des comparatifs et de récupérer des anciennes versions.
17.3 Créer et gérer des contenus par script
Imaginons que vous utilisez un site Plone pour gérer l’intranet des services de votre entreprise. Vous avez créé un
dossier pour chaque service. Vous souhaitez que chaque service rassemble ses factures par mois dans un dossier.
Tant qu’à faire, autant que la structure de ce dossier soit la même dans chaque service, à savoir “factures/2013/02”
(“Factures / 2013 / Février 2013” pour le titre).
Vous vous dites que vous pourriez écrire un script que vous passerez chaque mois et qui créera les bons dossiers.
Et vous avez raison, car Plone permet de faire cela très facilement !
Voici un premier script qui va créer le dossier factures dans chaque dossier principal à la racine de votre Plone.
Créez un script generate_invoices à la racine de votre ZMI :
for folder in container.values():
if folder.portal_type != ’Folder’:
continue
# on boucle sur la liste des contenus dont le portal_type est ’Folder’
if ’factures’ not in folder: # on vérifie que l’object identifié ’factures’ n’existe pas déjà
folder.invokeFactory(’Folder’, ’factures’, title="Factures", description="Factures du serv
print "factures créé dans %s" % folder.absolute_url() # %s est remplacé dans la chaine par
return printed
Testez ensuite le script (pour qu’il fonctionne, vous devez avoir quelques dossiers à la racine de votre site Plone).
La première ligne permet de boucler sur la liste des contenus. Ensuite, si on voit que le contenu n’est
pas un dossier, on reprend la boucle (mot clé continue). if ’factures’ not in folder permet
de vérifier qu’il n’y a pas dans le dossier un élément dont l’identifiant est ‘factures’. Cela équivaut à if
’factures’ not in folder.keys() ou if not hasattr(folder, ’factures’) ou encore
if not folder.has_key(’factures’).
folder.invokeFactory(’Folder’, ’factures’, title="Factures",
description="Factures du service") est l’expression la plus intéressante ! La méthode invokeFactory sur un dossier permet ici de créer un sous-contenu de portal_type ‘Folder’ avec un identifiant ‘factures’,
un titre : ‘Factures’ et une description : “Factures du service”.
Les arguments nommés (keyword args, ou kwargs) permettent de donner une valeur aux champs lors de la création
de l’objet.
La méthode invokeFactory vérifie les droits d’ajouts. Si l’utilisateur qui ajoute le script n’a pas le droit
d’ajouter ce type de contenu, ou si le script essaye d’ajouter un contenu interdit à cet endroit (restriction), le script
renverra une erreur de privilège.
Note : Rappel sur les types de contenu
Les types de contenus sont ce qui structure l’information sous Plone. Il y a deux “espèces” de types de contenu :
les types de contenu “Archetypes” et les types de contenu “Dexterity”. Les seconds ont la particularité de pouvoir
être définis en ligne. Les premiers sont plus anciens et, à l’heure où ces lignes sont écrites, les types de contenu de
base de Plone sont encore des contenus “Archetypes”.
Qu’il soit Archetypes ou Dexterity, un type de contenu est composé de deux choses : une factory et un schema.
La factory, disponible dans le tool portal_types de la ZMI, contient des informations sur le type de contenu telles
que son nom, sa description, les sous-contenus autorisés, les modes d’affichage. Le schéma contient la liste des
champs du type de contenu, qui détermine les informations que peuvent contenir les contenus de ce type. Il permet
de générer les formulaires d’ajout et de modification.
17.3. Créer et gérer des contenus par script
199
Plone pour les intégrateurs, Version 1.0.0
Pour aller plus loin, vous pouvez essayer de générer par script des contenus créés via dexterity (Pour créer des
types de contenus Dexterity, allez dans Configuration du site > Types de contenu Dexterity).
absolute_url() est une méthode qui permet de récupérer l’url de l’objet. Un autre méthode très utile est la
méthode getPhysicalPath() qui permet de récupérer (sous la forme d’un tuple), le chemin d’accès zope à
l’objet.
17.3.1 On continue notre script
Nous enrichissons maintenant notre script pour qu’il crée des dossiers en fonction du mois actuel.
from DateTime import DateTime
today = DateTime()
year = str(today.year())
month = "%02d" % today.month() # permet d’avoir des affichages du type "01", "02", ... "10", "11",
for folder in container.values():
if folder.portal_type != ’Folder’:
continue
# on boucle sur la liste des contenus dont le portal_type est ’Folder’
if ’factures’ not in folder: # on vérifie que l’object identifié ’factures’ n’existe pas déjà
folder.invokeFactory(’Folder’, ’factures’, title="Factures", description="Factures du serv
print "’factures’ créé dans %s" % folder.absolute_url()
if year not in folder.factures:
folder.factures.invokeFactory(’Folder’, year, title=year, description="Factures de l’année
month_id = ’%s-%s’ % (month, year)
if month_id not in folder.factures[year]:
folder.factures[year].invokeFactory(’Folder’, month_id, title=month_id)
print "%s créé dans %s" % (month_title, folder.factures[year].absolute_url())
return printed
DateTime est un module de dates spécifique à zope que l’on peut utiliser dans les scripts. Il prend en paramètre
soit rien (auquel cas l’objet correspond à la date du jour) soit une date au format (“YYY/MM/DD”).
17.3.2 Copier des contenus
Imaginons que vous ayez créé un modèle excel de synthèse annuelle “factures-synthese-anuelle.ods” des factures
que vous avez stocké dans un dossier “modeles”. Vous souhaitez qu’il soit copié à chaque fois dans le dossier de
factures annuel. C’est possible ! Vous allez ajouter dans la boucle les lignes suivantes :
modeles_folder = container.modeles
cb = container.modeles.manage_copyObjects([’factures-synthese-anuelle.ods’])
for folder in container.values():
if folder.portal_type != ’Folder’:
continue
...
if ’factures-synthese-anuelle.ods’ not in folder.factures[year]:
folder.factures[year].manage_pasteObjects(cb)
print "factures-synthese-anuelle.ods copié dans %s" % folder.factures[year].absolute_url()
Le copier-coller et le couper-coller fonctionnent suivant un système de clipboard : on crée un clipboard que l’on
copie ou déplace ensuite (aucun traitement n’est fait tant qu’on ne sait pas où le contenu est destiné à être coupé
ou copié).
200
Chapitre 17. Ecrire des scripts Plone : bases
Plone pour les intégrateurs, Version 1.0.0
17.3.3 Publier des contenus
Nous souhaitons que la synthèse anuelle soit immédiatement publiée
if ’factures-synthese-anuelle.ods’ not in folder.factures[year]:
cb = container.modeles.manage_copyObjects([’factures-synthese-anuelle.ods’])
folder.factures[year].manage_pasteObjects(cb)
container.portal_workflow.doActionFor(folder.factures[year][’factures-synthese-anuelle.ods’],
print "factures-synthese-anuelle.ods copié dans %s" % folder.factures[year].absolute_url()
Nous ne ferons pas de rappel ici sur les workflows, qui méritent un chapitre à part entière. Disons simplement que
nous appliquons la transition “publish” (“Publier”) sur le contenu. Si pour une raison ou une autre la transition
n’est pas disponible, ou si l’utilisateur qui lance le script n’a pas le droit de passer cette transition, le script renverra
une erreur.
17.3.4 Les tools
À la racine de la ZMI, vous avez dû observer un certain nombre d’objets spéciaux, nombre d’entre eux ayant un id
commençant par portal_. Ce sont les tools. Les tools offrent deux types de service : ils permettent de stocker des
propriétés utiles sur l’ensemble du site, et ils fournissent des méthodes. Pour consulter les méthodes disponibles,
Pour récupérer un tool, il faut faire soit :
portal_workflow = portal.portal_workflow #(où portal est l’objet ’site’)
soit :
from Products.CMFCore.utils import getToolByName
portal_workflow = getToolByName(context, ’portal_workflow’) #(où context est n’importe quel objet
Les tools ne sont pas la seule manière d’avoir accès à des méthodes de l’api. Il existe aussi les vues standard, que
nous aborderons plus loin.
17.3.5 Déplacer des contenus
Certains services avaient pris les devants en créant dans leur dossier un dossier “facturation” dans lequels ils
avaient placé en vrac les factures. Vous souhaitez déplacer ceux qui ont été créés en février dans le nouveau
dossier (vous pourrez améliorer votre script pour traiter aussi les anciens !).
Dans un nouveau script :
for folder in container.values():
if folder.portal_type != ’Folder’:
continue
if ’facturation’ in folder:
cb = folder.facturation.manage_cutObjects([
content.getId()
for content in folder.facturation.values()
if DateTime(’2013/02/01 00:00’) < content.created() < DateTime(’2013/02/28 23:
folder.factures[’2013’][’02-2013’].manage_pasteObjects(cb)
En paramètre de la méthode manage_cutObjects, nous avons une comprehension list, qui génère la liste des ids
des objets dont la date de création est située entre le 1er février 2013 et le 31 décembre 2013 à 23h59 (donc dans
le mois).
– getId() est une la méthode qui renvoit l’identifiant de l’objet.
– created() renvoit la date de création
17.3. Créer et gérer des contenus par script
201
Plone pour les intégrateurs, Version 1.0.0
17.3.6 Modifier des contenus / retrouver la valeur d’un champ
Imaginons que nous voulions changer le titre de tous les dossiers “02-2013” en “Février 2013”, nous allons écrire
ceci :
for folder in container.values():
if folder.portal_type != ’Folder’:
continue
folder[’factures’][’2013’][’02-2013’].setTitle("Février 2013")
folder[’factures’][’2013’][’02-2013’].reindexObject()
Pour modifier le contenu d’un champ (avec archetypes), en général la méthode est “set + le nom du champ dont
la première lettre passe en majuscule”.
la méthode suivante fonctionne également la plupart des cas :
obj = folder[’factures’][’2013’][’02-2013’]
obj.getField(’title’).set(obj, "Février 2013")
Pour récupérer la valeur d’un champ, sous archetypes en général la méthode (accesseur) permettant de la récupérer
est nommée : “getChamp”, avec le nom du champ où la première lettre est mise en majuscule.
Les cas particuliers sont très fréquents. Ainsi :
– Title() pour le titre
– Description() pour la description
– created() pour la date de création (champ CreationDate)
– modified() pour la date de modification (champ ModificationDate)
– Creator() pour l’auteur du document (le login de l’utilisateur qui l’a ajouté)
– Language() pour la langue du document
– etc.
La plupart du temps (c’est notamment vrai avec dexterity), on peut récupérer la valeur sur l’objet en prenant
l’attribut correspondant au nom du champ.
print obj.title
Warning : Ce code (en fait, tout le code qu’on écrit depuis le début) n’est pas du tout optimal. En général, on
évitera de faire des “values()” et de parcourir les dossiers pour atteindre les éléments souhaités, on passera par
une “requête catalogue” qui nous permet d’atteindre les éléments souhaités via une recherche à critères. Nous
verrons cela lors de la 3e partie de ce chapitre.
Note : Exercice : Détectez les dossiers de niveau 1 et 2 qui sont vides, affichez leur titre et leur URL et le login
de l’utilisateur qui l’a créé. Indiquez ceux qui parmi eux ont été créés il y a plus d’un mois.
17.3.7 Supprimer des contenus
Nous allons écrire un script pour supprimer tous les contenus que nous avons créé ! Le script suivant supprime
tous les dossiers factures.
for folder in container.values():
if folder.portal_type != ’Folder’:
continue
if ’factures’ in folder:
folder.manage_delObjects([’factures’])
print "factures supprimé dans %s" % folder.absolute_url()
return printed
202
Chapitre 17. Ecrire des scripts Plone : bases
Plone pour les intégrateurs, Version 1.0.0
17.4 Connaître et exploiter les informations utilisateur
Vous avez quelques trucs pour produire des éléments, récupérer de l’information sur ces éléments. Voyons maintenant comment récupérer des informations sur les utilisateurs.
17.4.1 Accéder aux propriétés de l’utilisateur
Note : Avant tout, nous, allons cesser de créer des scripts directement à la racine du portail (car c’est parfois
difficile de s’y retrouver). Nous allons les créer en tant que layer dans le portal_skins.
Allez dans l’objet portal_skins. Vous voyez la liste des skins, qui sont des dossiers. Ces skins ont un système de
priorités. Un layer est un objet disponible partout sur le site. Si plusieurs layers ont le même nom, c’est celui
qui est dans la skin prioritaire qui est utilisé. Les priorités des skins sont indiquées dans l’onglet “Properties” du
portal_skins. La skin custom est une skin éditable en ligne qui est toujours prioritaire sur les autres. Allez dans
“le custom” et faites “Add -> Script”.
Attention ! Ne laissez pas trainer des scripts dangereux dans le custom sans les avoir protégés !
Notre premier script va afficher quelques informations sur l’utilisateur logué. Nous l’appelerons : authenticated_user_infos.
from Products.CMFCore.utils import getToolByName
member = getToolByName(context, ’portal_membership’).getAuthenticatedMember()
print "Login de l’utilisateur : ", member.getId()
print "Email : ", member.getProperty(’email’)
print "Nom complet : ", member.getProperty(’fullname’)
return printed
Autorisez ce script pour les utilisateurs ‘Member’.
Le tool portal_membership est celui qui offre les services permettant d’accéder aux utilisateurs (liste des utilisateurs, utilisateur connecté, etc) et de vérifier leurs droits. La méthode getProperty permet de récupérer une
propriété de l’utilisateur. La liste des propriétés disponibles est disponible dans le tool portal_memberdata.
Vous pouvez tester ce script avec plusieurs utilisateurs.
Nous allons maintenant faire un script qui permet de retrouver les informations sur un utilisateur, suivant un
paramètre de la requête. Créez un nouveau script user_infos. Vous avez peut-être vu le champ “Parameter List”
sur le formulaire du script. Complétez-le avec user_id=None, puis saisissez le code suivant :
from Products.CMFCore.utils import getToolByName
member = getToolByName(context, ’portal_membership’).getMemberById(user_id)
print "Login de l’utilisateur : ", member.getId()
print "Email : ", member.getProperty(’email’)
print "Nom complet : ", member.getProperty(’fullname’)
print "Dernière connexion : ", member.getProperty(’login_time’)
print "Avant-dernière connexion : ", member.getProperty(’last_login_time’)
print "Groupes de l’utilisateur : ", ", ".join(member.getGroupIds()) or "Aucun"
return printed
Quand vous testez le script, un formulaire est mis à votre disposition. Mais l’usage réel est d’appeler directement
l’URL avec la valeur en paramètre.
La méthode getMemberById permet de trouver un utilisateur suivant son identifiant. L’objet utilisateur contient,
en plus de la méthode getProperty, un certain nombre de méthodes permettant de retrouver les groupes auxquels il appartient : getGroups(), getGroupIds(), etc. Le tool portal_groups, qui fonctionne à l’image
du tool portal_membership, permet de récupérer l’information sur les groupes.
17.4. Connaître et exploiter les informations utilisateur
203
Plone pour les intégrateurs, Version 1.0.0
17.4.2 Mettre en forme les dates / les vues standard
Dans notre affichage, les dates sont difficiles à lire, et exprimées dans un standard international. Comme tout
système de publication multilingue, Plone fournit un outil pour exprimer les dates dans un format local.
C’est un exemple - très utilisé - de service rendu par une vue standard de plone (en l’occurence la vue “plone”).
Pour accéder à une vue standard depuis un script, on utilise la méthode restrictedTraverse. Nous expliquerons un
peu plus en détail plus loin la notion de traversing - dans le chapitre sur les templates, qui en font un usage intensif.
Disons pour l’instant qu’il s’agit de la méthode générique pour accéder à un élément depuis un objet Zope : un
contenu depuis un contenant, une vue ou un script depuis un objet, etc.
from Products.CMFCore.utils import getToolByName
member = getToolByName(context, ’portal_membership’).getMemberById(user_id)
plone_view = context.restrictedTraverse(’@@plone’)
print "Login de l’utilisateur : ", member.getId()
print "Email : ", member.getProperty(’email’)
print "Nom complet : ", member.getProperty(’fullname’)
print "Dernière connexion : ", plone_view.toLocalizedTime(member.getProperty(’login_time’), long_f
print "Avant-dernière connexion : ", plone_view.toLocalizedTime(member.getProperty(’last_login_tim
print "Groupes de l’utilisateur : ", ", ".join(member.getGroupIds()) or "Aucun"
return printed
Une référence complète des vues standard est disponible dans la partie ‘http ://docs.ecreall.com/developpeur‘_
développeur de ce site.
17.4.3 Modifier les propriétés de l’utilisateur
Nous allons écrire un script qui permet de modifier les adresses email de tous les utilisateurs, afin que tous les
emails soient remplacés par votre propre adresse, avec un préfixe. Très utile (voire indispensable) quand on récupère une base de production sur un serveur de tests.
from Products.CMFCore.utils import getToolByName
mtool = getToolByName(context, ’portal_membership’)
members = mtool.listMembers()
plone_utils = getToolByName(context, ’plone_utils’)
for member in members:
member_id = member.getId()
old_email = member.getProperty(’email’)
new_email = "monemail+%[email protected]" % member_id
if old_email != new_email:
plone_utils.setMemberProperties(member, email=new_email)
print "Changed %s email : %s -> %s" % (member_id, old_email, mtool.getMemberById(member_id
return printed
Vous observez l’utilisation de la méthode setMemberProperties du tool plone_utils pour indiquer les nouvelles valeurs de propriétés utilisateur.
Warning : Ce script aura des comportements inattendus si vous utilisez un plugin qui ne permet pas de sortir
la liste des membres sans recherche préalable (type plugin ldap).
17.4.4 Exporter en csv des informations utilisateurs
Imaginons que vous souhaitiez simplement exporter dans un fichier la liste des emails des utilisateurs du site.
Nous allons réaliser pour cela un export CSV. Créez ce script all-emails.csv.
204
Chapitre 17. Ecrire des scripts Plone : bases
Plone pour les intégrateurs, Version 1.0.0
from Products.CMFCore.utils import getToolByName
users = getToolByName(context, ’portal_membership’).listMembers()
response = context.REQUEST.response
response.setHeader(’Cache-Control’, ’no-cache’)
response.setHeader(’Pragma’, ’no-cache’)
response.setHeader(
’Content-type’, ’application/vnd.ms-excel;charset=windows-1252’)
response.setHeader(
’Content-disposition’,
’attachment; filename="all-emails.csv"’)
print ’"Login";"Nom complet";"email"’
for user in users:
print ’"%s";"%s";"%s"’ % (
user.getId(),
user.getProperty(’fullname’).decode(’utf-8’).encode(’windows-1252’),
user.getProperty(’email’))
return printed
Warning : Ce script aura des comportements inattendus si vous utilisez un plugin qui ne permet pas de sortir
la liste des membres sans recherche préalable (type plugin ldap).
Ce script introduit quelques nouvelles notions.
L’objet REQUEST est un objet qui contient des informations sur la requête de l’utilisateur (url, ip, referer, paramètres de formulaire...). Pour en connaître le contenu, vous n’aurez qu’à imprimer REQUEST.items(). Dans
un script, REQUEST est disponible comme attribut de tous les objets, notamment le context.
L’objet response est un object qui permet de caractériser la réponse à renvoyer à l’utilisateur. Il permet de définir
une redirection, de définir les headers, etc. Ici, nous indiquons que le rendu est un fichier csv optimisé pour excel
(encodé en windows-1252) et qu’il n’est pas mis en cache.
Exercice : écrivez un script permettant d’exporter en csv la liste des utilisateurs qui ne se sont pas logués depuis
au moins un an, avec la date de dernière connexion. (Astuce : Il y a un an = DateTime() - 365. Si votre site
est ouvert depuis moins de temps que ça, vous pouvez changer la contrainte ;))
17.4.5 Récupérer les rôles d’un utilisateur
Nous allons écrire un script qui permet d’afficher les rôles d’un utilisateur sur un objet donné. Cela peut être très
utile pour comprendre l’origine d’un problème (pourquoi l’utilisateur n’a pas accès à ce document ? est-ce un
problème de paramétrage de ses droits ou est-ce un bug ?)
Créez le script get_userroles avec un paramètre user_id.
user = context.portal_membership.getMemberById(user_id)
print "Roles de %s : %s" % (user_id, user.getRolesInContext(context))
return printed
La méthode getRolesInContext permet de récupérer la liste des rôles d’un utilisateur sur l’objet en paramètre.
Allez sur n’importe qel document ou dossier de votre site, ajoutez get_user_roles à l’URL : vous obtenez un
résultat en fonction du contexte. L’objet context est bien l’élément dans le contexte duquel vous exécutez le
script.
17.4.6 Vérifier un privilège de l’utilisateur connecté
Vous pouvez vérifier si, oui ou non, l’utilisateur connecté a un privilège sur un élément. Le script suivant permet
de montrer si l’utilisateur connecté a le droit d’ajouter, de modifier, de reviewer.
17.4. Connaître et exploiter les informations utilisateur
205
Plone pour les intégrateurs, Version 1.0.0
Voici un script user_privileges :
from Products.CMFCore.utils import getToolByName
mtool = getToolByName(context, ’portal_membership’)
user = mtool.getAuthenticatedMember()
print "Vous avez les rôles : ", ", ".join(user.getRolesInContext(context))
print "Vous avez le droit de :"
print "Voir : ", mtool.checkPermission(’View’, context) and "oui" or "non"
print "Modifier : ", mtool.checkPermission(’Modify portal content’, context) and "oui" or "non"
print "Modérer : ", mtool.checkPermission(’Review portal content’, context) and "oui" or "non"
print "Ajouter du contenu : ", mtool.checkPermission(’Add portal content’, context) and "oui" or "
return printed
Connectez vous avec d’autres utilisateurs et essayez le script un peu partout, en ajoutant /user_privileges aux
adresses des contenus.
Exercice : réalisez un script permettant, quand on l’applique sur un dossier, d’avoir la liste des utilisateurs ayant
au moins un rôle Contributeur, Modérateur ou Editeur, avec leurs emails.
Info : la méthode folder.users_with_local_role(role) renvoit la liste des utilisateurs ayant ce role
défini localement sur le dossier. Si vous utilisez cette méthode, pensez au fait que le rôle peut également être hérité
du parent.
17.5 Utiliser le catalogue de Plone
Ce chapitre n’est pas un cours sur le catalogue de Plone. Nous ferons néanmoins quelques rappels :
– tous les contenus de Plone font l’objet d’un enregistrement dans un catalogue, qui est le tool portal_catalog,
– il est possible de retrouver des contenus de plone via des recherches multi-critères,
– il est considérablement moins couteux de rechercher et d’exploiter un enregistrement dans le catalogue que de
parcourir le site jusqu’à trouver un document et exploiter les données de celui-ci ; tout code destiné à être utilisé
régulièrement DOIT privilégier le catalogue sur le parcours du site.
– la liste des critères de recherche disponibles est dans l’onglet Index du portal_catalog, et la liste des métadonnées disponibles sur les enregistrements est dans l’onglet Metadata.
Nous allons écrire un script qui permet de retrouver la liste des 50 derniers éléments créés par un utilisateur. Créez
un script qui prend en paramètre user_id.
17.5.1 Une première requête catalogue
Ecrivez ce premier script last_documents avec un paramètre user_id :
from Products.CMFCore.utils import getToolByName
portal_catalog = getToolByName(context, ’portal_catalog’)
brains = portal_catalog.searchResults(Creator=user_id,
sort_on=’created’, # le tri se fait sur l’index ’created’ (d
sort_order=’reverse’, # le tri est inversé (antéchronologiqu
sort_limit=50) # on limite à 50 résultats
for brain in brains:
print brain.Title or brain.getId, " ", brain.getURL() # On affiche la métadonnée Title et on c
return printed
La méthode searchResults prend les critères en arguments nommés. Nous présentons ici un critère classique (Creator) et les trois critères de tri. On accède aux métadonnées sur l’enregistrement via l’appel à un attribut. En plus
des attributs-métadonnées, le brain dispose de trois méthodes utiles :
– getURL() -> renvoit l’URL absolue du document
– getPath() -> renvoit le chemin d’accès zope
– getObject() -> renvoit l’objet
206
Chapitre 17. Ecrire des scripts Plone : bases
Plone pour les intégrateurs, Version 1.0.0
Un aperçu un peu plus complet est disponible ici : Querying the catalog
A des fins illustratives, nous présentons ici un script qui affiche l’ensemble des documents modifiés depuis un
mois dans le dossier où est lancé le script, et affiche le total de résultats.
from Products.CMFCore.utils import getToolByName
portal_catalog = getToolByName(context, ’portal_catalog’)
brains = portal_catalog.searchResults(path="/".join(context.getPhysicalPath()), # critère chemin d
portal_type=(’File’, ’Document’), # critère sur le type : Fi
# entre aujourd’hui et il y a 31 jours (on pourrait écrire p
modified={’query’: (DateTime() - 31, DateTime()), ’range’: ’
sort_on=’modified’, # le tri se fait sur l’index ’modified’
sort_order=’reverse’, # le tri est inversé (antéchronologiqu
) # on limite à 50 résultats
print "Total : ", len(brains)
for brain in brains:
print brain.Title, " ", brain.getURL() # On affiche la métadonnée Title et on calcule l’url du
return printed
Voici un script, que nous appellerons all-contents.csv. Il exporte en csv une liste des documents contenus dans le
dossier où il est appliqué, et récursivement.
from Products.CMFCore.utils import getToolByName
response = context.REQUEST.response
response.setHeader(’Cache-Control’, ’no-cache’)
response.setHeader(’Pragma’, ’no-cache’)
response.setHeader(
’Content-type’, ’application/vnd.ms-excel;charset=windows-1252’)
response.setHeader(
’Content-disposition’,
’attachment; filename="all-contents.csv"’)
portal_catalog = getToolByName(context, ’portal_catalog’)
brains = portal_catalog.searchResults(path="/".join(context.getPhysicalPath()), # critère chemin d
portal_type=(’File’, ’Document’, ’Event’, ’News’), # critère
)
print ’"Path";"Titre";"Auteur";"MAJ"’
for brain in brains:
print ’"%s";"%s";"%s";"%s"’ % (brain.getPath(), brain.Title.decode(’utf-8’).encode(’windows-12
return printed
Exercices :
– Créez un script qui produit un fichier csv, qui indique, pour chaque utilisateur, le nombre d’élements qu’il a
créés depuis 2 ans et depuis la création du site, et un lien vers le dernier document qu’il a créé.
– Créez un script qui compte le nombre de documents et de fichiers dans chaque dossier à la racine du site
Pour ces exercices, vous devrez faire plusieurs requêtes catalogue dans le même script !
On le voit, les scripts sont très utiles dès lors qu’il s’agit d’établir rapidement des indicateurs sur l’utilisation de
son site.
Nous allons maintenant apprendre à valoriser sous forme d’affichage html les données que nous avons
appris à constituer : Ecrire des templates Plone : bases.
17.5. Utiliser le catalogue de Plone
207
Plone pour les intégrateurs, Version 1.0.0
208
Chapitre 17. Ecrire des scripts Plone : bases
CHAPITRE 18
Ecrire des templates Plone : bases
Author Thomas Desvenain
Created 2013-02-28
Version 0.1.0
–
–
–
–
–
–
–
–
–
–
Introduction
Ma première template
Appel à un script
Utiliser la master template de Plone
Utiliser une structure plus complexe dans une template
Appeler une template depuis une autre template
Exercices
Ecrire la template sous la forme d’une vue
Une vue pour un export csv
Une viewlet pour ajouter un lien vers une vue
– Ma première viewlet
– Exercices
Copyright (C) 2013 Thomas Desvenain <thomas.desvenain AT gmail.com>.
Chacun est autorisé à copier, distribuer et/ou modifier ce document suivant les termes de la licence
Paternité-Pas d’Utilisation Commerciale-Partage des Conditions Initiales à l’Identique 2.0 France accessible à
http ://creativecommons.org/licenses/by-nc-sa/2.0/fr
Le code source présent dans ce document est soumis aux conditions de la « Zope Public License », Version 2.1
(ZPL).
THE SOURCE CODE IN THIS DOCUMENT AND THE DOCUMENT ITSELF 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.
18.1 Introduction
Ce chapitre fait suite au chapitre Ecrire des scripts Plone : bases, notamment dans son objectif de permettre à des
webmaster Plone débutants en programmation de réaliser en ligne des outils simples pour l’animation de son site
(indicateurs, etc).
Nous allons ici apprendre à réaliser nos premiers écrans, d’abord uniquement via le Web, puis sur système de
fichiers (cela implique que vous ayez créé un produit pour héberger votre code ou qu’on l’ait fait pour vous). Nous
209
Plone pour les intégrateurs, Version 1.0.0
apprendrons également comment ajouter également un bloc dans une page standard de Plone pour intégrer un lien
vers un de vos nouveaux écrans.
Le lecteur devra de se référer également au chapitre TAL/Metal : les templates de Zope et Plone qui contient une
référence assez complète.
18.2 Ma première template
Nous allons commencer en réalisant une première template qui affiche quelques informations sur l’utilisateur
logué ainsi qu’un message de bienvenue.
Dans le dossier ‘custom’ (cf chapitre sur les scripts), ajoutez une “Page Template”, que vous appelez welcome.
Donnez un titre à votre template : Bienvenue !
<html>
<head>
<title tal:content="template/title">The title</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
</head>
<body tal:define="plone context/@@plone">
<h2>Bienvenue <span tal:content="python:user.getProperty(’fullname’)" /> !</h2>
<p>Vous vous êtes connectés la dernière fois le <span tal:content="python:plone.toLocalizedTim
<p>Depuis votre inscription sur ce site vous avez créé <span tal:content="python:len(context.p
</body>
</html>
Connectez-vous avec un autre utilisateur et allez à l’adresse http ://chemin/vers/monsite/welcome.
Une fois que vous avez compris que le langage Zope Page Template consiste en un HTML étendu par des attributs
dans un espace de nom TAL, qui contient les instructions, vous devriez pouvoir lire facilement cette template.
Reférez vous à la référence TAL/Metal : les templates de Zope et Plone.
Nous avons deux types d’expressions TAL :
– des expressions TAL simples, sans directive et qui se caractérisent par leur forme de chemin d’accès,
– des expressions python, introduites par la directive “python :”
Vous noterez que, dans les expressions tal simples, la syntaxe ‘/’ permet d’exprimer de nombreuses manières
d’accéder à un objet depuis un autre objet.
– “context/@@plone” est synonyme de context.restrictedTraverse(’@@plone’) en python
– “context/title_or_id” est synonyme de context.title_or_id(),
– “template/title” est synonyme de template.title,
18.3 Appel à un script
Mettre de longues expressions python dans une expression tal est souvent une mauvaise idée car c’est assez illisible
et des erreurs viennent facilement s’y glisser, et il n’est pas aiser de tester ses routines. Nous souhaiterions afficher
les derniers contenus ajoutés par l’utilisateur. Nous allons faire appel à notre script qui retrouvait la liste des 50
derniers contenus créés par l’utilisateur connecté. Nous allons le modifier pour qu’il ne renvoit pas un texte, mais
pour qu’il renvoit les enregistrements que nous valoriserons ensuite dans la template.
Créez le script get_user_recent_added :
from Products.CMFCore.utils import getToolByName
portal_catalog = getToolByName(context, ’portal_catalog’)
portal_membership = getToolByName(context, ’portal_membership’)
user = portal_membership.getAuthenticatedMember()
brains = portal_catalog.searchResults(Creator=user.getId(),
portal_type=(’News Item’, ’File’, ’Document’, ’Event’), # on
sort_on=’created’, # le tri se fait sur l’index ’created’ (d
210
Chapitre 18. Ecrire des templates Plone : bases
Plone pour les intégrateurs, Version 1.0.0
sort_order=’reverse’, # le tri est inversé (antéchronologiqu
sort_limit=50) # on limite à 50 résultats
return brains
Complétez ainsi votre template :
<html>
<head>
<title tal:content="template/title">The title</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
</head>
<body tal:define="plone context/@@plone;
portal_state context/@@plone_portal_state;">
<h2>Bienvenue <span tal:content="python:user.getProperty(’fullname’)" /> !</h2>
<p>Vous vous êtes connectés la dernière fois le <span tal:content="python:plone.toLocalizedTim
<p>Depuis votre inscription sur ce site vous avez créé <span tal:content="python:len(context.p
<h3>Derniers contenus ajoutés</h3>
<ul>
<li tal:repeat="brain context/get_user_recent_added">
<img tal:condition="brain/getIcon"
tal:attributes="src string:${portal_state/portal_url}/${brain/getIcon}" />
<a tal:attributes="href brain/getURL" tal:content="brain/Title"></a>
</li>
</ul>
</body>
</html>
Quelques remarques :
– Nous avons rajouté une boucle : tal :repeat=”brain context/get_user_recent_added” qui s’écrirait, dans un
script python : for brain in context.get_user_recent_added():.
– Comme vous pouvez le voir, brain/Title et brain/getURL équivalent respectivement à brain.Title
et brain.getURL() (les expressions TAL ont cela d’agréable qu’elles sont sobres en caractères spéciaux).
– Une expression TAL introduite par la directive string : permet de renvoyer une chaine de caractères composée
de contenu statique et du rendu de sous-expressions TALES.
– Nous utilisons ici une autre “vue standard” : plone_portal_state, qui permet notamment de récupérer l’URL
absolue du site.
18.4 Utiliser la master template de Plone
Le but est d’intégrer votre template dans le gabarit de Plone. L’usage des macros se restreint principalement
aujourd’hui à utiliser la “main template”. (Vous ne devriez pas avoir à définir des macros, c’est pourquoi on ne
présentera pas dans le cadre de ce tutorial.)
Indiquez simplement dans l’élément html que vous utilisez la macro master en introduisant l’attribut suivant :
metal:use-macro="here/main_template/macros/master".
Et dans l’élément body, que le contenu de cet élément remplit la slot “main” du master
metal:fill-slot="main"
Affichez la vue welcome. Elle s’intègre dans le corps d’une page Plone.
Allez consulter maintenant la main_template. Faites une recherche sur main_template dans l’onglet “Find” du
portal_skins, et choisissez celle qui est mise en valeur par une étoile : c’est celle qui est prioritaire dans l’ordre des
skins.
La macro définit un ensemble de slots avec un contenu par défaut. Vous pouvez surcharger ce contenu par défaut
à l’aide de la directive metal :fill-slot.
Exercice : modifiez votre template welcome de sorte que les colonnes de gauche et de droite n’affichent rien.
18.4. Utiliser la master template de Plone
211
Plone pour les intégrateurs, Version 1.0.0
18.5 Utiliser une structure plus complexe dans une template
Nous avons, dans la template précédente, valorisé une liste de brains. Nous allons maintenant valoriser un dictionnaire.
Vous voyez que la récupération d’une propriété utilisateur dans la template est assez verbeuse. Nous allons écrire
un script qui renvoit un dictionnaire avec les informations qui nous intéressent.
Modifiez le script user_infos que vous avez créé au chapitre précédent pour qu’il n’affiche pas un texte mais
renvoie un dictionnaire.
from Products.CMFCore.utils import getToolByName
member = getToolByName(context, ’portal_membership’).getAuthenticatedMember()
plone_view = context.restrictedTraverse(’@@plone’)
infos = {’login’: member.getId(),
’email’: member.getProperty(’email’),
’fullname’: member.getProperty(’fullname’) or member.getId(),
’login_time’: plone_view.toLocalizedTime(member.getProperty(’login_time’), long_format=1)
’last_login_time’: plone_view.toLocalizedTime(member.getProperty(’last_login_time’), long
’groups’: ", ".join(member.getGroupIds()) or "Aucun"}
return infos
Puis modifiez votre template pour qu’elle récupère cette structure et qu’elle affiche les infos.
<html metal:use-macro="here/main_template/macros/master">
<head>
<title tal:content="template/title">The title</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
</head>
<body metal:fill-slot="main"
tal:define="plone context/@@plone;
portal_state context/@@plone_portal_state;
user_infos context/user_infos">
<h2>Bienvenue <span tal:replace="user_infos/fullname" /> !</h2>
<p>Vous êtes connectés depuis <span tal:content="user_infos/login_time" />
<p>Votre email est :
<a tal:attributes="href string:mailto:${user_infos/email}"
tal:content="user_infos/email" /></p>
<p>Vous vous êtes connectés la dernière fois le <span tal:content="user_infos/last_login_time"
<p>Depuis votre inscription sur ce site vous avez créé <span tal:content="python:len(context.p
<p>Vous êtes membres des groupes <span tal:content="user_infos/groups" /></p>
<h3>Derniers contenus ajoutés</h3>
<ul>
<li tal:repeat="brain context/get_user_recent_added">
<img tal:condition="brain/getIcon"
tal:attributes="src string:${portal_state/portal_url}/${brain/getIcon}" />
<a tal:attributes="href brain/getURL" tal:content="brain/Title"></a>
</li>
</ul>
</body>
</html>
Vous observez que la template est beaucoup plus lisible. Ce que nous avons fait, c’est déporter la préparation des
informations à afficher dans du code python, et réserver la template pour la disposition des informations.
212
Chapitre 18. Ecrire des templates Plone : bases
Plone pour les intégrateurs, Version 1.0.0
18.6 Appeler une template depuis une autre template
18.7 Exercices
– Vous réaliserez un tableau qui présentera, pour les dossiers à la racine du site, le nombre de documents (hors
dossiers) qu’il contient (récursivement), et le nombre de documents qui y ont été créés depuis moins d’un mois.
– Vous réaliserez une page destinée à être affichée au niveau d’un dossier, qui affichera la liste des utilisateurs qui
ont un rôle sur le dossier, et pour chacun d’entre eux le nombre de documents qu’ils ont créé.
– Vous réaliserez une template qui affiche, pour chaque mot clé disponible sur le site, le nombre d’occurences
et un lien vers une page de résultat (dont vous devrez également écrire la template). (Astuces : 1/ le script
context.collectKeywords(’subject’, ’Subject’) vous permet de récupérer la liste des mots
clés, 2/ l’index concerné est l’index Subject.). Bonus : la taille de l’affichage du mot clé sera proportionnelle au
nombre d’occurences !
18.8 Ecrire la template sous la forme d’une vue
Si vous estimez que votre template et ses scripts seront utilisés sur le long terme, il est temps de penser à les
transformer en vue. Vous aurez beaucoup plus de facilités à les déployer en production.
Une vue est composée d’une template et d’une classe. La template va reprendre la template que vous avez créé.
Ce chapitre n’a pas pour objectif d’expliquer la création d’un package. Référez-vous, pour cela, à la documentation
développeur, ou demandez à votre prestataire favori.
Nous allons créer une vue “welcome”. Pour cela, il faut d’abord la déclarer dans une zcml.
<browser:page
name="welcome"
template="welcome.pt"
class=".views.Welcome"
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
permission="zope2.View"
/>
Vous pouvez ensuite simplement récupérer la template (utilisez le lien click context du formulaire d’édition de la
template), et l’enregistrer dans un fichier welcome.pt.
Vous reprenez ensuite dans la classe Welcome (qui hérite de BrowserView) d’un module views.py le code des
scripts que vous incluez dans des méthodes du même nom. La classe Welcome contient un attribut context (l’équivalent du context dans le script ou la template) et un attribut request (l’équivalent de context.REQUEST dans
le script ou request dans la template).
# -*- encoding: utf-8 -*from Products.CMFCore.utils import getToolByName
from Products.Five.browser import BrowserView
class Welcome(BrowserView):
def user_infos(self):
member = getToolByName(self.context, ’portal_membership’).getAuthenticatedMember()
plone_view = self.context.restrictedTraverse(’@@plone’)
infos = {’login’: member.getId(),
’email’: member.getProperty(’email’),
’fullname’: member.getProperty(’fullname’) or member.getId(),
’login_time’: plone_view.toLocalizedTime(member.getProperty(’login_time’), long_f
’last_login_time’: plone_view.toLocalizedTime(member.getProperty(’last_login_time
’groups’: ", ".join(member.getGroupIds()) or "Aucun"}
18.6. Appeler une template depuis une autre template
213
Plone pour les intégrateurs, Version 1.0.0
return infos
def get_user_recent_added(self):
portal_catalog = getToolByName(self.context, ’portal_catalog’)
portal_membership = getToolByName(self.context, ’portal_membership’)
user = portal_membership.getAuthenticatedMember()
brains = portal_catalog.searchResults(Creator=user.getId(),
portal_type=(’News Item’, ’File’, ’Document’, ’Event
sort_on=’created’, # le tri se fait sur l’index ’cre
sort_order=’reverse’, # le tri est inversé (antéchro
sort_limit=50) # on limite à 50 résultats
return brains
Modifiez votre template de sorte qu’elle aille chercher les méthodes non pas sur le contexte (context) mais sur la
vue (view). Retirez toute référence à l’objet template.
<html metal:use-macro="here/main_template/macros/master">
<body metal:fill-slot="main"
tal:define="plone context/@@plone;
portal_state context/@@plone_portal_state;
user_infos view/user_infos">
<h2>Bienvenue <span tal:content="user_infos/fullname" /> !</h2>
<p>Vous êtes connectés depuis <span tal:content="user_infos/login_time" />
<p>Votre email est : <a tal:attributes="href string:mailto:${user_infos/email}" tal:content="u
<p>Vous vous êtes connectés la dernière fois le <span tal:content="user_infos/last_login_time"
<p>Depuis votre inscription sur ce site vous avez créé <span tal:content="python:len(context.p
<p>Vous êtes membres des groupes <span tal:content="user_infos/groups" /></p>
<h3>Derniers contenus ajoutés</h3>
<ul>
<li tal:repeat="brain view/get_user_recent_added">
<img tal:condition="brain/getIcon"
tal:attributes="src string:${portal_state/portal_url}/${brain/getIcon}" />
<a tal:attributes="href brain/getURL" tal:content="brain/Title"></a>
</li>
</ul>
</body>
</html>
Pensez à renommer vos anciens scipts et templates qui restent dans le custom, pour éviter les conflits.
18.9 Une vue pour un export csv
Le script d’export csv peut également être transformé en vue. Nous allons faire une vue pour l’export allcontents.csv pour lequel nous avons fait un script dans le chapitre précédent.
<browser:view
name="all-contents.csv"
class=".views.AllContentsCSV"
for="Products.CMFCore.interfaces.IFolderish"
permission="cmf.AddPortalContent"
/>
Deux remarques sur le zcml : Comme on n’a pas de template on utilise non pas une browser :page mais une
browser :view. Pour faire simple, par rapport à ce que vous connaissez, une browser :page équivaut à une template
et une browser view à un script.
Le critère for indique une restriction sur l’interface du contenu - ici, on restreint aux contextes IFolderish, qui
est une interface qu’ont tous les objets qui peuvent en contenir d’autres. Les autres contextes n’auront pas cette
214
Chapitre 18. Ecrire des templates Plone : bases
Plone pour les intégrateurs, Version 1.0.0
vue (pour connaitre les interfaces d’un contexte, dans la ZMI, allez dans l’onglet Interfaces de l’objet). Le critère
permission permet protéger la vue. Un utilisateur essayant d’y accéder sans avoir ladit permission aura une erreur
de privilèges insuffisants.
Pour une browser view, il faut écrire une méthode __call__ qui renvoit le rendu attendu.
class AllContentsCSV(BrowserView):
def __call__(self):
response = self.request.response
response.setHeader(’Cache-Control’, ’no-cache’)
response.setHeader(’Pragma’, ’no-cache’)
response.setHeader(
’Content-type’, ’application/vnd.ms-excel;charset=windows-1252’)
response.setHeader(
’Content-disposition’,
’attachment; filename="all-contents.csv"’)
portal_catalog = getToolByName(self.context, ’portal_catalog’)
brains = portal_catalog.searchResults(path="/".join(self.context.getPhysicalPath()), # cri
portal_type=(’File’, ’Document’, ’Event’, ’News’), #
)
lines = [’"Path";"Titre";"Auteur";"MAJ"’]
for brain in brains:
lines.append(’"%s";"%s";"%s";"%s"’ % (brain.getPath(),
brain.Title.decode(’utf-8’).encode(’windows-1252’),
brain.Creator, brain.modified.strftime(’%d/%m/%Y’)))
return "\n".join(lines)
Nous sommes dans une vue, qui est du code python non restreint. À ce titre, on a accès à toute l’API python
disponible. Dans ce cas, nous gagnerons à utiliser la librairie csv pour produire notre fichier.
from csv import writer
from StringIO import StringIO
class AllContentsCSV(BrowserView):
def __call__(self):
response = self.request.response
response.setHeader(’Cache-Control’, ’no-cache’)
response.setHeader(’Pragma’, ’no-cache’)
response.setHeader(
’Content-type’, ’application/vnd.ms-excel;charset=windows-1252’)
response.setHeader(
’Content-disposition’,
’attachment; filename="all-contents.csv"’)
portal_catalog = getToolByName(self.context, ’portal_catalog’)
brains = portal_catalog.searchResults(path="/".join(self.context.getPhysicalPath()), # cri
portal_type=(’File’, ’Document’, ’Event’, ’News’), #
)
csvdata = StringIO()
csvhandler = writer(csvdata, dialect=’excel’, delimiter=’;’)
csvhandler.writerow(["Path","Titre","Auteur","MAJ"])
for brain in brains:
csvhandler.writerow((brain.getPath(),
brain.Title,
18.9. Une vue pour un export csv
215
Plone pour les intégrateurs, Version 1.0.0
brain.Creator,
brain.modified.strftime(’%d/%m/%Y’)))
csvdata.seek(0)
return csvdata.read().decode(’utf-8’).encode(’windows-1252’)
Ce qui est tout de même bien plus propre.
18.10 Une viewlet pour ajouter un lien vers une vue
18.10.1 Ma première viewlet
Tous les développements que nous avons réalisés jusqu’à présent souffrent, vous avez du le remarquer, d’un gros
inconvénient : nous n’avons nulle part, dans notre site, de lien vers les différentes pages et exports que nous avons
réalisés ! Autrement dit : nos développements ne sont pas intégrés.
Comment ajouter un lien vers nos nouvelles pages ?
Vous pouvez tout simplement mettre un lien à la main dans un document Plone, mais cela peut être fastidieux si
vous souhaitez que ce lien apparaisse dans de nombreux contextes. Un réflexe de développement “à l’ancienne”
est, à l’extrême opposé, de modifier le code de la template de base et d’y mettre le lien (éventuellement conditionnel) vers notre page. Mais “si tout le monde fait cela”, à la fin cette template ne ressemblera plus à rien. Surtout,
si vous voulez que votre développement soit utilisé par d’autres, ou sur d’autres de vos sites, il ne faut pas qu’il
intervienne sur le comportement par défaut du site.
Pour cela, Plone fonctionne avec ce qu’on appelle des viewlets. Ce sont des blocs que l’on peut enregistrer pour
qu’ils s’affichent dans des slots appelés viewletmanagers. Une documentation complète des viewlets est disponible
dans la documentation développeur.
Nous allons, nous, simplement ajouter un lien (sous forme d’image) vers notre export xml sous le titre des dossiers
de notre site, pour les utilisateurs ayant le droit d’ajouter des contenus.
Nous allons ajouter ceci dans une zcml de notre package :
<browser:viewlet
name="link-allcontents-csv"
manager="plone.app.layout.viewlets.interfaces.IAboveContentTitle"
for="Products.CMFCore.interfaces.IFolderish"
class=".viewlets.LinkAllContentsCSV"
permission="cmf.AddPortalContent"
/>
Remarques : - class indique la classe qui fournira le rendu html de notre lien (voir ci–après). - manager indique le
bloc dans lequel l’élément sera ajouté. Pour choisir le manager, allez sur la vue /@@manage-viewlets sur une des
pages de votre site. Les viewlet managers ont un nom et une interface. C’est l’interface que vous indiquez ici. for permet de mettre une contrainte sur le contexte (ici, on n’affichera le lien que sur les dossiers). - permission
permet de n’afficher la viewlet que pour certains utilisateurs (on la fera correspondre avec la permission de la vue).
- cela ne fait pas l’objet du présent cours, mais pour information un attribut layer est souvent utilisé afin de mettre
une contrainte sur les produits installés / l’interface de la request. - name est utile si vous souhaitez remplacer
une viewlet existante. Si deux viewlets ont le même nom et sont associées au même manager, alors une seule est
affichée : celle qui déclare une interface for la plus proche du contexte en cours, et celle qui a un critère layer le
plus proche du layer en cours.
Dans un module viewlets.py nous allons créer cette classe LinkAllContentsCSV :
from plone.app.layout.viewlets.common import ViewletBase
from Products.CMFCore.utils import getToolByName
class LinkAllContentsCSV(ViewletBase):
def render(self):
216
Chapitre 18. Ecrire des templates Plone : bases
Plone pour les intégrateurs, Version 1.0.0
portal_url = getToolByName(self.context, ’portal_url’)()
return u"""<a href="%(url)s" id="link-allcontents-csv"
style="float: right;"
title="Exporter la liste des contenus en csv">
<img src="%(portal_url)s/xls.png" />
</a>
""" % ({’url’: self.context.absolute_url() + ’/all-contents.csv’,
’portal_url’: portal_url})
Les viewlets hériteront de la classe ViewletBase, qui fournit quelques services. Pour les besoins les plus simples,
vous surchargez ensuite la méthode render, qui génèrera le HTML en python pur. (en principe vous ne mettrez
jamais de css en inline : vous indiquerez dans une css : #link-allcontents-csv{float: right;}).
Pour des besoins plus complexes, vous utiliserez une template en surchargeant l’attribut index :
from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile
class LinkAllContentsCSV(ViewletBase):
index = ViewPageTemplateFile(’link-allcontents-csv.pt’)
18.10.2 Exercices
– Ajoutez un lien sur les dossiers pour conduire vers un écran que vous avez développé lors d’un exercice sur les
templates ou les vues.
– Affichez sous le titre d’un dossier un bloc d’informations indiquant notamment la liste des personnes qui ont
ajouté des documents dans ce dossier.
18.10. Une viewlet pour ajouter un lien vers une vue
217
Plone pour les intégrateurs, Version 1.0.0
218
Chapitre 18. Ecrire des templates Plone : bases
CHAPITRE 19
TAL/Metal : les templates de Zope et
Plone
Les Zope Page Templates sont un mécanisme permettant d’écrire des pages xhtml dynamiques.
Ces ZPT utilisent un langage de template XML TAL/METAL. L’objectif est d’être capable de comprendre, créer
et modifier les pages dynamiques.
219
Plone pour les intégrateurs, Version 1.0.0
– Le langage TAL
– Savoir
– TALES
– Savoir
– METAL
– Savoir
– Ressources
– Namespaces
– Variables globales
– Présentation des ZPT
– Le langage TAL
– Liste des commandes
– Ordre d’évaluation
– Content et Replace
– Condition
– Attributes
– Define
– Repeat
– On-error
– Omit-tag
– TALES
– Définition
– Exemples
– Path
– Path alternatif et nothing
– Not
– String
– Nocall
– Python
– METAL
– metal :define-macro
– metal :define-slot
– metal :use-macro
– metal :fill-slot
– Tips
19.1 Le langage TAL
19.1.1 Savoir
–
–
–
–
–
–
–
–
Liste des commandes
Ordre d’évaluation
Content et Replace
Condition
Define
Repeat
On-error
Omit-tag
220
Chapitre 19. TAL/Metal : les templates de Zope et Plone
Plone pour les intégrateurs, Version 1.0.0
19.2 TALES
19.2.1 Savoir
–
–
–
–
–
–
–
Exemples
Path
Path alternatif et nothing
Not
String
Nocall
Python
19.3 METAL
19.3.1 Savoir
–
–
–
–
metal:define-macro
metal:define-slot
metal:use-macro
metal:fill-slot
19.4 Ressources
Lire la documentation ZPT - Zope Page Templates sur plone.org.
Un tal:repeat sur une balise <ul ..> ou <tbody ...> répètera la balise à chaque tour de boucle. Le
tal:repeat devrait donc se situer sur un <li ...> ou un <tr ...>.
Petit rappel sur les tableaux : vous pouvez mettre un <tr> dans un <thead> pour avoir une ligne d’en-tête sur
chaque page lors de l’impression d’un tableau. Il va de même pour un pied de page avec la balise <tfoot>.
Dans le document ci-dessus, il manque les commandes tal:omit-tag et tal:on-error, cela est expliqué
dans le ZopeBook :
– Using Zope Page Templates
– Advanced Page Templates
– Appendix C : Zope Page Templates Reference
La documentation sur plone.org et celle dans le ZopeBook se ressemble beaucoup. Les pages dans le ZopeBook
sont complémentaires à la documentation sur plone.org.
19.5 Namespaces
Prenez l’habitude de toujours inclure les namespaces dans vos templates. Ils seront nécessaires pour le nouveau
moteur de template Chameleon qui parse la page de manière stricte.
La structure minimale est donc :
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
xml:lang="en" lang="en"
metal:use-macro="context/main_template/macros/master"
i18n:domain="mydomain">
...
</html>
19.2. TALES
221
Plone pour les intégrateurs, Version 1.0.0
Vous pouvez vérifier si vos templates sont bien valides XML avec la commande xmllint matemplate.pt.
19.6 Variables globales
Dans Plone 3.3, vous avez accès à des variables et fonctions globalement dans vos pages templates. Vous n’y avez
pas accès via une vue zope3.
Vous
pouvez
récupérer
une
liste
des
Products.CMFPlone.browser.ploneview.
fonctions
disponibles
dans
le
module
Toutefois étant donné que dans Plone 4, vous n’y aurez plus accès, prenez l’habitude d’appeler ces fonctions
spéciales par l’intermédiaire d’une vue. Par exemple au lieu d’utiliser :
<span tal:content="python:toLocalizedTime(context.ModificationDate())">
modification date
</span>
utilisez plutôt :
<span tal:define="plone_view context/@@plone"
tal:content="python:plone_view.toLocalizedTime(context.ModificationDate())">
modification date
</span>
Les variables globales vont être supprimées dans Plone 4 pour des raisons de performances. En effet de nombreuses
variables sont accessibles depuis la template mais ne sont pas forcément utilisées, et donc il y a un traitement inutile
au rendu de la page.
Vous avez quatre vues intéressantes pour récupérer des informations :
– @@plone (toLocalizedTime...)
– @@plone_tools (properties pour récupérer portal_properties)
– @@plone_portal_state (navigation_root_url, is_locked, language, is_editable, object_url...)
– @@plone_context_state (portal_url...)
19.7 Présentation des ZPT
Objectif
Être capable de comprendre, créer et modifier les pages dynamiques.
Les Zope Page Template sont un mécanisme permettant d’écrire des pages XHTML dynamiques.
Elles sont constituées de page XHTML dans lesquelles sont inclus des balises et attributs TAL/METAL.
Exemple :
<html xmlns="http://www.w3.org/1999/xhtml"
xml:lang="en"
lang="en"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
metal:use-macro="here/main_template/macros/master"
i18n:domain="plone">
<head><title></title></head>
<body>
<metal:fill fill-slot="main">
<metal:main_macro define-macro="main">
<div tal:content="python:1+3*7" />
</metal:main_macro>
</metal:fill>
222
Chapitre 19. TAL/Metal : les templates de Zope et Plone
Plone pour les intégrateurs, Version 1.0.0
</body>
</html>
19.8 Le langage TAL
Le texte d’origine est accessible à http ://www.sebastien-verbois.be/plone/zpt/zpt-am
Template Attribute Language (commandes possibles)
19.8.1 Liste des commandes
–
–
–
–
–
–
–
–
tal:content pour remplacer le contenu d’une balise ;
tal:replace pour remplacer toute la balise ;
tal:condition condition d’exécution du bloc ;
tal:attributes pour manipuler les attributs de la balise ;
tal:define pour définir des variables ;
tal:repeat pour faire une boucle ;
tal:omit-tag pour ne pas produire la balise elle-même ;
tal:on-error pour définir le comportement en cas d’erreur.
tal:content et tal:replace sont mutuellement exclusives.
Une commande ne peut apparaître qu’une seule fois dans une balise.
19.8.2 Ordre d’évaluation
define -> condition -> repeat -> (content | replace) -> attributes -> omit-tag
on-error est évalué si une exception est levée lors d’un traitement d’une des opérations ci-dessus.
19.8.3 Content et Replace
tal:content="[structure] Tales"
tal:replace="[structure] Tales"
Le contenu est automatiquement transformé à l’aide de la fonction html_quote. Pour ne pas subir cette
transformation, il faut utiliser le préfixe structure.
Il est possible d’accéder aux informations portées par les itérations en utilisant la variable repeat.
19.8.4 Condition
tal:condition="Tales"
Tales est évalée à True ou False. Le nombre zéro, la chaîne vide, une liste vide et la variable nothing sont
évaluées à False.
19.8.5 Attributes
tal:attributes="NomAttribut1 Tales1; NomAttribut2 Tales2; ...; NomAttributN TalesN"
19.8. Le langage TAL
223
Plone pour les intégrateurs, Version 1.0.0
19.8.6 Define
tal:define="[global] NomVariable1 Tales1; [global] NomVariable2 Tales2; ...; [global] NomVariableN
19.8.7 Repeat
tal:repeat="NomVariable Tales"
Les itérations imbriquées sont possibles.
Les tales suivantes sont accessibles dans le bloc repeat :
– repeat/NomVariable/index : 0,1,...
– repeat/NomVariable/number : 1,2,...
– repeat/NomVariable/letter : a,b,...
– repeat/NomVariable/Letter : A,B,...
– repeat/NomVariable/roman : i,ii,...
– repeat/NomVariable/Roman : I,II,...
– repeat/NomVariable/even
– repeat/NomVariable/odd
– repeat/NomVariable/start
– repeat/NomVariable/end
– repeat/NomVariable/first
– repeat/NomVariable/last
19.8.8 On-error
tal:on-error="Tales"
La valeur de Tales est utilisée pour remplacer l’expression qui a levé une exception dans une autre TAL.
19.8.9 Omit-tag
tal:omit-tag=""
19.9 TALES
19.9.1 Définition
TAL Expression Syntax (language d’expression des opérations possibles)
Tales ::= [Type:]Suite
Type ::= path|string|python|not|exists|nocall
Si Type n’est pas donné, le type path est utilisé (type par défaut).
– path permet d’accéder au rendu d’un objet ou attribut disponible dans la pile d’acquisition de la template ;
– string permet de combiner une expression simple avec du texte ;
– python permet d’évaluer du code python ;
– not permet d’effectuer une négation sur une expression path, string ou python ;
– nocall permet d’accéder à l’objet évalué plutôt qu’à son rendu ;
– exists permet de tester l’existence d’un attribut ou d’une méthode (même formalisme que path).
path, nocall et exists sont des expressions “path”.
Variables implicites :
224
Chapitre 19. TAL/Metal : les templates de Zope et Plone
Plone pour les intégrateurs, Version 1.0.0
– attrs
– container
– default
– context/here
– modules
– nothing
– options
– request
– root
– template
– user
Voir http ://plone.org/documentation/tutorial/zpt/ pour une description.
L’utilisation de here est dépréciée au profit de context.
19.9.2 Exemples
Path
–
–
–
–
–
–
–
path :context/title_or_id
path :context/bobobase_modification_time
path :container/objectValues
path :container/objectIds
path :user/getUserName
path :request/AUTHENTICATED_USER
path :request/URL
Path alternatif et nothing
– path :request/form/custname | context/custname | nothing
Not
– not :request/maVariable
String
string:Quelques mots !
On peut utilise une expression path dans une expression string en l’encadrant par ${}.
– string :Bienvenue ${user/getUserName} !
– string :$$ 30
Nocall
tal:define="doc nocall:here/monDocument" tal:content="string:${doc/id}: ${doc/title}"
Python
python:len(container.objectValues([’File’,’Image’]))
python:context.bobobase_modification_time.strftime(’%d/%m/%Y’)
19.9. TALES
225
Plone pour les intégrateurs, Version 1.0.0
python:test(nombre/2,’Nombre pair’,’Nombre impair’)
python:context.monScript(arg1,arg2)
Possibilité d’utiliser les autres types d’expressions au sein d’une expression python à l’aide des fonctions path(),
string(), exists(), nocall().
python:path(’here/%s/title_or_id’ % currentfolder)
python:path(string(’here/$foldername/thing’))
python:path(’request/form/x’) or default
Accéder à des objets zope
python:getattr(here,’penguin.gif’) (== path:here/penguin.gif)
python:request[’URL’] (== path:request/URL)
python:request.form[’x’] (== path:request/form/x)
python:modules[’math’]
19.10 METAL
Macro Expansion Template Attribute Language (système de macros)
metal:define-macro
metal:define-slot
metal:use-macro
metal:fill-slot
19.10.1 metal :define-macro
Permet de définir une macro que l’on pourra appeler par metal=use-macro.
19.10.2 metal :define-slot
Permet de définir un connecteur dans une macro qui permettra d’insérer du code lors de l’expansion de la macro.
19.10.3 metal :use-macro
Permet d’indiquer que l’on souhaite utiliser une macro définie dans une ZPT.
Ainsi <div metal:use-macro="here/main_template/macros/master"> va chercher la macro
master définie dans la ZPT main_template.
19.10.4 metal :fill-slot
Permet d’insérer du XHTML dans l’espace prévue pour cela dans une macro.
Ainsi <metal:fill fill-slot="main">Mon contenu</metal:fill> permet d’insérer “Mon
contenu” dans la partie metal:define-slot="main" de la zpt appelée par metal-use-macro.
226
Chapitre 19. TAL/Metal : les templates de Zope et Plone
Plone pour les intégrateurs, Version 1.0.0
Tips
Utiliser default
<p tal:content="request/form/info | default">Pas de variable "info" dans la requête.</p>
Afficher du texte dans la template qui ne sera pas rendu par la suite
tal:replace="nothing"
Utilisation d’un dictionnaire dans les expressions path
getPerson est une fonction python qui renvoie le dictionnaire {’name’: ’Toto’, ’age’: 8}.
Accéder à des modules python
tal:define="global mstring modules/string" tal:replace="python:mstring.join(slist, ’:’)"
Module “PythonScripts” de Zope
tal:define="pps modules/Products.PythonScripts.standard"
Gérer une exception
<p>Le prix de l’article est <b tal:content="context/prix" tal:on-error="string:N/A">0.00</b> Euros
19.10. METAL
227
Plone pour les intégrateurs, Version 1.0.0
228
Chapitre 19. TAL/Metal : les templates de Zope et Plone
CHAPITRE 20
Paramétrage local des workflows
–
–
–
–
–
–
Préparation
Installation du module
Gestion des politiques de workflow
Affectation des workflows locaux
Export Generic Setup
Conclusion
Nous allons montrer ici comment affecter, sous Plone 4, des processus documentaires différents selon les rubriques
du site.
Imaginons que nous voulons gérer une partie Intranet et une partie Internet sur notre site Plone. Les permissions
et les circuits de validation ne seront probablement pas les mêmes.
Nous allons donc gérer, grâce à la fonctionalité Support des politiques documentaires locales, un dossier Intranet
dans lequel les documents auront un workflow de type Intranet (les membres peuvent soumettre des documents à
un modérateur, qui publie pour tous les membres), et un dossier Internet, où les documents auront un workflow
avec modération a priori (les membres peuvent soumettre des documents à un modérateur, qui publie soit pour les
anonymes soit pour les seuls membres).
20.1 Préparation
Connectez vous en tant qu’administrateur du site.
Avant de commencer, vous aurez créé à la racine un dossier Intranet et un dossier Internet, que vous aurez publié.
Dans chacun de ces dossiers, vous aurez ajouté une actualité, sans la publier.
20.2 Installation du module
Le système de workflows locaux n’est pas activé par défaut. Nous allons commencer par installer la fonctionnalité.
Allez dans configuration du site, puis modules.
Vérifiez si la ligne Support des politiques documentaire locales (CMFPlacefulWorkflow) apparaît pas dans Modules disponibles. Sinon, vérifiez qu’elle n’est pas déjà dans Modules installés : dans ce cas, passez à l’étape
suivante.
Cochez la ligne Support des politiques documentaire locales (CMFPlacefulWorkflow) dans Modules disponibles,
et cliquez sur Activer.
229
Plone pour les intégrateurs, Version 1.0.0
230
Chapitre 20. Paramétrage local des workflows
Plone pour les intégrateurs, Version 1.0.0
20.2. Installation du module
231
Plone pour les intégrateurs, Version 1.0.0
Le module est maintenant installé.
20.3 Gestion des politiques de workflow
Revenez dans la configuration du site. Dans Configuration de module, cliquez sur la nouvelle entrée : Politiques
documentaires.
Les listes de politiques documentaires existantes par défaut sont affichées.
Il existe déjà une politique ‘Intranet’. Pour en connaître les détails, cliquez sur le titre.
Ce que vous voyez est en fait une version simplifiée de la page de configuration du workflow général, dans la zmi
> portal_workflows. Référez vous à la formation sur les workflows pour davantage d’informations.
Vous pouvez sélectionner le workflow par défaut, et éventuellement un workflow spécifique par type de contenu
(en général on utilise des workflows différents pour les contenus de type rubrique). Les différents workflows disponibles sont ceux décrits dans portal_workflows, onglet ‘Contents’. Référez vous à la formation sur les workflows
pour retrouver comment ajouter et modifier des workflows existants.
Cette configuration conviendra pour notre partie Intranet. Revenons à la page principale de configuration des
processus en cliquant sur “Aller au niveau supérieur”.
Nous pourrions vérifier parmi les trois autres workflows disponibles s’il y en a qui pourraient correspondre à notre
besoin pour la partie Internet. Mais nous allons créer une nouvelle politique pour les besoins de cette formation.
Entrez internet dans le champ Nouvelle politique documentaire, puis cliquez sur Ajouter.
Donnez lui pour titre Publication Internet.
232
Chapitre 20. Paramétrage local des workflows
Plone pour les intégrateurs, Version 1.0.0
20.3. Gestion des politiques de workflow
233
Plone pour les intégrateurs, Version 1.0.0
234
Chapitre 20. Paramétrage local des workflows
Plone pour les intégrateurs, Version 1.0.0
Nous allons choisir, pour les documents, un Processus de publication simple, qui consiste en un circuit privé ->
en attente de validation -> publié pour tous. Pour cela, nous sélectionnons cette valeur pour le champ Processus
documentaire par défaut.
Pour tous les documents sauf Dossier et Collection, nous choisissons Processus par défaut de la politique, qui
renvoit à la valeur choisie ci-avant. Imaginons que dans le cas de notre site Internet, nous n’ayons pas besoin
de valider les dossiers vu que seul l’administrateur pourra en ajouter. Nous choisirons alors un workflow à un
seul état : le dossier est immédiatement publié, seul son contenu est modéré. Nous choisissons donc Processus de
publication à état unique. Supposons que nous voulons que la gestion des Collections soit identique sur le dossier
Internet et au niveau du site. Nous choisirons Acquisition du processus dans les dossiers parents pour Collection :
le workflow sera le même que pour le dossier parent (le site Plone).
Vous pouvez maintenant cliquer sur Enregistrer. Votre politique a été ajoutée.
20.4 Affectation des workflows locaux
Nous allons maintenant associer des workflows différents pour les actualités selon que nous sommes sur l’intranet
ou sur l’internet. Allez dans le dossier Intranet. Cliquez sur le menu État, puis Politique locale.
L’affectation locale des workflows n’est pas activée par défaut dans ce dossier. Vous arrivez donc sur une page
intermédiaire. Cliquez sur Ajouter une configuration locale des politiques documentaires dans le Dossier.
Vous arrivez sur la page de configuration locale des processus. Vous choisissez ici quelle est la politique que vous
voulez activer pour ce Dossier. Sélectionnez dans Pour ce dossier : Intranet, puis enregistrez.
Vous pouvez également faire en sorte que la politique soit associée à tous les sous-dossiers du dossier Intranet,
mais pas au dossier Intranet lui-même. C’est utile, par exemple, quand vous voulez des droits et des validations
différents pour les modifications à la racine de votre rubrique. Dans ce cas, vous choisirez la politique dans En
dessous de ce dossier.
Revenez dans le dossier Intranet. Ce dossier est maintenant en ‘Brouillon interne’ : il est modifiable par les modérateurs et visible par les membres). Si vous vous déconnectez, vous observerez qu’il n’est plus visible aux
anonymes.
Allez sur l’actualité. Vous observerez que les transitions proposées correspondent au workflow Publication internet : en tant qu’administrateur, je peux Publier en interne, c’est-à-dire rendre visible aux membres seulement.
Allez maintenant sur le dossier Internet. Cliquez sur État -> Politique locale. Faites de même, mais sélectionnez
Pour ce dossier -> Publication Internet.
Le dossier est resté à l’état ‘Publié’, mais vous observerez qu’aucune autre transition n’est disponible : nous
utilisons pour les dossiers le workflow Processus de publication à état unique.
Allez dans l’actualité. Vous avez en tant qu’administrateur le choix entre Publier et Soumettre à la publication.
Nous utilisons ici le workflow Processus de publication simple.
20.5 Export Generic Setup
Les politiques documentaires peuvent être exportées en xml via l’outil Generic Setup.
Dans portal_setup > Export, sélectionnez Placeful Workflow Policies puis Export selected steps.
L’outil ne permet pas d’exporter la configuration des politiques locales.
20.6 Conclusion
Nous savions déjà que nous pouvions avoir des processus documentaires différents suivant le type de contenu.
Nous savons maintenant que Plone permet de paramétrer des workflows différents pour un même type de contenu
20.4. Affectation des workflows locaux
235
Plone pour les intégrateurs, Version 1.0.0
236
Chapitre 20. Paramétrage local des workflows
Plone pour les intégrateurs, Version 1.0.0
20.6. Conclusion
237
Plone pour les intégrateurs, Version 1.0.0
mais à différents endroits du site.
Pour conclure, il faut prendre garde à distinguer trois notions, que nous définirons ici :
Processus de publication, ou workflow : c’est la description d’un processus de validation, avec états, transitions,
permissions... On les définit dans la ZMI, dans portal_workflows > Contents.
Politique documentaire : c’est la configuration des workflows pour tous les types de documents du site. On définit la politique par défaut sur la page d’accueil de portal_workflows, et des politiques supplémentaires dans
Configuration du site > Politiques documentaires.
Politique locale : c’est la sélection d’une politique documentaire pour qu’elle s’applique sur une rubrique du site.
On les définit via l’action État > Politique locale sur la rubrique.
238
Chapitre 20. Paramétrage local des workflows
CHAPITRE 21
Déclenchement d’événements avec
les règles de contenu
Plone permet de gérer des déclenchements d’actions avec un très haut niveau de paramétrage, suivant :
– un événement déclencheur (ajout d’un document, d’un utilisateur, passage d’une transition...),
– une / des conditions (état du document, type de document, rôle de l’utilisateur...),
– la localisation sur le site.
Les événements peuvent lancer des actions diverses telles que :
– envois d’emails,
– ajout de log,
– affichage d’un message,
– etc.
–
–
–
–
–
–
–
–
–
–
–
–
–
Objectif de la formation
Préparation
Créer une règle
Paramétrer une règle
Créer une condition
Créer une action
Activer la règle pour une partie du site
Tester la règle
Exemple 2 : Logguer les suppressions de documents
Exemple 3 : Déplacer les événements dans un même dossier, où qu’ils soient ajoutés
Export Generic Setup
Extensibilité
Conclusion
21.1 Objectif de la formation
Nous allons créer :
– une règle qui affiche un message à l’utilisateur et envoie un mail au modérateur lorsqu’une actualité est soumise
à validation dans la partie Intranet,
– une règle qui ajoute une entrée dans les logs à chaque fois qu’un document est supprimé,
– une règle qui déplace tous les événements ajoutés dans la partie Internet dans le dossier Événements.
239
Plone pour les intégrateurs, Version 1.0.0
21.2 Préparation
Il nous faudra un dossier Intranet et un dossier Internet à la racine de notre site (cf. chapitre précédent).
Il faut créer un utilisateur Modérateur Intranet qui ait le rôle Peut Modérer sur le dossier Intranet. Le smtp et
l’email par défaut du site doivent être correctement configurés.
21.3 Créer une règle
Créons la première règle citée ci-dessous.
Pour cela, connectez vous en administrateur, puis allez sur admin > Configuration du site. Cliquez sur ‘règles’.
Vérifiez tout d’abord que la case Activer globalement a bien été cochée. Elle a pour effet d’activer tout le système
de règles. Lorsque vous avez besoin de désactiver provisoirement toutes les règles, le mieux est de décocher cette
case.
Cliquez ensuite sur Ajouter une règle.
Choisissez comme titre : Une actualité a été ajoutée.
Il faut vérifier si la règle s’applique à chaque fois qu’un utilisateur effectue une transition. Sélectionnez comme
déclencheur Workflow state changed.
Puis enregistrez. La règle a été ajoutée. Elle apparaît maintenant dans la liste des règles.
Mais pour l’instant, elle ne se déclenche jamais, et ne fait rien... Il faut la paramétrer.
21.4 Paramétrer une règle
Cliquez sur la règle, vous arrivez à la page de paramétrage de cette règle.
240
Chapitre 21. Déclenchement d’événements avec les règles de contenu
Plone pour les intégrateurs, Version 1.0.0
21.4. Paramétrer une règle
241
Plone pour les intégrateurs, Version 1.0.0
Il nous faut maintenant ajouter les conditions de la règle, et ses résultats.
21.5 Créer une condition
La règle a deux conditions : il doit s’agir d’une actualité, et la transition doit être une soumission à la publication.
Dans la partie Si toutes les conditions suivantes sont remplies, sélectionnez Type de contenu, et Ajouter
Choisissez le type de contenu Actualité, puis enregistrez. La condition a été ajoutée.
De même, ajoutez la condition sur la transition : sélectionnez Ajouter une condition > Transition de workflow puis
Ajouter. Choisissez Soumettre à la publication [submit] puis enregistrez.
21.6 Créer une action
On veut que le modérateur reçoive un mail. Pour Effectue les actions suivantes, sélectionnez Ajouter une action >
Envoyer courriel, puis Ajouter.
Vous arrivez sur la page de paramétrage de l’email. Vous définissez ici le sujet, le texte, les destinataires, etc, en
utilisant un certain nombre de variables fournies de base par Plone.
242
Chapitre 21. Déclenchement d’événements avec les règles de contenu
Plone pour les intégrateurs, Version 1.0.0
Indiquez le sujet de l’email : L’actualité ${title} est en attente de validation. L’emplacement ${title} sera remplacé
par le titre du document au moment de l’envoi.
Comme source du courriel, ne mettez rien : ainsi, la source sera l’adresse du portail.
Comme destinataires, utilisez la variable ${reviewer_emails} : le mail sera envoyé à la liste des modérateurs
(Reviewers)
Entrez enfin un message comme sur cette copie d’écran :
Enregistrez ; votre action a été ajoutée.
Imaginons que les contributeurs de l’intranet craignent que leur demande ne soit pas prise en compte. Nous allons
ajouter un message leur indiquant que les modérateurs ont reçu un mail.
Faites Ajouter une action > Notifier l’utilisateur, puis Ajouter.
Indiquez comme message : Les modérateurs ont été notifiés par mail de votre demande., conservez info comme
type de message, puis enregistrez.
Votre règle a été créée. Il reste maintenant à l’activer dans la partie Intranet du site.
21.7 Activer la règle pour une partie du site
Allez dans la rubrique Intranet, sélectionnez l’onglet Règles.
Vous avez un champ Affecter une règle ici qui propose (uniquement, pour l’instant) la règle Une actualité a été
ajoutée. Cliquez sur Ajouter.
Ceci fait, la règle est maintenant activée pour ce dossier, et seulement celui-ci. Pour l’activer sur tous les sousdossiers de l’intranet, cochez la règle dans le tableau et cliquez sur Appliquer aux sous-dossiers.
Vous pouvez activer / désactiver la règle ici. Si vous l’avez associée à d’autres dossiers via d’autres onglets règles,
seul celui-ci est impacté.
21.7. Activer la règle pour une partie du site
243
Plone pour les intégrateurs, Version 1.0.0
244
Chapitre 21. Déclenchement d’événements avec les règles de contenu
Plone pour les intégrateurs, Version 1.0.0
21.8 Tester la règle
Cliquez sur l’onglet Voir, puis sur une actualité du dossier. Soumettez à la publication le document.
Vous observerez que le message Les modérateurs ont été notifiés par mail de votre demande. apparaît bien. Et le
modérateur a reçu un courriel.
21.9 Exemple 2 : Logguer les suppressions de documents
Dans Configuration du site > Règles, cliquez Ajouter une règle.
21.8. Tester la règle
245
Plone pour les intégrateurs, Version 1.0.0
Appelez-la Un document a été supprimé, choisissez le déclencheur Object removed from this container et enregistrez.
Cliquez sur la règle pour paramétrer les actions.
Nous ne spécifierons pas de conditions particulières ici. Sélectionnez Ajouter une action > Logger puis Ajouter.
Remplacez le Message par Suppression du document &c.
Allez à la racine du site et cliquez sur Règles ; ajoutez la règle Un document a été supprimé. Activez-la pour les
sous-dossiers.
Ajoutez un document sur le site, et supprimez-le. Si votre site est démarré en mode foreground, vous pouvez y
voir le log.
Sinon, consultez vos logs avec la commande tail -f ./var/log/instance.log depuis la racine du
buildout.
21.10 Exemple 3 : Déplacer les événements dans un même dossier, où qu’ils soient ajoutés
Imaginons que nous voulions regrouper tous les événements du site dans un seul dossier, sans contraindre l’utilisateur à être à un endroit particulier du site lorsqu’il ajoute un tel élément.
246
Chapitre 21. Déclenchement d’événements avec les règles de contenu
Plone pour les intégrateurs, Version 1.0.0
Ajoutez une nouvelle règle, que vous appelerez Un événement a été ajouté, avec le déclencheur Objet ajouté au
dossier.
Associez-lui la condition : Type de contenu : Événement.
Ajoutez ensuite l’action Déplacer vers dossier, et choisissez le dossier Événements.
Dans Affectations, cliquez sur le bouton Appliquer la règle sur l’ensemble du site.
Dans le dossier Internet, ajoutez un événement. Allez ensuite dans le dossier Événements, vous verrez qu’il y a
été déplacé. Revenez dans le dossier Internet : il n’y est plus.
21.11 Export Generic Setup
Les règles de contenu peuvent être exportées en xml via l’outil Generic Setup.
Dans portal_setup > Export, sélectionnez Content rules puis Export selected steps. Cela exporte à la fois vos
définitions de règles et les activations des règles sur les rubriques.
Attention : après l’export, vérifiez que l’indentation automatique du xml n’a pas ajouté des espaces non désirés
dans vos messages.
21.12 Extensibilité
Les règles de contenu sont largement extensibles. Il est possible d’ajouter ou créer :
– de nouveaux déclencheurs,
– de nouvelles conditions,
– de nouvelles actions.
Si
vous
avez
des
besoins
spécifiques,
recherchez
sur
pypi
trules
pour
vérifier
si
une
extension
existe
pour
votre
http ://pypi.python.org/pypi ?%3Aaction=search&term=contentrules&submit=search.
le
cas
mot-clé
contend’utilisation
:
Vous pouvez également vous lancer dans le développement de conditions et actions (niveau avancé) avec l’aide
de ce guide http ://plone.org/documentation/kb/creating-content-rule-conditions-and-actions. Ou contactez votre
prestataire Plone favori.
21.11. Export Generic Setup
247
Plone pour les intégrateurs, Version 1.0.0
21.13 Conclusion
Il est possible d’associer à un événement du site et suivant des conditions, sur des parties déterminées du site, des
actions. Un certain nombre de déclencheurs, d’actions et de conditions sont disponibles par défaut. D’autres sont
disponibles en tant qu’extensions. Il est aisé à un développeur d’en créer de nouveaux.
248
Chapitre 21. Déclenchement d’événements avec les règles de contenu
CHAPITRE 22
Créer des pages composées en ligne
avec Collage
Collage permet de composer en ligne, comme des contenus, des pages complexes composées d’éléments organisés
en grille. C’est le moyen idéal de permettre à un webmaster de gérer lui-même ses pages d’accueil.
–
–
–
–
–
–
–
–
–
Préparation
Objectif de la formation
Installer Products.Collage
Créer un Collage
Ajouter les éléments du Collage
Utiliser le collage comme page d’accueil
Paramétrer l’affichage du collage
Extensibilité
Conclusion
22.1 Préparation
Vous n’aurez besoin sur votre site que d’un dossier et de quelques actualités publiées.
22.2 Objectif de la formation
Nous allons associer comme page par défaut d’un dossier une page composée d’une collection d’actualités, d’une
image et d’une actualité complète.
22.3 Installer Products.Collage
Ajoutez à l’entrée eggs de votre buildout la valeur Products.Collage. Relancez le buildout puis redémarrez votre
site. La dernière version du package Products.Collage a été ajoutée à votre environnement Plone.
Il faut maintenant activer le module. Connectez vous en tant qu’administrateur. Allez dans admin > Configuration
du site, puis Modules. Cochez Products.Collage, puis enregistrez.
249
Plone pour les intégrateurs, Version 1.0.0
22.4 Créer un Collage
Allez dans un dossier de votre site, faites Ajout d’un élémént > Collage.
Indiquez un titre et enregistrez. Cliquez sur Composer pour aller sur la page de construction du collage.
Un collage se compose de rangées elles-mêmes divisiées en colonnes, chaque colonne pouvant contenir plusieurs
éléments les uns au-dessus des autres. Ajoutez une première rangée.
Cela ajoute une rangée, contenant par défaut une colonne.
22.5 Ajouter les éléments du Collage
Nous allons composer un collage en deux colonnes sur une ligne. La première colonne contiendra une liste des
actualités, la seconde contiendra une image statique et le rendu d’une actualité.
Cliquez sur créer une colonne. Nous avons maintenant deux colonnes.
Dans la colonne de droite, cliquez sur Insérer un élément existant. Recherchez une actualité et insérez-la.
Vous avez créé un alias sur votre composition, qui affiche le contenu de votre actualité.
Vous pouvez créer un contenu spécifique pour votre composition. Dans la colonne de droite, cliquez sur Créer un
nouvel élément -> Image.
Vous arrivez sur le formulaire de création d’une image. Uploadez une image et publiez-la. Vous observez que la
nouvelle image est un contenu image qui a été ajouté dans un contenu colonne, lui même ajouté dans un contenu
rangée.
Cliquez sur Retour au collage.
Vous souhaitez que l’image s’affiche au-dessus du texte de l’actualité. Cliquez sur la flèche haut de l’image (ou la
flèche bas de l’actualité).
Vous avez changé l’ordre des éléments de la colonne.
250
Chapitre 22. Créer des pages composées en ligne avec Collage
Plone pour les intégrateurs, Version 1.0.0
22.5. Ajouter les éléments du Collage
251
Plone pour les intégrateurs, Version 1.0.0
252
Chapitre 22. Créer des pages composées en ligne avec Collage
Plone pour les intégrateurs, Version 1.0.0
22.5. Ajouter les éléments du Collage
253
Plone pour les intégrateurs, Version 1.0.0
Vous observerez que vous avez directement accès à certaines fonctionnalités des documents, comme par exemple,
la rotation des images (transformer), la copie, etc.
Nous allons créer une collection des actualités dans la colonne de gauche. Faites Créer un nouvel élément >
Collection.
Créez une collection qui affiche toutes les actualités du site. Revenez ensuite au Collage.
Cliquez sur Voir pour observer le résultat.
22.6 Utiliser le collage comme page d’accueil
Publiez le collage, puis assignez-le comme vue par défaut du dossier : sur le dossier, cliquez sur Affichage >
Changer la vue par défaut et sélectionnez votre collage.
Nous ne voulons pas faire apparaître le titre de notre collage Accueil internet sur cette page d’accueil. Allez dans
Modifier > Paramètres. Décochez Afficher le titre et enregistrez.
22.7 Paramétrer l’affichage du collage
Nous allons maintenant tester quelques options de paramétrage de notre collage. Nous pouvons choisir un modèle
pour notre ligne. Sur la ligne, cliquez modèle. Vous avez une liste de layouts disponibles.
Sélectionnez par exemple Gauche large.
Le résultat est manifeste (mais pas forcément très bon... re-sélectionnez le modèle Automatique).
254
Chapitre 22. Créer des pages composées en ligne avec Collage
Plone pour les intégrateurs, Version 1.0.0
22.7. Paramétrer l’affichage du collage
255
Plone pour les intégrateurs, Version 1.0.0
256
Chapitre 22. Créer des pages composées en ligne avec Collage
Plone pour les intégrateurs, Version 1.0.0
22.7. Paramétrer l’affichage du collage
257
Plone pour les intégrateurs, Version 1.0.0
Nous pouvons également choisir un modèle pour les éléments. Cliquez sur modèle de l’actualité, choisissez portlet.
La vue portlet permet de choisir un habillage.
22.8 Extensibilité
Il est possible de développer de nouveaux layouts et de nouveaux types d’éléments pour les compositions de
Collage.
Pour
trouver
les
modules
d’extension
existants,
cherchez
http ://pypi.python.org/pypi ?%3Aaction=search&term=collective.collage&submit=search.
sur
pypi
:
Dans la liste des modules disponibles pour collage, nous avons le produit collective.collage.portlet. C’est un plugin
collage qui nous permet d’avoir des portlets dans notre collage. Nous allons l’installer.
Dans votre buildout.cfg, ajoutez à votre paramètre eggs la valeur collective.collage.portlet. Relancez votre buildout
et redémarrez le site.
Allez dans configuration du site, et installez le module collective.collage.portlet.
Retournez sur votre collage. Ajoutez une colonne. Cliquez sur modèles. Un modèle a été ajouté au modèle standard : portlets. Choisissez-le.
La colonne fournit maintenant une interface permettant de sélectionner un portlet, similaire à celle de la page
‘Gérer les portlets’.
Ajoutez un portlet de modération, et enregistrez.
S’il n’existe pas de plugin correspondant à vos besoins, contactez votre prestataire Plone favori :).
22.9 Conclusion
Le module collage permet de créer des pages composées.
258
Chapitre 22. Créer des pages composées en ligne avec Collage
Plone pour les intégrateurs, Version 1.0.0
22.9. Conclusion
259
Plone pour les intégrateurs, Version 1.0.0
260
Chapitre 22. Créer des pages composées en ligne avec Collage
Plone pour les intégrateurs, Version 1.0.0
22.9. Conclusion
261
Plone pour les intégrateurs, Version 1.0.0
262
Chapitre 22. Créer des pages composées en ligne avec Collage
Plone pour les intégrateurs, Version 1.0.0
22.9. Conclusion
263
Plone pour les intégrateurs, Version 1.0.0
264
Chapitre 22. Créer des pages composées en ligne avec Collage
Plone pour les intégrateurs, Version 1.0.0
On organise des contenus en lignes et en colonnes. Ces contenus peuvent être des alias de documents du site, des
collections, ou des contenus embarqués.
On peut présenter les éléments de la composition suivant différents modèles, voire avec différents habillages.
Ces compositions sont idéales pour construire des pages d’accueil de sites ou de rubriques.
Des plugins existent pour étendre les éléments disponibles pour vos compositions.
22.9. Conclusion
265
Plone pour les intégrateurs, Version 1.0.0
266
Chapitre 22. Créer des pages composées en ligne avec Collage
CHAPITRE 23
Glossaire
Définition des termes et abréviations utilisés dans ce document.
adapter Classe Python fournissant aux objets exposant une certaine interface des services supplémentaires, sans
utiliser directement la technologie d’héritage Python. Les adapteurs font partie des concepts amenés par la
ZCA (Zope Component Architecture).
adaptateur Traduction libre de adapter.
AT Abréviation courante d’Archetypes utilisée dans les documentations, blogs, mailing-lists, forums ayant trait
à Plone.
brain Toute requête au catalogue fournit une itération de brains. Chaque brain étant une référence à un élément
de contenu, et incorpore la copie de certains attributs de celui-ci (titre, description, ...). cheeseshop voir pypi.
buildout Buildout – ou zc.buildout – est un outil multi-plateformes conçu pour installer et paramétrer les différents composants logiciels d’un système d’informations. Plone est installable par ce mode depuis sa version
2.5. zc.buildout permet en outre de personnaliser l’installation des composants qui concourent à l’installation de “votre” site Plone en modifiant son fichier de configuration. Le packaging sous forme d’eggs est
favorisé.
C Langage compilé de bas niveau utilisé pour coder - entre autres - Linux et Python. Un compilateur C est
nécessaire pour installer Zope ainsi que de nombreuses extensions Python.
component Package Python fournissant des fonctionnalités supplémentaires à Zope ou Plone. Les composants
sont installés le plus souvent dans $INSTANCE_HOME/lib/python, et plus généralement dans les répertoires du système de fichiers désignés par la directive path du fichier de configuration de votre instance
Zope. L’extension de Zope ou Plone par composants est la méthode recommandée pour faciliter la future
migration vers le pur Zope 3. Attention, si un composant comporte des directives ZCML, celui-ci doit être
déclaré dans la configuration de de votre instance Zope.
composant Traduction libre de component.
configlet Panneau de configuration de Plone permettant de paramétrer de façon globale certains aspects de Plone.
Par exemple, le panneau de configuration des utilisateurs et des groupes ou le thème graphique. Certains
composants d’extension de tierce partie ajoutent leur panneau de configuration.
content type Un type de contenu est le moule avec lequel tous les élément d’un certain type sont gérés. Un type
de contenu incorpore les dispositifs suivant :
– factory de création de l’élément
– vues HTML de l’élément schéma d’informations portées par l’élément, incluant ses méta-données
– formulaires de création/modification de ce schéma d’informations
– services “métier” proposés par l’élément.
distribute Distribute est une refonte et une alternative à setuptools élaborée à l’initiative de Tarek Ziadé.
distribute fournit les outils de packaging, de distribution et d’installation de packages Python sous
forme d’egg.
Nous recommandons vivement l’utilisation de distribute dont les contributeurs sont bien plus réactifs
que ceux de setuptools. Bien entendu, distribute est packagé sous forme d’egg.
267
Plone pour les intégrateurs, Version 1.0.0
distutils distutils est un package fourni en standard avec Python fournissant les outils de packaging. distribute s’appuie sur distutils et on préfèrera l’utilisation de ce dernier qui fournit des outils plus avancés.
dotted name Il n’y a pas de traduction en français facile et concise pour ce terme. Un dotted name permet
- généralement dans un fichier ZCML - de désigner un symbole Python quelconque (objet, classe, fonction,
...) sous la forme d’une chaîne de caractères proche de celle utilisée par le mot clé Python import. Par
exemple, le dotted name foo.bar.stuff représente l’équivalent en python from foo.bar import
stuff.
En outre, la notation dotted name admet la notation de package relatif par l’utilisation du préfixe ..
Par exemple .foo.bar dans un fichier ZCML permet de référencer l’objet (classe, fonction, ...) bar du
module foo.py lorsque ce module figure dans le même répertoire que le fichier ZCML. Un préfixe de
deux points (..) permet d’accéder au répertoire parent de celui incluant le fichier ZCML et ainsi de suite.
egg Packaging d’un module Python incluant ses méta-données telles que sa version, sa documentation et les
éventuelles dépendances d’autres eggs. La grande majorité des eggs publics sont distribués sur le site pypi.
Reportez-vous au chapitre Concept de Python eggs pour plus de détails.
eggs Voir egg.
élément (de contenu) ou “content item”. Unité atomique de contenu fournie par un auteur, tel qu’un document,
une image, un fichier. Certains types d’éléments, tel que le dossier ou la collection sont dits également conteneurs ou “folderish” de par leur aptitude à contenir d’autres éléments de la même façon qu’un répertoire
peut inclure d’autres fichiers et répertoires dans un disque dur.
groupe (d’utilisateurs). Un groupe d’utilisateurs permet d’associer un ensemble d’utilisateurs à une fonction
dans un site Plone. Ceci permet - principalement - d’octroyer des droits particuliers, élément par élément,
à tout un ensemble d’individus par le biais de l’onglet partage. Les groupes d’utilisateurs sont gérés par
PlonePAS à travers le configlet Utilisateurs et groupes. Un utilisateur peut appartenir à autant de groupes
que nécessaire, voire aucun groupe. Un groupe peut appartenir à un autre groupe (imbrication).
i18n Abréviation commune du terme “internationalisation” (il y a 18 lettres entre le “i” et le “n” de “internatonalisation”). Opération consistant à marquer le code (Python, templates, ...) pour lui permettre de fournir les
textes de l’interface utilisateur en différents langages. Voir l10n.
interface (en Python) : Une interface est une classe spéciale décrivant l’API publique de toute autre classe
l’implémentant. L’utilisation des interfaces est à la base de la ZCA.
invite de commandes Logiciel vous invitant à contrôler votre système en fournissant des commandes et en lisant
le compte-rendu des dites commandes. Jusque dans les années 80, l’invite de commandes était l’unique
moyen de contrôler un ordinateur. Sous Windows, l’invite de commandes est fournie par le logiciel cmd.exe‘
alors que sous Unix - le choix est plus vaste - le couple xterm et bash est généralement utilisé.
l10n Abréviation commune de “localisation” (il y a 10 lettres entre le “l” et le “n” de “localisation”). Opération
consistant à fournir les textes de l’interface utilisateur d’un logiciel (d’un composant Plone) dans un langage
particulier. Voir i18n.
msi installer Format de bundle d’installation du monde Windows. Les fichiers de ce type ont l’extension .msi.
multiplugin Un plugin ayant l’aptitude de remplir plusieurs rôles, donc, généralement implémentant plus d’une
interface. Un plugin pour PAS est d’ailleurs généralement un multiplugin.
part Une part est une section d’un fichier buildout contenant une variable recipe définissant le rôle de la part
dans le processus d’installation global défini par la configuration buildout. Une part n’est exécutée que si
elle est référencée dans la liste parts = ... de la section [buildout].
parts voir part.
permission Protection d’accès à un objet dont la sécurité est gérée par Zope.
permissions voir permission.
PAS Aréviation de PluggableAuthService, la base du service de gestion des utilisateurs, rôles et groupes de
Plone. Voir le chapitre Gestion des utilisateurs avec PlonePAS.
paster Couteau suisse du développeur d’applications Python. Voir http ://pythonpaste.org/index.html
PATH Variable d’environnement utilisée par votre système d’exploitation pour trouver les logiciels invoqués
par l’invite de commandes. Cette variable d’environnement est constituée d’une liste de répertoires, séparés
par : pour Unix et ; sous Windows.
268
Chapitre 23. Glossaire
Plone pour les intégrateurs, Version 1.0.0
plugin Se dit d’un composant logiciel (fonction, classe, ou objet) s’intégrant dans une infrastructure existante et
ayant une interface et un rôle pré-défini vis-à-vis de cette infrastructure (le rôle est généralement défini par
une interface), mais implémentant le rôle d’une façon qui lui est propre. Les logiciels de type “plugin” sont
légion dans le monde de Plone, et plus notamment dans le service de gestion des utilisateurs PAS. Voir le
chapitre Gestion des utilisateurs avec PlonePAS.
PMI Plone Management Interface : Ensemble des formulaires fournis par Plone et ses éventuelles extensions
permettant de gérer et paramétrer le contenu et les services.
portlet Petite boite d’interface utilisateur située dans la colonne gauche d’un portail Plone. Les conditions d’apparition et les interfaces des portlets est automatiquement calculé en fonction du contexte (droits de l’utilisateur, et emplacement de navigation). L’outil de navigation et le calendrier sont des exemples de portlets.
Dans la grande majorité des cas, les portlets ne font pas strictement partie du contenu.
policy package Un policy package est un composant pour Plone défininissant la politique éditoriale du site,
et - éventuellement - sa logique métier spécifique. un policy package a également pour rôle d’installer et
paramétrer de façon spécifique Plone et les différents composants de tierce partie ajoutés.
principal Agent du système Zope exécutant une action. Un agent dispose de permissions sur les objets Zope pour
exécuter ces actions. Dans les applications Zope ou Plone, vous ne verrez que deux types de principals :
les utilisateurs (ou membres) et les groupes.
product Package Python fournissant des fonctionnalités supplémentaires à Zope ou Plone. Les produits sont
installés le plus souvent dans $INSTANCE_HOME/Products, et plus généralement dans les répertoires
du système de fichiers désignés par la directive “products” du fichier de configuration de votre instance
Zope. L’extension de Zope et Plone par produits est un héritage des anciennes versions de Zope, facilitant
ainsi l’adaptation d’extensions Zope ou Plone conçues pour des versions antérieures. Il est en conséquence
recommandé de réaliser dorénavant des composants (voir plus haut) pour ajouter des fonctionnalités à Zope
ou Plone.
produit Traduction libre de product.
profil Traduction libre de profile.
profile (GenericSetup) : un profil désigne un lot de fichiers XML définissant le paramétrage appliqué à un site
Plone permettant l’utilisation dans le dit site des ressources d’un composant ou d’un produit. Les fichiers
d’un profil GenericSetup sont – généralement – placés dans le sous-répertoire profiles/default d’un
composant ou produit.
propertysheet En français : feuille de propriétés. Dans Plone, il y a deux types de feuilles de propriétés :
– Les feuilles de propriétés servant à conserver des propriétés globales du site, celles-ci se trouvant dans le
tool portal_properties
– Les feuilles de propriétés dynamiques associées aux utilisateurs et aux groupes.
pypi
PYthon Packages Index, anciennement appellé cheeseshop, est le site dans lequel la grande majorité des packages open source Python sont mis à la disposition du public. Sa page d’accueil est
http ://pypi.python.org/pypi
pywin32 Package Python pour Windows - disponible pour les architectures 32 et 64 bits - fournissant l’accès
aux services système spécifiques à ce système d’exploitation : contrôle des services, de la base de registres,
accès COM ou DCOM aux applications, accès à Exchange et Active Directory, extensions et filtres ISAPI,
etc, etc.
recipe Peut être traduit en français par “recette”. Une recipe définit le rôle d’une part d’une configuration buildout
(exemples : installation/paramétrage d’Apache, instalation d’un client ZEO, fichier de comfiguration défini
par une template, ...). La plupart des recipes disponibles sont disponible dans le site Pypi à cette adresse.
rôle Un rôle regroupe un ensemble de permissions. Tout visiteur dispose d’un ou plusieurs rôles, soit de façon
globale, soit de façon contextuelle.
SSO Single Sign On ou Authentification unique. Agent permettant de n’effectuer qu’une seule authentification
pour accéder à plusieurs sites. Comme par exemple pour Google apps (mail, agendas, documents). Voir
http ://fr.wikipedia.org/wiki/SSO
structural folder Type de contenu permettant à un contributeur d’y inclure les contenus de son choix. A contrario, le “non structural folder” permet pas à un contributeur de structurer librement son contenu. Les composants de tierce partie Products.PloneArticle et Products.Collage fournissent des exemples
de “non structural folder”.
269
Plone pour les intégrateurs, Version 1.0.0
tool Dans un contexte CMF, donc Plone, un “tool” est un objet unique dans un site fournissant un ensemble de
services et incorporant ses propres données persistantes de configuration. Les tools se trouvent à la racine de
Plone et leurs noms sont généralement préfixés par portal_. portal_properties abrite les feuilles
de propriétés de Plone et de la plupart des composants d’extension de tierce partie. portal_catalog
indexe les contenus du site...
TTW Ou “Through The Web”. Qualifie généralement le paramétrage ou la programmation d’une application
Zope depuis des formulaires accessibles uniquemant à un administrateur ou un auteur authentifié. La ZMI
est le principal outil Zope de programmation ou de paramétrage TTW.
type de contenu Traduction libre de content type.
unified installer Bundle d’installation complète de Plone, incluant Python, Zope, Plone ainsi que tous les modules requis (PIL, elementtree, ...). L’unified installer est disponible pour Windows, Mac OSX et Linux.
viewlet Une viewlet est responsable du rendu d’un composant de page, donc de la réalisation d’un bloc - generalement - HTML. Les viewlets sont généralement assemblées par un viewlet manager.
viewlet manager Un viewlet manager permet d’assembler les viewlets. L’utilisation de viewlets et de viewlet
managers permet une disposition plus souple des composants d’une page que les classiques macros ZPT
ainsi que des performances de publication améliorées.
virtualenv
virtualenv est un outil permettant de créer des installations virtuelles de Python (presque) indépendantes du Python installé de façon globale dans votre système, de sorte que tout egg ajouté dans
une installation virtuelle ne vient pas “polluer” votre installation globale. Par extension, on appelle un
“virtualenv” tout environnement virtuel créé avec cet outil. Reportez-vous au chapitre Création d’un
environnement isolé avec virtualenv pour plus de détails. Ou bien sur la page d’accueil de virtualenv
widget Élément unitaire d’une page permettant au serveur de solliciter une information à l’utilisateur. Les widgets sont généralement assemblés dans un formulaire. Plone fournit bien évidemment tous les widgets standard du langage HTML (cases à cocher, boutons, listes déroulantes, champ de saisie de texte, ...). Ses divers
composants, notamment la bibliothèque zope.formlib, KSS et Archetypes proposent des widgets plus
évolués tel que des calendriers, éditeur WYSIWYG, arbres d’exploration, ...
workflow Outil permettant de définir les différents états d’un élément, et les transitions permettant de passer
d’un état à un autre. Pour chaque état, un sous-ensemble de permissions de cet élément fixe la limite les
différents types d’accès à celui-ci. Par exemple pour interdire la vue à un utilisateur anonyme. L’exécution
de chaque transitions est protégée de façon spécifique. Par exemple, seul un modérateur peut exécuter la
transition “publier” Dans Pone, les workflows sont définis en ZMI à l’aide de l’outil DCWorkflow. Certains
types d’éléments, comme l’image, ne sont pas associés à un workflow.
ZCA Zope Component Architecture : Ensemble de services intégrés dans Zope 3, et adaptés à Zope 2 depuis
sa version 2.9 par l’entremise de Five. La ZCA fournit les outils facilitant la collaboration entre objets et
services de natures différentes concourant à la réalisation de fonctions applicatives, tout en évitant les pièges
d’un héritage complexe de classes. Par exemple, vous disposez d’un composant (A) d’exploration AJAX
d’arbre virtuel, d’un autre composant (B) gérant un contenu pouvant être représenté de façon arborescente,
il vous suffira de fournir les adapteurs permettant d’explorer le contenu des objets fournis par B à l’aide
des widgets fournis par A. Ceci ne peut bien entendu être possible que si ces deux composants exposent les
ressources ZCA (généralement des interfaces) permettant ceci. L’utilisation de la ZCA, entamée par Plone
depuis sa version 2.5, se généralise depuis sa version 3. Plus de détails dans concepts_zope3.
zc.buildout voir buildout.
ZCML Zope Configuration Markup Language : Langage basé sur XML permettant de configurer des composants
ou produits pour Zope ou Plone dans des fichiers configure.zcml ou overrides.zcml.
zexp Format binaire d’exportation et d’importation d’un objet (et éventuel sous-objets) de la ZODB. Pour exporter ou importer un fichier au format zexp, cliquez le bouton Import/Export et suivez les instructions.
ZODB Zope Object Data Base : base de données objets native de Zope.
ZMI Zope Management Interface : Interface Web de paramétrage et contrôle d’une instance Zope, permettant
l’exploration de la ZODB.
270
Chapitre 23. Glossaire
CHAPITRE 24
Indexes et tables
– genindex
– modindex
– search
271
Plone pour les intégrateurs, Version 1.0.0
272
Chapitre 24. Indexes et tables
CHAPITRE 25
Contributeurs
–
–
–
–
Vincent Fretin
Gilles Lenfant
Thomas Desvenain
Michaël Launay
273
Plone pour les intégrateurs, Version 1.0.0
274
Chapitre 25. Contributeurs
Index
Symbols
multiplugin, 268
élément, 268
P
A
part, 268
parts, 268
PAS, 268
paster, 268
PATH, 95, 268
permission, 268
permissions, 268
plugin, 269
PMI, 269
policy package, 269
portlet, 269
principal, 269
product, 269
produit, 269
profil, 269
profile, 269
propertysheet, 269
pypi, 269
pywin32, 269
adaptateur, 267
adapter, 267
AT, 267
B
brain, 267
buildout, 267
C
C, 267
component, 267
composant, 267
configlet, 267
content type, 267
D
distribute, 267
distutils, 268
dotted name, 268
E
egg, 268
eggs, 268
G
groupe, 268
I
i18n, 268
interface, 268
invite de commandes, 268
R
rôle, 269
recipe, 269
S
SSO, 269
structural folder, 269
T
tool, 270
TTW, 270
type de contenu, 270
L
U
l10n, 268
unified installer, 270
M
V
msi installer, 268
variable d’environnement
275
Plone pour les intégrateurs, Version 1.0.0
PATH, 95
viewlet, 270
viewlet manager, 270
virtualenv, 270
W
widget, 270
workflow, 270
Z
zc.buildout, 270
ZCA, 270
ZCML, 270
zexp, 270
ZMI, 270
ZODB, 270
276
Index
Téléchargement