CPS 3 Guide du d´velopp eur e
Herv´ Cauwelier e Anahide Tchertchian 23 mars 2005
ii
Table des mati`res e
1 Autour de CPS 3 1.1 Un portail collaboratif ? . ` 1.2 A qui s'adresse ce livre ? . 1.3 Ce qui fait CPS 3 . . . . . 1.3.1 Les produits CPS . 1.3.2 Les outils de CPS 1.4 Probl´matique de ce livre e
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
1 1 2 2 3 4 7 8 8 10 12 13 13 14 16 20 20 24 25 29 29 30 32 35 36 39 40 44 44 44 44 48 49
2 Premiers pas dans la p ersonnalisation 2.1 Le bon r´flexe : cr´er un produit . . . . . . . . . . . . . . . . . e e 2.2 Personnaliser CPS . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Changer les propri´t´s du portail . . . . . . . . . . . . . . . . . ee 2.4 Manipuler les bo^tes . . . . . . . . . . . . . . . . . . . . . . . . i 2.4.1 Qu'est-ce qu'une bo^te ? . . . . . . . . . . . . . . . . . . i 2.4.2 Supprimer des bo^tes et en a jouter automatiquement . . i 2.4.3 Changer les bo^tes par d´faut : le logo et le pied de page i e 2.4.4 Ajouter des bo^tes locales . . . . . . . . . . . . . . . . . i 2.5 Changer les propri´t´s des feuilles de style . . . . . . . . . . . . ee 2.6 Cr´er l'arborescence du site . . . . . . . . . . . . . . . . . . . . e 2.7 Le squelette du site : main template.pt . . . . . . . . . . . . . . 3 Int´gration avanc´e e e 3.1 Cr´er nos types de documents . . . . . . . . . . . . . . . . . e 3.1.1 Les sch´mas . . . . . . . . . . . . . . . . . . . . . . . e 3.1.2 Les widgets . . . . . . . . . . . . . . . . . . . . . . . 3.1.3 Le layout . . . . . . . . . . . . . . . . . . . . . . . . 3.1.4 Le type de document . . . . . . . . . . . . . . . . . . 3.1.5 Activer ce type dans le portail . . . . . . . . . . . . 3.1.6 Rendre le document flexible . . . . . . . . . . . . . . 3.2 Changer les r`gles de s´curit´ . . . . . . . . . . . . . . . . . e e e 3.2.1 Restreindre l'acc`s aux annuaires . . . . . . . . . . . e 3.3 Les workflows . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1 Le m´canisme de workflow et les workflows existants e 3.3.2 Changer les r`gles des workflows . . . . . . . . . . . e 3.4 L'internationalisation de l'application . . . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
i
4 D´velopp er p our CPS e 50 4.1 Cr´er un type de bo^te . . . . . . . . . . . . . . . . . . . . . . . . 50 e i 4.2 Cr´er un type de widget . . . . . . . . . . . . . . . . . . . . . . . 56 e 4.3 Cr´er un workflow . . . . . . . . . . . . . . . . . . . . . . . . . . 56 e A Pour aller plus loin B Ressources sur CPS B.1 CPS Pro ject . . . . . . B.2 cps-users-fr . . . . . . B.3 cps-users . . . . . . . . B.4 cps-devel . . . . . . . . B.5 CPS 3 Book . . . . . . B.6 Da Zope French Page 58 59 59 59 59 59 59 60 61 61 61 61 61 61 62 63 64 70 74
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
C Ressources sur Zope et CMF C.1 Zopeuse.org . . . . . . . . . . C.2 Zope Book . . . . . . . . . . . C.3 French Zope Book . . . . . . C.4 Zope Developer Guide . . . . C.5 Zope Labs . . . . . . . . . . . C.6 Documentation DCWorkflow D Script d'initialisation E Script d'installation F Macros des b o^tes i G Fichier d'arb orescence
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
ii
Table des figures
2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 2.14 2.15 2.16 2.17 2.18 2.19 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 4.1 4.2 4.3 4.4
Code minimal pour d´clarer ses r´pertoires de skins. e e Code minimal d'installation d'un produit. . . . . . . Code d'installation compl´t´ pour les skins. . . . . . ee Aspect par d´faut d'un site CPS flambant neuf. . . . e Formulaire de reconfiguration du portail. . . . . . . . Changer automatiquement les propri´t´s du portail. ee Code de base pour g´rer les bo^tes et les supprimer. e i Dictionnaire de d´finition des nouvelles bo^tes. . . . e i Code d'a jout des nouvelles bo^tes. . . . . . . . . . . i Contenu de nos bo^tes personnelles. . . . . . . . . . . i D´finition de nos types de bo^tes. . . . . . . . . . . . e i Le dictionnaire des bo^tes par d´faut chang´es . . . . i e e Code de modification des bo^tes par d´faut . . . . . i e Notre site avec les nouvelles bo^tes en place. . . . . . i La nouvelle charte graphique du site. . . . . . . . . . Code de chargement de l'arborescence . . . . . . . . Code d'a jout du plan du site . . . . . . . . . . . . . Le plan du site a fi`re allure. . . . . . . . . . . . . . e Le site dans son aspect final. . . . . . . . . . . . . . Aspect de l'´cran de cr´ation d'un sch´ma. e e e D´finition des sch´mas de nos propres types e e Aspect de l'´cran de cr´ation d'une instance e e Aspect de l'´cran de cr´ation d'un layout. . e e D´finition de la mise en page de nos types . e D´finition de nos types de documents . . . e D´finition du layout flexible . . . . . . . . . e D´finition du type de document flexible . . e La repr´sentation de workflows. . . . . . . . e Le workflow de CMF. . . . . . . . . . . . . Le workflow de CPS. . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11 11 12 12 26 26 26 26 26 26 26 26 26 27 27 27 27 28 28 31 32 34 35 36 38 43 44 45 46 47 51 51 52 52
....... ....... de widget. . ....... ....... ....... ....... ....... ....... ....... ....... . . . . . . . . . . . .
Imports n´cessaire ` la bo^te de fortunes . . . . . . e a i D´claration de la factory type information . . . . . e V´rification au d´marrage de la commande fortune e e D´claration de la classe FortuneBox . . . . . . . . e
iii
TABLE DES FIGURES 4.5 4.6 4.7 4.8 4.9 4.10 4.11 4.12 Constructeur de la classe FortuneBox . . . . . . . . . . . . M´thode de r´cup´ration des fortunes . . . . . . . . . . . e e e M´thodes de mise en forme du texte de la fortune . . . . e Initialisation et constructeur Zope de la classe . . . . . . . D´claration des ob jets de notre module . . . . . . . . . . e D´claration des variantes de la bo^te de fortunes . . . . . e i Code d'a jout du nouveau type dans le script d'installation La bo^te de fortune ins´r´e dans le site. . . . . . . . . . . i ee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 53 53 53 54 54 55 57
iv
Chapitre
1
Autour de CPS 3
Le Diable est une femme et vous vous en doutiez : La place d'une femme n'est-el le pas au foyer ? ´ Juliette, L'Eternel f´minin e
1.1
Un p ortail collab oratif ?
La notion de portail et d'outil collaboratif est clairement au centre du d´bat e pour les syst`mes d'informations actuels. Le portail met ` la disposition des e a utilisateurs (clients et employ´s de l'entreprise) un outil fonctionnel et pr´sentant e e une interface adapt´e ` leurs besoins. ea Au del` de l'aspect collaboratif et du travail de groupe, le portail est aussi un a outil de gestion documentaire. Les proc´dures et les documents papier prennent e vie sous forme ´lectronique pour assister l'utilisateur dans son travail, faciliter e les proc´dures et faire acc´l´rer les temps de traitement. e ee La combinaison d'un portail et du r´seau, priv´ dans le cas d'un intranet ou e e public, en clair Internet, pousse le concept vers la notion de bureau virtuel : le navigateur web devient le seul logiciel ou presque, n´cessaire pour travailler. e Bien qu'on puisse aussi imaginer un outil complet de bureautique accessible en ligne. . . Le logiciel dont il est question, Col laborative Portal Server (CPS), r´pond ` e a cette demande. Logiciel libre, publi´ sous licence General Public License (GPL), e il offre une plate-forme de travail collaboratif, con¸u pour la gestion documenc taire. CPS 3 vient remplacer la version pr´c´dente, num´rot´e 2, en remettant ` ee ee a plat beaucoup de choix techniques pour offrir ` l'utilisateur une meilleure exp´a e rience avec une interface agr´able et rapide ; le d´veloppeur profite aussi d'une e e architecture plus simple ` ´tendre, ` int´grer et pour d´velopper de nouveaux ae a e e produits.
1
` 1.2. A QUI S'ADRESSE CE LIVRE ?
1.2
` A qui s'adresse ce livre ?
Ce livre ne se veut pas un manuel complet de CPS. Il s'adresse sp´cifiquement e ` ceux qui ont besoin de personnaliser CPS au-del` de ce que permet l'interface a a en ligne de l'outil. Typiquement, si vous avez besoin de modifier en profondeur l'apparence du site par d´faut ou de l'´tendre par de nouveaux types de bo^tes e e i ou de documents, ce livre est fait pour vous. Je me dois donc de supposer un certains nombre de pr´-requis : e Savoir installer et utiliser Zope et ses outils de d´veloppement Vous avez e install´ et configur´ la version de Zope requise par CPS 3. Vous sae e vez donc utiliser la ZMI, vous savez utiliser l'ob jet error log et vous savez lire les logs du serveur en cas de probl`me. Une connaissance du e d´veloppement pour Zope me para^t tout aussi indiqu´e ; ce qui souse i e entend que vous savez ´crire des programmes en Python et des Pages e Templates et que avez d´j` probablement eu affaire au Zope Book. Vous seea rez surement ravi d'apprendre qu'une traduction en fran¸ais est en cours : ^ c http://www.zope.org/Members/herve/zopebook/ Savoir installer CPS Je pars du site CPS par d´faut donc vous devez l'avoir e cr´´ sur un serveur de test. Dans le cas contraire, reportez-vous ` la docuee a mentation accompagnant la distribution du logiciel ou consultez le guide de l'utilisateur. Savoir utiliser CPS Vous ^tes familier avec l'interface par d´faut de CPS et e e si je vous demande d'aller ` la page de gestion des bo^tes ` la racine, vous a i a saurez ou cliquer sans h´sitation. La cr´ation d'une nouvelle bo^te ` droite ` e e ia pour afficher les derniers documents de type Br`ve publi´s ne doit pas non e e plus vous effrayer. Si c'´tait malheureusement le cas, la lecture du guide e de l'utilisateur devrait faire lever vos derniers doutes.
1.3
Ce qui fait CPS 3
Je ne compte plus le nombre de fois que j'ai cit´ le nom du produit mais quel e est-il au niveau technique exactement ? CPS est un ensemble de produits (au sens Zop e, ou composants), chacun d´di´ ` une t^che, qui s'appuie sur le framee ea a work CMF. Ce dernier offre les services de base pour ´crire des portails, avec e gestion par des r`gles de workflow et est lui-m^me bas´ sur Zope, un serveur e e e d'application ´crit en Python. e Pour r´sumer ce point de vue technique, CPS est une combinaison de logiciels e con¸ue pour offrir un portail ` haute valeur a jout´e, ` la fois abouti et extensible. c a ea Une partie des produits ´crits pour CPS peut ^tre utilis´e ind´pendamment par e e e e les d´veloppeurs de CMF et de Zope. e Nous verrons dans un premier temps quel est le r^le de chaque produit CPS. o Nous expliquerons ensuite quels sont les outils de CPS visibles dans la ZMI.
2
1.3. CE QUI FAIT CPS 3
1.3.1
Les pro duits CPS
Voyons le r^le de chaque produit : o CPSCore CPSCore est litt´ralement le coeur de CPS. Il contient le moteur de e r´vision et de traduction des documents. Il g`re aussi le d´p^t documene e eo taire qui contient toutes les versions et les traductions de chaque document du site. En pratique, le document que vous manipulez est une r´f´rence ee vers une r´vision dans une langue pr´cise disponible dans le d´p^t. CPSe e eo Core offre aussi la notion d'´v´nements, par exemple la publication d'un ee document d´clenche un ´v´nement que recevront les services qui en auront e ee fait la demande. Le dernier point essentiel est qu'il fournit les services de workflow aussi bien pour tout le site que pour un emplacement particulier du site. CPSSchemas Ce produit recoupe la notion de typologie documentaire : un document est une structure d´finie ` partir d'un formulaire. Ce formulaire e a contient des champs, et il est possible de contr^ler la mise en page de ces o derniers, ainsi que les valeurs qui sont accept´es. Il y a quatre notions ` e a retenir : le field qui est le champ pour stocker une valeur (cha^ne, nombre, i date/heure, etc.) ; le widget qui est la repr´sentation du champ et qui va e valider ou non la valeur fournie ; le layout qui est la mise en page du document dans ses diff´rents modes (visualisation, ´dition, cr´ation, etc.) ; et e e e le vocabulary, qui est une liste de valeurs ordonn´e, venant d'un dictione naire ou calcul´es par une fonction, pour les champs qui en ont besoin. e Les sch´mas servent aussi ` d´crire les annuaires de CPSDirectory. e ae CPSDo cument Ce produit utilise CPSSchemas pour proposer des types de documents par d´faut : Br`ve, Fichier, Image, etc. Ces derniers peuvent e e ^tre personnalis´s au niveau de leur mise en page (layout ), soit par la ZMI, e e soit en utilisant le type Document flexible. Si l'administrateur l'a autoris´, e je peux a jouter une image au squelette de br`ve propos´ par d´faut. Les e e e documents se conforment de pr´f´rence au Dublin Core pour ce qui est des ee m´ta-donn´es. Il existe aussi les documents dits folderish qui permettent e e de stocker plusieurs documents ensemble mais de les publier en une seule fois. CPSDirectory Cet annuaire remplace NuxMetaDirectories, utilis´ dans la e version 2. Il propose les m^mes fonctionnalit´s : annuaires de toutes sortes, e e stock´s dans LDAP ou dans la ZODB. Les annuaires les plus courants e sont les annuaires de membres, de groupes et de r^les. La structure de o chaque annuaire est d´crite par son sch´ma et repr´sent´e par son layout . e e e e Il fonctionne donc de pair avec CPSSchemas, widgets inclus. CPSDefault Il s'agit en fait de l'impl´mentation par d´faut de CPS, donc e e le site pr^t-`-l'emploi que vous utilisez tel quel, que vous adaptez ` vos ea a besoins ou dont vous vous inspirez pour ´crire votre propre site ` partir e a des services de CPS. Tout ce qui est bo^te, la plupart des traductions, i les sections de publication et les espaces de travail, ainsi que les r`gles de e workflow par d´faut proviennent de CPSDefault. e CPSInstaller TODO CPS utilise d'autres logiciels pour son fonctionnement. Je ne reviens pas sur CMF, dont le r^le a d´j` ´t´ explicit´. Ces produits sont les suivants : o eaee e 3
1.3. CE QUI FAIT CPS 3 CPSRSS Ce produit apporte un type de bo^te qui permet d'afficher les infori mations publi´es par de plus en plus de site au travers de la « syndication e ». CPSForum CPS 3 propose un forum adapt´ ` sa nouvelle architecture. ea CPSMaib oxer TODO CPSSubscriptions TODO Lo calizer Voyez Localizer comme un gros catalogue ` qui on demande quelle a est la traduction de, par exemple, cps_is_cool dans la langue choisie par l'utilisateur en cours. cps_is_cool est l'idiome utilis´ dans le code : il sera e remplac´ par la phrase associ´e qui lui est associ´e dans la langue choisie. e e e Non, ne cherchez pas cette traduction dans le catalogue. TranslationService Ce produit se combine ` Localizer pour remplacer ` la voa a e l´e les cha^nes comme « cps is cool » par la valeur renvoy´e par Localizer. e i C'est donc lui qui traduit les pages que vous voyez quand Zope en re¸oit c l'ordre, pour simplifier quand l'utilisateur demande la page en question. Ep oz Si vous voyez une interface ressemblant ` celle d'un petit traitement de a textes quand vous ´ditez un document, il s'agit de Epoz. Il vous permet e de composer du texte enrichi sans utiliser de langage comme HTML ou Structured Text. PortalTransforms Gr^ce ` ce produit, CPS peut importer les document de aa bureautique au format texte pour leur indexation par le moteur de recherche et au format HTML pour vous en donner un aper¸u dans le nac vigateur. Il sert aussi dans l'autre sens pour exporter des documents au format PDF, par exemple. BTreeFolder2 Voici un produit purement technique dont vous ne verrez que peu de trace dans l'interface de CPS. Il apporte un nouveau type de Folder pour Zop e qui utilise des algorithmes avanc´s pour pouvoir g´rer des e e milliers d'ob jets et m^me plus. Le d´p^t documentaire est une instance de e eo cet ob jet. CPSCore peut donc sans soucis y stocker tous vos documents dans toutes leurs r´visions et leurs traductions. Au cas ou vous vous en e ` inqui´terez, il y fait aussi du m´nage quand une r´vision ou une langue e e e n'est plus r´f´renc´e dans le site. ee e
1.3.2
Les outils de CPS
Nous allons passer en revue les ´l´ments que vous pouvez trouver dans la ZMI, ee dans votre instance de CPS. Les outils ` part enti`re poss`dent un nom coma e e men¸ant par «portal ». La connaissance de ces outils peut vous ^tre utile pour c e personnaliser votre site et d´velopper pour CPS. Elle peut ^tre ´galement utile e e e pour rep´rer facilement les erreurs. e .cps b oxes ro ot Cet ´l´ment contient les bo^tes qui sont d´finies ` la racine ee i e a du portail. A l'installation, il contient une dizaine de bo^tes qui sont les i bo^tes par defaut du site. i BenchmarkTimer Ce script calcule les temps de rendu des pages. Lo calizer Cet outil permet de manipuler les traductions du site. Il contient notamment le catalogue de messages default, qui est enrichi par la plupart des traductions disponibles pour les produits. 4
1.3. CE QUI FAIT CPS 3 Mailhost Cet ob jet contient les param`tres permettant d´xp´dier des courriers e ee ´lectroniques sur le portail. e Memb ers C'est un r´sidu de CMF. Il n'est pas utilis´ dans notre cadre. e e e e acl users Ce r´pertoire contient les utilisateurs du portail. Il peut-^tre de plusieurs types diff´rents, notamment si les utilisateurs sont stock´s dans un e e annuaire LDAP auquel se connecte CPS. content typ e registry C'est un r´sidu de CMF. Il n'est pas utilis´ dans notre e e cadre. co okie authentication Contient les noms des cookies utilis´s par le portail et e les pages vers lesquelles l'utilisateur est redirig´ si n´cessaire. e e mimetyp es registry Il remplace content type registry et est utilis´ par Pore talTransforms. p ortal actions Cet outil contient des actions disponibles sur le site (pour consulter les annuaires, par exemple), ainsi que la liste des outils qui d´e finissent d'autres actions. e p ortal b oxes Cet outil fournit une interface pour les m´thodes de gestion des bo^tes. i p ortal calendar This tool provides a common interface for providing calendar rendering and manipulation functions. TODO. p ortal catalog Cet outil fournit l'indexation du contenu du site, et permet d'effectuer les recherches par mots-clefs. p ortal directories Cet outil contient les annuaires du portail : typiquement, l'annuaire des membres, des r^les et des groupes. o p ortal discussion This tool embodies the policies for a given CPSSite concerning the storage mechanisms for comments (discussion) about content, managed and displayed using CPSForum constructs. TODO. p ortal eventservice TODO. e p ortal layouts Cet outil contient les layouts qui sont utilis´s par les documents et les annuaires du portail. Vos propres layouts seront visibles ici. p ortal memb erdata This tool is responsible for handling the storage of the «membership» properties germane to the CMFSite. TODO. p ortal memb ership This tool encapsulates the authentication mechanism (the user folder) in a more usable, «member-centric» interface, insulating other CMF ob jects from changes or idiosyncracies in the particular member folder. TODO. p ortal metadata This tool embodies site-wide policies concerning required metadata for each content type, as well as default values and controlled vocabularies. TODO. p ortal prop erties This tool provides a common interface for accessing «portalwide» properties. TODO. p ortal proxies TODO. p ortal registration TODO. p ortal rep ository Cet outil contient le d´p^t documentaire qui contient toutes eo les versions et les traductions de chaque document du site. En pratique, le document que vous manipulez est une r´f´rence vers un ´l´ment de ce ee ee d´p^t. eo 5
1.3. CE QUI FAIT CPS 3 p ortal rss TODO. e e p ortal schemas Cet outil contient les sch´mas qui sont utilis´s par les documents et les annuaires du portail. Vos propres sch´mas seront visibles e ici. e ee e p ortal skins Cet outil contient les skins des diff´rents produits r´f´renc´s par Zope. Elle pr´sente tous les scripts, les templates et les images qui come posent un site CMF. Vos propres fichiers contenus dans le r´pertoire e skins de votre produit y seront visibles ´galement. Nous revenons plus e en d´tail sur cet outil ` la fin de cette section. e a p ortal syndication See the online help by clicking the 'Help' link on the Management Forms. To turn on syndication, visit the Properties Tab in the management interface. More online documentation is available at : Syndication Administration (http://cmf.zope.org/doc/admin/syndication/). TODO. p ortal transforms Cet outil contient les outils de transformation de contenu : par exemple, pour transformer du texte au format HTML au format texte, pour transformer du texte au format PDF au format HTML, etc... p ortal trees Cet outil contient les arborescences des sections et des espaces de travail mises en «cache». Elles ne r´f´rencent que les ob jets «folderish», ee c'est-`-dire susceptibles de contenir d'autres ob jets. a p ortal typ es Cet outil contient les diff´rents types d'ob jets qui peuvent ^tre e e cr´´s sur le site. Vos propres types de documents, par exemple, seront ee visibles ici. p ortal undo This tool provides an interface to the Zope undo machinery, without requiring access to the Zope Management Interface. TODO. p ortal url This tool provides a common mechanism for finding the «root» ob ject of a CMFSite, and for computing paths to ob jects relative to that root. TODO. p ortal vo cabularies Cet outil contient les diff´rents vocabulaires qui sont d´e e finis sur le site. Vos propres vocabulaires appara^tront ici. i e p ortal widget typ es Cet outil contient les diff´rents types de widgets qui peuvent ^tre utilis´s sur le site. Vos propres widgets seront visibles ici. e e p ortal workflow This tool associates ob jects of a given content type with a «workflow» ; workflows are «state machines», each representing the life cycle of a given family of content types, and specifying the «workflow actions» which are possible in any phase of the life cycle. This is the CPS version, with extended APIs for placeful workflows and fine-grained content creation control. TODO. translation service TODO. sections Une section, ou rubrique, est un r´pertoire particulier de CPS. Les e sections et sous-sections sont destin´es ` pr´senter le contenu fini du site, eae c'est-`-dire les documents qui ont ´t´ valid´s par les diff´rentes personnes a ee e e responsables de ce contenu. workspaces Un espace de travail est ´galement un r´pertoire particulier de e e CPS. Les espaces de travail sont d´di´s ` la cr´ation et ` la modification eea e a des documents ` l'´tat de travail, documents qui seront pr´sent´s, ` terme, ae e ea dans les sections. 6
´ 1.4. PROBLEMATIQUE DE CE LIVRE On trouve ´galement un ensemble de m´thodes externes qui appellent les inse e talleurs de plusieurs produits. Elle peuvent ^tre utilis´es pour mettre ` jour ces e e a produits. Revenons sur l'outil «portal skins» : il centralise les scripts, templates et images qui sont d´finis pour les produits CMF. Vous pouvez y consulter vos propres e fichiers, ce qui peut ^tre tr`s utile pour trouver une erreur, car les pages affich´es e e e vous pr´sentent le r´sultat de la compilation de votre template ou script. Les e e messages sont suffisamment explicites, je pense, m^me si vous ne ma^trisez pas e i l'anglais. Attention toutefois au num´ros de lignes indiqu´s qui ne sont pas e e forc´ment ceux de votre ´diteur, cherchez autour de la ligne indiqu´e. e e e
1.4
Probl´matique de ce livre e
Pour plonger dans la cr´ation d'un site bas´ sur CPS 3, j'ai choisi de vous e e faire cr´er, ´tape par ´tape, un site complet. J'ai longuement h´sit´ avant de e e e ee finalement choisir un site qui m'est familier : Da Linux French Page (http: //www.linuxfr.org/). Il s'agit donc d'un portail orient´ sur l'actualit´ ou les e e` membres proposent des d´p^ches valid´es ou refus´es par des mod´rateurs. ee e e e Les sources du produit fini sont disponibles ` l'adresse http://cps3book.zopefr. a org/. Vous pouvez choisir de les utiliser telles quelles, ou de recr´er ces sources e au fur et ` mesure en suivant les instructions. a Cr´ons donc Da Zope French Page ` l'adresse http://www.zopefr.org/. Non, e a en fait c'est moi qui le fait et d'ailleurs je viens de le faire ` l'instant ou j'´cris a `e ces mots (v´ridique). Ceci ´tant fait. . . e e Suivez donc le guide !
7
Chapitre
2
Premiers pas dans la p ersonnalisation
You'l l remember me Like a melody Fiona Apple, Slow Like Honey
2.1
Le b on r´flexe : cr´er un pro duit e e
CPS 3 ´tant une collection de produits, il est logique d'en faire autant si vous e souhaitez personnaliser CPS ou lui a jouter de nouvelles fonctionnalit´s. Aue del` de cet aspect rh´torique, les avantages de cr´er son application sous forme a e e de produits sont r´els : e Travailler avec ses applications pr´f´r´es Ne me faites pas croire que vous ee e aimez cr´er vos scripts et vos templates dans le cadre de texte que la ZMI e vous offre. De toute fa¸on, le travail ` partir de la ZMI doit ^tre r´serv´ c a e e e aux cas d'installation et de r´paration, pas de d´veloppement ! Je ne vous e e propose pas moins que de vous sentir ` l'aide dans votre environnement de a travail pr´f´r´. L'utilisation d'un outil de versionning comme CVS n'est eee pas un mal non plus. Repro duire facilement le travail de configuration Toutes les ´tapes que e vous serez amen´ ` suivre pour cr´er votre produit finissent par ^tre ea e e longues et r´p´titives. C'est pourquoi pour chacune d'entre elles, je vous ee explique comment automatiser ceci dans un script d'installation et de mise ` jour. Si un jour vous voulez recr´er votre site, vous installez un a e site CPS par d´faut et vous lancez ce script d'installation pour retrouver e votre site avec tous ces r´glages. Notez qu'un effet de bord int´ressant est e e qu'il constitue aussi un historique de toutes les modifications apport´es ` ea CPSDefault. Distribuer sa contribution Vous allez surement ´crire un outil ou un com^ e posant que vous aurez envie de partager avec les autres utilisateurs de CPS. La combinaison produit/script d'installation a fait ses preuves ; c'est d'ailleurs celle que vous avez utilis´ pour installer CPS et ses produits e tierces. Ce jour-l`, vous serez pr^t et vous n'aurez oubli´ aucune ´tape a e e e pour que votre produit fonctionne ailleurs. 8
´ ´ 2.1. LE BON REFLEXE : CREER UN PRODUIT Maintenant que vous ^tes convaincus, cr´ons-le. Dans le r´pertoire Products ` e e e a la racine de votre installation de Zope, celui qui contient d´j` les produits de ea CPS, cr´ez un r´pertoire au nom pertinent. Dans notre cas, ce sera DaZopee e FrenchPage. Le risque qu'il entre en conflit avec un produit existant est quand m^me faible ! e Les produits Zop e suivent plus ou moins le m^me mod`le, le m^me squelette. e e e Celui que je vous propose est adapt´ aux produits bas´s sur CMF et CPS. e e Cr´ez dans ce r´pertoire les fichiers (vides) et les r´pertoires n´cessaires pour e e e e retrouver l'arborescence suivante : DaZopeFrenchPage __init__.py README.txt Extensions/ install.py i18n/ locate.pot en.po fr.po skins/ default/ images/ styles/ install/ M^me si je suppose que tout ceci vous est familier, un rappel ne fait jamais de e mal. Le fichier __init__.py sert a d´clarer notre r´pertoire aupr`s de Zope pour `e e e que ce dernier le voit comme un produit. Le fichier README.txt est tout aussi indispensable. Il doit contenir au minimum la description du produit, le nom de l'auteur et un moyen de le contacter, la licence du logiciel et les instructions d'installations (sauf si pr´sentes dans e un fichier INSTALL.txt). Avec ceci, vos utilisateurs, ou vous-m^me si vous le e ressortez un an apr`s, ne doivent pas se sentir perdus. e Le r´pertoire Extensions est destin´ ` contenir les m´thodes externes n´cese ea e e saires ` l'utilisation du produit. De mani`re g´n´rale, il ne contient que le script a e ee d'installation install.py. Le r´pertoire i18n est destin´ ` recevoir les traductions, qu'elles soient sp´cie ea e fiques ` ce produit, ou qu'elles remplacent celles par d´faut : le fichier locale.pot a e contient les idiomes ` traduire, et les fichiers en.po et fr.po contiennent les a traductions en anglais et fran¸ais. D'autres langages peuvent ^tre ´galement c e e a jout´s. e Les trois r´pertoires pr´sents dans skins vont permettre de r´partir chaque e e e fichier l'on souhaite modifier, par exemple le formulaire d'authentification ou les couleurs du site. La r´partition se fait ainsi : e default Ce sont les templates et les scripts, autrement dit les vues et la logique de votre application. 9
2.2. PERSONNALISER CPS images Toutes les images utilis´es dans les templates (pas les documents) : e logos, ´l´ments graphiques pour d´corer les pages, etc. ee e styles Les propri´t´s des feuilles de style de CPSDefault et les feuilles de ee styles personnelles. Vous pouvez cr´ez plusieurs r´pertoires dans celui-ci e e et ainsi avoir plusieurs styles au choix pour votre site. install Ce sont les scripts dits «custom» qui ne servent qu'au moment de l'ex´e cution du script d'installation. Comptez par exemple, les scripts qui d´e crivent vos propres types de documents. Retenez donc que pour personnaliser un fichier, en g´n´ral on le copie vers le ee r´pertoire ´quivalent dans son propre produit sauf : e e i e b oxes nuxeo.pt . Il s'agit bel et bien des types de bo^tes propos´s par Nuxeo. Si vous voulez changez ces bo^tes, il vous faudra cr´er votre propre colleci e tion de bo^tes. Nous apprendrons peu apr`s ` le faire. i ea Des scripts de d´finition qui disposent d'une seconde version personnalisable e commen¸ant par getCustomNom au lieu de getNom . Ce sont bien sur les c ^ versions « custom » que vous devez personnaliser. Celles qui ne servent qu'au moment de l'installation par le script peuvent ^tre plac´es dans e e install au lieu de default. Ce mod`le est utilis´ pour les produits «` part enti`re», qui ne personnalisent e e a e pas CPS mais lui a joute de nouvelles fonctionnalit´s. Ce mod`le peut ´galement e e e ^tre suivi pour notre produit, qui personnalise CPS et lui a joute de nouvelles e fonctionnalit´s. Attention, deux produits personnalisant CPS ne peuvent cohae biter sur une m^me instance de CPS, car ils pourraient entrer en conflit. e
2.2
Personnaliser CPS
Dans la suite du livre, j'adopte une double approche : je vous montre comment modifier CPS par son interface ou la ZMI puis nous rendons tout ceci scriptable en l'a joutant ` notre script d'installation. a Bien entendu, utiliser ces deux approches simultan´ment est redondant : les e changements effectu´s sont les m^mes, ` la diff´rence que les changements scripe e a e t´s sont reproductibles facilement. e Cependant, il peut ^tre utile d'utiliser les outils de l'interface ou de la ZMI pour e obtenir automatiquement certaines parties du code voulu, comme nous le verrons ensuite. N´anmoins, si vous r´alisez les changements via l'interface avant de e e les avoir script´s, vous risquez de pas vous rendre compte que votre script n'est e pas complet, et que certains changements ne sont pas correctement r´alis´s. ee Pour ´viter ce d´sagr´ment, vous pouvez ´ventuellement d´cider de travailler e e e e e avec deux instances de CPS, les changements ´tant effectu´s manuellement sur e e l'une, et automatiquement en lan¸ant le script d'installation sur l'autre. c Commen¸ons avec le contenu du fichier __init__.py : il d´clare le r´pertoire c e e skins aupr`s de CMF pour pouvoir utiliser de nouvelles templates et de noue veaux scripts ou remplacer ceux existants.
10
2.2. PERSONNALISER CPS
from Products . CMFCore . DirectoryView import registerDirectory registerDirectory ( ' skins ' , globals ())
Fig. 2.1 Code minimal pour d´clarer ses r´pertoires de skins. e e Le fichier README de notre produit contient ceci : Le r´pertoire Extensions contient le script install.py mentionn´ dans le fichier e e README.txt. Le contenu de ce script fait qu'il existe mais est sans effet :
from Products . CPSDefault . Installer import BaseInstaller class D Z F P I n s t a l l e r ( B a s e I n s t a l l e r ): product_name = ' DaZopeFrenchPage ' def i n s t a l l ( self ): " " " M´thode d ' installation qui d´clenche toutes les proc´dures e e e n´cessaires dans l ' ordre .""" e pass def i n s t a l l ( self ): " " " Passer d ' un site C P S D e f a u l t ` un site D a Z o p e F r e n c h P a g e . " " " a installer = DZFPInstaller ( self ) i n s t a l l e r . i n s t a l l () return i n s t a l l e r . l o g R e s u l t ()
Fig. 2.2 Code minimal d'installation d'un produit. Ne perdez pas de vue que nous le compl´terons au fur et ` mesure. N'oubliez pas e a non plus que ce script est destin´ ` l'installation, il est donc a priori ` usage ea a unique. Vous risquez sinon de perdre les modifications faites manuellement. Il reste ` faire utiliser ce produit par CPS. Apr`s un red´marrage de Zope, il a e e devrait appara^tre dans la liste des produits du panneau de configuration. Pour i ce qui est de l'installation, nous allons donner un premier coup de pinceau ` a notre fonction d'installation.
from Products . CPSDefault . Installer import BaseInstaller # skins pour s u r c h a r g e r celles de CPS SKINS = ( ( ' dzfp_default ', ' Products / DaZopeFrenchPage / skins / default '), ( ' dzfp_images ', ' Products / DaZopeFrenchPage / skins / images '), ( ' dzfp_styles ', ' Products / DaZopeFrenchPage / skins / styles '), ) class D Z F P I n s t a l l e r ( B a s e I n s t a l l e r ): product_name = ' DaZopeFrenchPage ' def i n s t a l l ( self ): " " " M´thode d ' installation qui d´clenche toutes les proc´dures e e e n´cessaires dans l ' ordre .""" e self . log ( " I n s t a l l a t i o n de D a Z o p e F r e n c h P a g e " )
11
´´ 2.3. CHANGER LES PROPRIETES DU PORTAIL
self . log ( " Mise en place des skins " ) self . setupSkins ( SKINS ) self . setSkinsOnTop ( SKINS ) self . log ( " Fin de l ' i n s t a l l a t i o n de D a Z o p e F r e n c h P a g e " )
def i n s t a l l ( self ): " " " Passer d ' un site C P S D e f a u l t ` un site D a Z o p e F r e n c h P a g e . " " " a installer = DZFPInstaller ( self ) i n s t a l l e r . i n s t a l l () return i n s t a l l e r . l o g R e s u l t ()
Fig. 2.3 Code d'installation compl´t´ pour les skins. ee Vous remarquez ainsi que le code d'installation sera compl´t´ au fur et ` meee a sure de nos besoins. Fort de votre r´cent succ`s, installez la m´thode externe e e e d'installation comme indiqu´ dans le fichier README.txt et testez-la. e ` l'issue de ce travail, nous en sommes toujours au site CPS par d´faut, comme A e sur la figure 2.4. Normal puisque nous n'avons encore rien modifi´, juste pr´par´ e ee le terrain.
Fig. 2.4 Aspect par d´faut d'un site CPS flambant neuf. e
2.3
Changer les propri´t´s du p ortail ee
Commencez par vous rendre a la page de reconfiguration du portail comme sur ` la figure 2.5. Changez ce que vous voulez pour votre part mais je ne touche qu'au titre et ` la description. a Apr`s mure r´flexion, voici que j'inscris : e ^ e
12
2.4. MANIPULER LES BO^TES I Titre du p ortail Description du p ortail Da Zope French Page News, journaux, forums et astuces sur Zope !
Cliquez sur le bouton Enregistrer et un message vous informe du succ`s de e l'op´ration sur l'´cran suivant. Notez le nouveau titre dans la barre de titre de e e votre navigateur. Voyons maintenant comment retrouver ces valeurs pour la prochaine installation de votre produit. Le module d'installation de CPSDefault a la m´thode qu'il e nous faut, suivons le formalisme qu'elle demande et faisons-y appel apr`s avoir e configur´ les skins. e
# p r o p r i ´ t ´ s du p o r t a i l ee PROPERTIES = ( { ' id ': ' title ' , ' value ': " Da Zope French Page " } , { ' id ': ' d e s c r i p t i o n ' , ' value ': " News , journaux , forums et a s t uc e s sur Zope ! " } , ) class D Z F P I n s t a l l e r ( B a s e I n s t a l l e r ): # ... def i n s t a l l ( self ): # ... self . log ( " C h a n g e m e n t des p r o p r i ´ t ´ s du p o r t a i l " ) ee self . setupPortalProperties ( PROPERTIES ) # ...
Vous pouvez v´rifier son fonctionnement en changeant ` nouveau le titre et la e a description du portail pour n'importe quoi puis voir qu'ils reviennent ` la valeur a voulue apr`s un appel au script d'installation. e
2.4
2.4.1
Manipuler les b o^tes i
Qu'est-ce qu'une b o^te ? i
Les bo^tes permettent aux administrateurs et aux responsables des espaces de i travail de personnaliser l'aspect visuel et les fonctionnalit´s du portail. Les bo^tes e i peuvent contenir par exemple du texte, des images, des actions, des animations, un agenda... Il existe diff´rents types de bo^te pr´d´finis : e i ee Bo^te g´n´rique i ee Bo^te de texte i Bo^te de navigation i Bo^te de contenu i Bo^te d'action i Bo^te d'image i Bo^te flash i 13
2.4. MANIPULER LES BO^TES I Bo^te calendrier d'´v´nements i ee Bo^te de flux RSS i Pour une description plus compl`te de ces types de bo^tes, veuillez vous r´f´rer e i ee ` la documentation utilisateur. a Il est possible de manipuler les bo^tes «globales», c'est-`-dire les bo^tes d´finies i a i e ` la racine du portail, qui peuvent ^tre visibles sur toutes les pages du portail, a e quel que soit l'utilisateur. C'est ce que nous feront dans un premier temps. Il est ´galement possible de cr´er et manipuler des bo^tes «locales», localis´es dans des e e i e sous-r´pertoires du site, ce que nous verrons bri`vement dans un second temps. e e
2.4.2
Supprimer des b o^tes et en a jouter automatiquei ment
Vous allez apprendre d`s maintenant ` modifier la mise en page en composant e a avec les bo^tes. i Regardez votre page d'accueil, en ´tant connect´ ou non et demandez-vous ce e e qui manque ou qui est de trop. Nous allons commencer par supprimer la barre indiquant «Bienvenue sur Nuxeo CPS.». Vous pouvez bien sur le faire en sup^ primant la bo^te avec l'outil de gestion des bo^tes ` la racine mais nous allons i i a le faire faire par notre script. Cette boite a pour id welcome. Demandons alors ` Zop e de supprimer l'ob jet dont l'identifiant est welcome. a Ins´rez le code suivant dans le script, ` la suite des autres ´tapes mais tout de e a e m^me avant le message de fin. e
# liste des noms de bo^tes ` e f f a c e r i a BOITES_EFFACEES = ( ' welcome ', ' l10n_select ', ' navigation ', ' search ', ' action_folder ', ' action_object ', ) class D Z F P I n s t a l l e r ( B a s e I n s t a l l e r ): # ... def i n s t a l l ( self ): # ... self . log ( " Mise en place des bo^tes " ) i boites_racine = self . getBoxContainer ( parent = self . portal ) self . log ( " Suppression des bo^tes inutiles " ) i self . setupDelBoxes ( BOITES_EFFACEES , boites_racine ) # ...
La bo^te qui ´tait affich´e au centre de la page ayant ´t´ supprim´e, la racine du i e e ee e site se comporte maintenant comme un r´pertoire et fait afficher son contenu : les e ob jets qui servent ` faire fonctionner le site. Ceci ´tant aussi indiscret qu'inutile, a e nous allons vite a jouter une nouvelle bo^te pour habiller la page d'accueil : la i liste des derni`res br`ves. e e
14
2.4. MANIPULER LES BO^TES I
# dictionnaire des bo^tes ` ajouter avec leurs propri´t´s i a ee NOUVELLES_BOITES = { ' dernieres_breves ': { ' type ': ' Content Box ' , ' title ': ' Derni`res br`ves ', e e ' provider ': ' dzfp ', ' btype ': ' dernieres_breves ', ' box_skin ': ' here / box_lib / macros / box ' , ' minimized ': 0, ' closed ': 0, ' slot ': ' center ', ' order ': 2, ' display_in_subfolder ': 0, ' display_only_in_subfolder ': 0, ' locked ': 0, ' folder ': '/ sections ', ' n b _ i t e m s ' : 20 , ' sort_by ': ' date ', ' direction ': ' desc ', ' display ': ' summary ', ' zoom ': 1, ' query_title ': '', ' query_description ': '', ' query_fulltext ': '', ' query_status ': ' published ', ' q u e r y _ p o r t a l _ t y p e ' : [] , ' query_modified ': '', }, ' actions_contexte ': { ' type ': ' Action Box ' , ' title ': ' Current actions ', ' provider ': ' nuxeo ', ' btype ': ' menu ', ' box_skin ': ' here / box_lib / macros / box ' , ' minimized ': 0, ' closed ': 0, ' slot ': ' center_top ', ' order ': 0, ' display_in_subfolder ': 1, ' display_only_in_subfolder ': 0, ' locked ': 0, ' categories ': ( ' folder ', ' object ', ' workflow '), }, }
Je ne sors pas ces propri´t´s de mon chapeau, ce sont celles que chaque type de ee bo^te accepte. Voici comment je vous conseille de proc´der : i e Utilisez l'interface de gestion des bo^tes de CPS. Vous voyez en plus l'effet i imm´diat plut^t qu'en travaillant ` l'aveuglette. e o a Allez dans la ZMI, dans le r´pertoire qui contient cette bo^te puis dans l'inse i tance de la bo^te elle-m^me. Cliquez alors sur l'onglet Export tout ` droite. i e a Copiez le dictionnaire qui s'affiche puis collez ce bloc de texte au bon emplacement dans votre script. Respectez l'indentation pour faciliter la lecture de votre script et v´rifiez que le dictionnaire ne contienne pas au final d'erreurs e de syntaxe. Attention aux apostrophes pour d´limiter les cha^nes si celles-ci e i en contiennent d´j`. ea Viens ensuite le code pour passer de ce grand dictionnaire ` une instance de a bo^te. Notez que je supprime d'abord l'ancienne bo^te. Si vous d´cidez plus tard i i e que dernieres breves sera une bo^te d'un autre type que Content Box, il vous i 15
2.4. MANIPULER LES BO^TES I faudra de toute fa¸on l'effacer puis la recr´er. Voici le code ` a jouter apr`s celui c e a e de suppression des bo^tes : i
class D Z F P I n s t a l l e r ( B a s e I n s t a l l e r ): # ... def i n s t a l l ( self ): # ... self . log ( " Ajout des nouvelles bo^tes " ) i self . setupAddBoxes ( NOUVELLES_BOITES , boites_racine ) # ...
Je vous laisse en exercice l'a jout d'une bo^te dans la colonne de gauche qui affiche i les document en attente de publication. La solution se trouve dans l'annexe E
2.4.3
Changer les b o^tes par d´faut : le logo et le pied de i e page
Rappelez-vous qu'il ne faut pas personnaliser les bo^tes en r´cup´rant le fii e e chier boxes_nuxeo.pt. Puisque notre produit s'appelle DaZopeFrenchPage, DZFP en abr´g´, cr´ons le fichier boxes_dzfp.pt dans le r´pertoire default. ee e e ´ Ecrivez-y la macro basebox logo avec le contenu de votre choix. Le plus simple est surement de recopier le contenu de la macro du m^me nom depuis le fi^ e chier CPSDefault/skins/cps_default/boxes_nuxeo.pt et de changer le nom ´ de l'image et sa taille. Ecrivez dans la foul´e de quoi faire un joli pied de page. e Je ne sais pas pour vous mais j'obtiens ceci :
<! -- ============================================================ --> < metal : block define - macro = " basebox_logo " > <a href = " http :// www . zopefr . org / " tal : attributes = " href string : $ { base_url } " > < img src = " logo . png " width = " 253 " height = " 55 " class = " logo " alt = " Logo " title = " Da Zope French Page " tal : attributes = " src string : $ { base_url } logo . png " > </a > < div class = " fondlogo " tal : content = " container / description " > Description </ div > </ metal : block > <! -- ============================================================ --> < metal : block define - macro = " basebox_footer " > < div class = " footer " > Da Zope French Page < br > Copyright & copy ; 2003 Herv´ Cauwelier e <a href = " mailto : webmaster@zopefr . org " > webmaster chez zopefr . org </ a > </ div > </ metal : block > <! -- ============================================================ --> < metal : block define - macro = " c on ten tb ox _de rn ier es _b rev es " tal : d e f i n e = " i t e m s p y t h o n : box [ ' box ']. g e t C o n t e n t s ( h e r e ) [ 0 ] " tal : repeat = " item items " >
16
2.4. MANIPULER LES BO^TES I
< m e t a l : b l o c k use - m a c r o = " p y t h o n : p a t h ( box [ ' s e t t i n g s '][ ' b o x _ s k i n ']) " > < metal : block fill - slot = " b o x _ t i t l e " tal : c o n t e n t = " item / Title " > Titre de la br`ve </ metal : block > e < metal : block fill - slot = " b o x _ b o d y " tal : define = " content item / getContent ; rurl python : item . absolute_url ( relative =1); "> < tal : block content = " content / Description " > D e s c r i p t i o n de la br`ve e </ tal : block > <p > <a href = " " tal : attributes = " href string : $ { base_url } $ { rurl } " > Lire la suite ... </a > </ metal : block > </ metal : block > </ metal : block >
Vous aurez bien sur dot´ le r´pertoire images des images utilis´es et vous aurez ^ e e e v´rifi´ que la taille donn´e concorde avec la taille des images. ee e Il va maintenant falloir d´finir tous les types de bo^tes que je vous ai fait cr´er e i e pour qu'ils apparaissent dans l'interface. Copiez pour cela le fichier getCustomBoxTypes.py du r´pertoire cps_default de CPSDefault dans votre r´pertoire default. e e Changez alors la d´claration de «items» pour ceci : e
items = [ { ' category ': ' basebox ', ' title ': ' portal_type_BaseBox_title ', ' desc ': ' portal_type_BaseBox_description ', ' types ': [{ ' p r o v i d e r ': ' dzfp ' , ' id ': ' logo ' , ' desc ': ' description_dzfp_logo ', }, { ' provider ': ' dzfp ', ' id ': ' footer ' , ' desc ': ' description_dzfp_footer ', }, ] }, { ' category ': ' actionbox ', ' title ': ' portal_type_ActionBox_title ', ' desc ': ' portal_type_ActionBox_description ', ' types ': [{ ' p r o v i d e r ': ' dzfp ' , ' id ': ' a c t i o n s _ c o n t e x t e ' , ' desc ': ' description_dzfp_actions_contexte ', ' config ': { ' categories ': ( ' folder ', ' object ', ' workflow '), }, }, ] }, { ' category ': ' contentbox ', ' title ': ' portal_type_ContentBox_title ', ' desc ': ' portal_type_ContentBox_description ', ' types ': [{ ' p r o v i d e r ': ' dzfp ' , ' id ': ' d e r n i e r e s _ b r e v e s ' , ' desc ': ' description_dzfp_dernieres_breves ', ' config ': { ' folder ': '/ sections ', ' n b _ i t e m s ' : 20 ,
17
2.4. MANIPULER LES BO^TES I
' sort_by ': ' date ', ' direction ': ' desc ', ' display ': ' summary ', ' zoom ': 1, ' query_title ': '', ' query_description ': '', ' query_fulltext ': '', ' query_status ': ' published ', ' q u e r y _ p o r t a l _ t y p e ' : [] , ' query_modified ': '', }, }, { ' provider ': ' dzfp ', ' id ': ' e n _ a t t e n t e ' , ' desc ': ' description_dzfp_en_attente ', ' config ': { ' folder ': '/ sections ', ' n b _ i t e m s ' : 10 , ' sort_by ': ' date ', ' direction ': ' asc ' , ' display ': ' icon ', ' zoom ': 0, ' query_title ': '', ' query_description ': '', ' query_fulltext ': '', ' query_status ': ' pending ', ' q u e r y _ p o r t a l _ t y p e ' : [] , ' query_modified ': '', }, }, ] }, ] return items
Puisque le provider est dzfp, la macro pour afficher la bo^te sera cherch´e dans i e le fichier boxes_dzfp.pt. Le nom de la macro est calcul´ ` partir de category ea et id pour obtenir category id comme nom, soit par exemple basebox logo. C'est bien le nom de notre pr´c´dente macro. Je reviendrai plus tard sur le contenu ee de la cl´ desc, dans le chapitre concernant l'internationalisation de l'application. e Il est temps de s'amuser avec les nouveaux logo et pied de page. Allez dans la gestion des bo^tes ` la racine et cliquez pour ´diter la bo^te Nuxeo Logo i a e i de l'en-t^te de la page. Comme type de bo^te choisissez votre nouveau type e i (th´oriquement l'avant-dernier de la liste) et cliquez sur le bouton Modifier. e Voyez comme le logo a chang´. Puisque vous ^tes de retour sur le formulaire de e e gestion des bo^tes, cliquez pour ´diter cette fois la bo^te intitul´e Footer, tout i e i e en bas. Choisissez ici encore votre nouveau type de bo^te (en bas de la liste) et i cliquez sur Modifier. On se sent d´j` plus chez soi ! ea Votre logo et votre pied de page apparaissent maintenant ` la place de ceux par a d´faut. Libre ` vous de cr´er d'autres bo^tes de logos et de pieds de page pour e a e i en changer en un clic ou presque ! «Pourquoi faire tout ceci alors que ce code aurait pu ^tre le contenu d'une bo^te e i de texte ?»
18
2.4. MANIPULER LES BO^TES I Cette question est l´gitime, c'est une technique possible et elle offre pour avane tage de pouvoir changer le code du logo ou du pied de page depuis l'interface de CPS, sans avoir acc`s au serveur. Mais elle a pour inconv´nient de se priver du e e langage TAL et donc d'avoir des valeurs calcul´es qui remplacent les valeurs en e dur. Pour profiter du lien automatique vers la page d'accueil et de la description du portail, je travaille quand m^me dans un template. e e «Argh ! J'ai modifi´ mon fichier boxes dzfp.pt et mon site est tout cass´ !» e Du calme. . .Allez ` l'URL suivante : http://monsite/boxes_dzfp/manage_ a main monsite ´tant bien sur l'adresse de votre site. Si vous n'´tiez pas authentifi´ e ^ e e en tant qu'administrateur, il va falloir y passer pour pouvoir acc´der ` la ZMI. e a Cette page est simplement la page affich´e dans l'outil portal skins pour votre e fichier. Quand vous pensez avoir corrig´ l'erreur, rafra^chissez cette page pour tester e i ` nouveau la compilation. Une fois qu'aucun message d'erreur appara^t, vous a i pouvez revenir au site. Refaisons maintenant ces ´tapes mais dans notre script d'installation et pour e garder trace de ce qu'on a modifi´. Le code final est bien plus simple que pour e a jouter de nouvelles bo^tes puisqu'il ne s'agit que de modifier quelques propri´t´s i ee sur des ob jets existants.
# dictionnaire des bo^tes dont les propri´t´s sont ` changer i ee a BOITES_CHANGEES = { ' footer ': { ' provider ': ' dzfp ', }, ' logo ': { ' provider ': ' dzfp ', ' o r d e r ' : 10 , }, }
Si vous voulez faire du logo et du pied de page des bo^tes d'un autre type que i celui des versions de CPSDefault, il vous faudra faire supprimer ces bo^tes en i les a joutant ` BOITES EFFACEES et en accolant ` BOITES NOUVELLES a a les dictionnaires de vos propres bo^tes. i Encore une fois, nous faisons appel aux m´thodes fournies par CPSInstaller. e Ajoutez le code suivant avant ou apr`s celui d'a jout des bo^tes, peu importe. e i
class D Z F P I n s t a l l e r ( B a s e I n s t a l l e r ): # ... def i n s t a l l ( self ): # ... self . log ( " Modification des bo^tes par d´faut " ) i e self . setupEditBoxes ( BOITES_CHANGEES , boites_racine ) # ...
19
´´ 2.5. CHANGER LES PROPRIETES DES FEUILLES DE STYLE Nous voici avec un site qui commence ` avoir de l'allure ! Le logo de la figure 2.14 a est certes peu esth´tique sur un site ` dominante bleue mais j'ai anticip´ sur e a e l'´tape suivante. e
2.4.4
TODO
Ajouter des b o^tes lo cales i
2.5
Changer les propri´t´s des feuilles de style ee
Copiez le fichier stylesheet_properties.props qui se trouve dans CPSDefault/skins/cps_styles/nuxeo vers le r´pertoire styles de votre produit. e Attention ! Ces propri´t´s servent ` construire les feuilles de styles. Il est essentiel ee a d'´viter certains pi`ges : e e Une erreur de syntaxe dans les propri´t´s peut conduire ` une erreur dans ee a la feuille de style qu'il faut pouvoir d´tecter. En cas de doute, faites afficher e les feuilles de styles nuxeo_css1.css et nuxeo_css2.css en entrant leur nom derri`re l'URL de base du site. Si elles contiennent des erreurs, Zope devrait e ^tre assez explicite. e Le deuxi`me pi`ge vient de votre navigateur. Son cache peut devenir votre pire e e ennemi. Pensez ` le d´sactiver ou ` demander un rafra^chissement complet, a e a i par exemple avec la combinaison de touche Ctrl+Ma j+R sur Mozilla. Voyons chaque propri´t´ et ce qu'elle affecte : ee mainFont La police principale de la page. souvent surcharg´e par la police des e bo^tes et des documents. i mainBackground Le fond de la page, couleur ou image. mainFontColor La couleur de la police principale de la page. Voir la remarque pour mainFont. mainLinkColor La couleur des liens de la page. Souvent surcharg´ par les e liens des bo^tes et des documents. i mainTabBorderColor La couleur du bord des onglets pour les sections sous le logo. mainTabBorderColorSelected La couleur de ce bord quand l'onglet est s´e lectionn´. e mainTabBackground La couleur de fond des onglets de sections actifs. mainTabBackgroundNotSelected La couleur de fond pour les onglets de sections inactifs. mainTabBackdrop mainTabFontWeight La taille de la police des onglets de sections. mainTabFontColor La couleur de la police des onglets de sections. mainTabFontColorSelected La couleur de la police des onglets s´lectionn´s. e e headingFont La police des ´l´ments de titre comme H1 ou H2. ee headingFontColor La couleur de la police des ´l´ments de titre. ee 20
´´ 2.5. CHANGER LES PROPRIETES DES FEUILLES DE STYLE headingSize1 La taille de l'´l´ment H1. ee headingSize2 La taille de l'´l´ment H2. ee headingSize3 La taille de l'´l´ment H3. ee headingSize4 La taille de l'´l´ment H4. ee headingSize5 La taille de l'´l´ment H5. ee headingSize6 La taille de l'´l´ment H6. ee descriptionFont La police pour le texte de description. contentFont La police pour le contenu du document. contentBackground Le fond du contenu du document. contentImageBorder La bordure appliqu´ aux images du document. e contentLinkActiveColor La couleur des liens actifs dans le document. contentLinkVisitedColor La couleur des liens visit´s dans le document. e contentTabBorder La bordure des onglets au-dessus du document (non-utilis´ e dans CPSDefault). contentTabBackground Le fond de l'onglet actif au-dessus du document (non-utilis´ dans CPSDefault). e contentTabBackgroundNotSelected Le fond des onglets inactifs au-dessus du document (non-utilis´ dans CPSDefault). e contentTabBackdrop contentTabFontWeight L'´paisseur de la police des onglets au-dessus du doe cument (non-utilis´ dans CPSDefault). e contentTabFontColor La couleur de la police des onglets au-dessus du document (non-utilis´ dans CPSDefault). e contentTabFontColorSelected La couleur de la police de l'onglet actif audessus du document (non-utilis´ dans CPSDefault). e preBorder La bordure de l'´l´ment PRE. ee preBackground Le fond de l'´l´ment PRE. ee messageFont La police pour le message informatif (` la suite d'une validation a de formulaire). messageBackground Le fond pour le message informatif (` la suite d'une a validation de formulaire). messageBorder La bordure pour le message informatif (` la suite d'une valia dation de formulaire). textTransform Le formatage appliqu´ au texte dans les titres de bo^te, les e i ` boutons, onglets de navigations, etc. A utiliser si vous voulez appliquer une des valeurs possibles de l'attribut CSS text-transform (capitalize, uppercase, lowercase, none) au texte de votre site, except´ les documents e eux-m^mes. e noBorder Utilis´ pour savoir quelle bordure appliquer aux ´l´ments INPUT e ee qui utilisent la classe CSS noborder. Il sert ` ma connaissance pour supa primer la bordure que Internet Explorer donne ` tous les ´l´ments INPUT a ee l` ou les autres navigateurs qui supportent CSS 2 ne l'appliquent qu'aux a` boutons. 21
´´ 2.5. CHANGER LES PROPRIETES DES FEUILLES DE STYLE groupBorder Les ´l´ments qui utilisent la classe CSS group sont ´largis et ee e utilisent la bordure sp´cifi´e par cette propri´t´. ee ee requiredField Les ´l´ments marqu´s comme requis par l'int´grateur, en utiliee e e sant la classe CSS required, utilisent le fond sp´cifi´ par cette propri´t´. ee ee inputFont La police pour tous les ´l´ments INPUT (champs de texte, boutons, ee etc.). inputBorder La bordure pour tous les ´l´ments INPUT (champs de texte, ee boutons, etc.). inputBackground Le fond pour tous les ´l´ments INPUT (champs de texte, ee boutons, etc.). contextButtonBackground Le fond pour les boutons de port´e contextuelle. e contextButtonPadding L'espacement dans les boutons de port´e contexe tuelle. contextButtonFontColor La couleur de la police dans les boutons de port´e e contextuelle. standaloneButtonBackground Le fond pour les boutons de port´e globale. e standaloneButtonPadding L'espacement dans les boutons de port´e globale. e standaloneButtonFontColor La couleur de la police pour les boutons de port´e globale. e destructiveButtonBackground Le fond pour les boutons qui provoquent une action dangereuse. destructiveButtonPadding L'espacement dans les boutons qui provoquent une action dangereuse. destructiveButtonBorder La bordure pour les boutons qui provoquent une action dangereuse. destructiveButtonFontColor La couleur de la police pour les boutons qui provoquent une action dangereuse. moveUpButtonBackground Le fond pour le bouton de d´placement vers le e haut. moveDownButtonBackground Le fond pour le bouton de d´placement vers e le bas. moveTopButtonBackground Le fond pour le bouton de d´placement au pree mier rang. moveBottomButtonBackground Le fond pour le bouton de d´placement au e dernier rang. buttonWeight L'´paisseur de la police dans les boutons. e b oxBorder La bordure des bo^tes. i b oxHeaderBackground Le fond du titre des bo^tes. i b oxHeaderFontColor La couleur de la police du titre des bo^tes. i b oxLinkBackground Le fond des liens dans le titre des bo^tes. i b oxLinkColor La couleur des liens dans le contenu des bo^tes. i b oxEvenBackground Le fond des ´l´ments pairs (utilis´ ailleurs que dans les ee e bo^tes) i 22
´´ 2.5. CHANGER LES PROPRIETES DES FEUILLES DE STYLE b oxOddBackground Le fond des ´l´ments impairs (utilis´ ailleurs que dans ee e les bo^tes) i b oxHighlight La bordure de mise en valeur pour les bo^tes. i listingBorder La bordure autour d'un listage de valeurs. listingHeaderBackground Le fond d'un listage de valeurs. listingHeaderFontColor La couleur de la police d'un listage de valeurs. listingLinkHover La mise en valeur pour les liens au passage de la souris (soulign´, etc.). e topBackground Le fond de la partie haute de la page. topMargin La marge autour de la partie haute de la page. topPadding L'espacement ` l'int´rieur de la partie haute de la page. a e logoMargin La marge autour du logo (si l'´l´ment IMG utilise la classe CSS ee logo ). logoPadding L'espacement a l'int´rieur du logo (m^me remarque que pour ` e e logoMargin). searchMargin La marge autour de la bo^te de recherche ` droite du logo. i a searchPadding L'espacement ` l'int´rieur de la bo^te de recherche. a e i searchFontColor La couleur du texte dans la bo^te de recherche. i fo oterBackground Le fond de la bo^te du pied de page (s'il utilise la classe i CSS footer ). fo oterBorder La bordure de la bo^te du pied de page (m^me remarque que i e pour footerBackground). columnsLeftBackground Le fond de la colonne de gauche. columnsRightBackground Le fond de la colonne de droite. columnsLeftBackgroundNS4 La couleur de la colonne de gauche pour Netscape 4. N'utilisez pas d'image de fond par exemple. columnsRightBackgroundNS4 La couleur de la colonne de droite pour Netscape 4. N'utilisez pas d'image de fond par exemple. workspaceBackground La couleur de fond associ´e aux espaces de travail e inactifs. workspaceBackgroundSelected La couleur de fond associ´e aux espaces de e travail actifs. urlFontColor La couleur des ´l´ments qui utilisent la classe CSS url (utilis´ ee e dans les r´sultats de recherche dans CPSDefault). e legendFontSize La taille de la police pour le texte mis en l´gende. e Vous devriez avoir ´tabli une charte graphique avant de toucher ` ce fichier, ne e a serait-ce que pour garder des couleurs coh´rentes et assorties. Si vous en doutiez e encore je vous l'assure, graphiste c'est un vrai m´tier. e Pour ma part, j'ai remplac´ le bleu fonc´ par un rouge cerise ´vocateur (pour e e e moi en tout cas) et le bleu clair des fonds par du gris. Le r´sultat final est visible e sur la figure 2.15.
23
´ 2.6. CREER L'ARBORESCENCE DU SITE
2.6
Cr´er l'arb orescence du site e
Vous trouverez dans CPSDefault les outils pour extraire l'arborescence de votre site. Commencez par cr´er quelques rubriques sur plusieurs niveaux. Placeze a vous ensuite ` la racine des sections et a joutez dump tree ` la fin de l'URL a pour appeler le script du m^me nom. Sauvegardez le r´sultat dans le fichier e e arbo_dzfp.txt du r´pertoire var de votre instance de Zope. Pensez ` en laise a ser une copie ` la racine de votre produit si vous le distribuez. Avec assez de a valeurs d'exemple, vous trouverez qu'il est plus simple de compl´ter ce fichier e (avec attention) que d'utiliser une interface web. La version finale est plac´e ` ea la page 77. Ce script est dans la skin CPSDefault/skins/cps_devel. Il est ´vident qu'une e fois le site en production, vous devrez enlever cette skin de la liste de portal skins. Je me contente de charger deux niveaux de section. Notez que vous pouvez aussi renseigner la description de la section en a joutant une cl´ de ce nom, sous title e par exemple. Reste maintenant ` transformer ce fichier en de vraies sections. a Ajoutons une fonction chargeArbo ` notre script : a
class D Z F P I n s t a l l e r ( B a s e I n s t a l l e r ): # ... def i n s t a l l ( self ): # ... self . log ( " C h a r g e m e n t de l ' a r b o r e s c e n c e " ) self . setupSiteStructure ( ' arbo_dzfp . txt ') # ...
Apr`s avoir ex´cut´ ce script, votre site est peupl´ de toutes ses rubriques. Pour e ee e mieux admirer l'arborescence, je vous propose de cr´er un plan du site sans e effort. Compl´tez simplement le script d'installation avec le code suivant : e
BOITE_PLAN = { ' plan_site ': { ' type ': ' Tree Box ' , ' title ': ' Plan du site ' , ' provider ': ' nuxeo ', ' btype ': ' sitemap ', ' box_skin ': ' here / box_lib / macros / wbox ', ' minimized ': 0, ' closed ': 0, ' slot ': ' center ', ' order ': 1, ' display_in_subfolder ': 0, ' display_only_in_subfolder ': 0, ' locked ': 0, ' root ': '/ sections ', ' depth ': 2, ' contextual ': 1, ' children_only ': 0, ' authorized_only ': 1, ' display_managers ': 0, ' display_description ': 1,
24
2.7. LE SQUELETTE DU SITE : MAIN TEMPLATE.PT
' show_root ': 0, },
class D Z F P I n s t a l l e r ( B a s e I n s t a l l e r ): # ... def i n s t a l l ( self ): # ... self . log ( " Ajout du plan du site " ) self . s e t u p P l a n S i t e () # ... def s e t u p P l a n S i t e ( self ): " " " Met en place la bo^te de plan du site ` la r a c i n e des i a sections .""" sections = self . portal . sections boites_sections = self . getBoxContainer ( sections , create =1) self . setupAddBoxes ( BOITE_PLAN , boites_sections )
Relancez l'installation et rendez-vous ` la racine des sections pour admirez le a r´sultat. Ce que j'obtiens se trouve sur la figure 2.18. e
2.7
Le squelette du site : main template.pt
La mise en page ` l'aide de bo^tes ne me suffit plus, je vais modifier le mod`le a i e g´n´ral. Je commence par supprimer la troisi`me colonne, inutile dans notre ee e maquette. Je passe aussi ` une mise en page par CSS, exit donc la table et les div seront a positionn´s par le code n´cessaire dans custom.css.dtml. En parlant de CSS, e e j'utilise un type de document standard, le HTML 4.01 Transitional dans sa vraie syntaxe1 . Le changement de mod`le de bo^te pour celui du W3C m'oblige e i ` adapter les classes CSS utilis´es par les bo^tes. Toutes ces modifications rendent a e i le rendu plus hasardeux sur les navigateurs plus anciens comme Netscape 4.71 et Internet Explorer 5.0. L'ob jectif de CPSDefault est d'avoir un rendu ´quivalent e sur les navigateurs de plusieurs g´n´rations mais ce n'est pas le mien. ee Puisque nous en venons ` modifier le squelette, vous pouvez l´gitimement vous a e demander pourquoi le logo et le pied de page ne sont pas ´crits en dur dedans. e Certes, vous pouvez le faire mais vous perdez le b´n´fice de l'interface de gestion ee des bo^tes. La diff´rence dans le temps de rendu entre des bo^tes ou un logo et i e i un pied de page en dur est n´gligeable. e D'une mani`re g´n´rale, l'int´gration pour CPS est con¸ue pour vous ´viter e ee e c e d'avoir ` toucher ` ce fichier. Le maximum de travail peut et doit se faire avec a a ` les bo^tes. A moins d'avoir ` changer le Document Type du code HTML ou i a changer les variables comme showthirdcol, je ne reviendrai pas dessus. Vous pouvez voir l'aspect final du site sur la figure 2.19. Vous retrouverez tous les fichiers que j'ai modifi´s sans le d´tailler dans les annexes. e e
1 http://gutfeldt.ch/matthias/articles/doctypeswitch/table.html
25
2.7. LE SQUELETTE DU SITE : MAIN TEMPLATE.PT
Fig. 2.5 Formulaire de reconfiguration du portail.
Fig. 2.6 Changer automatiquement les propri´t´s du portail. ee
Fig. 2.7 Code de base pour g´rer les bo^tes et les supprimer. e i
Fig. 2.8 Dictionnaire de d´finition des nouvelles bo^tes. e i
Fig. 2.9 Code d'a jout des nouvelles bo^tes. i
Fig. 2.10 Contenu de nos bo^tes personnelles. i
Fig. 2.11 D´finition de nos types de bo^tes. e i
Fig. 2.12 Le dictionnaire des bo^tes par d´faut chang´es i e e
Fig. 2.13 Code de modification des bo^tes par d´faut i e
26
2.7. LE SQUELETTE DU SITE : MAIN TEMPLATE.PT
Fig. 2.14 Notre site avec les nouvelles bo^tes en place. i
Fig. 2.15 La nouvelle charte graphique du site.
Fig. 2.16 Code de chargement de l'arborescence
Fig. 2.17 Code d'a jout du plan du site
27
2.7. LE SQUELETTE DU SITE : MAIN TEMPLATE.PT
Fig. 2.18 Le plan du site a fi`re allure. e
Fig. 2.19 Le site dans son aspect final.
28
Chapitre
3
Int´gration avanc´e e e
You say you want a revolution Wel l you know We al l want to change the world John Lennon, Revolution #1
3.1
Cr´er nos typ es de do cuments e
Il est temps d'attaquer la typologie documentaire. La cr´ation de nouveaux e types de documents est tr`s simple dans CPS 3 et se fait en grande partie ` e a coups de clics de souris dans la ZMI. Revenons sur les concepts de la typologie documentaire utilis´e : e Le sch´ma Le sch´ma est la structure du document. Il donne les champs qui e e d´finissent le document, ainsi que leur type (une cha^ne de caract`res, une e i e date,...). Un m^me document peut utiliser plusieurs sch´mas. e e Les widgets Le r^le d'un widget est de contr^ler les valeurs prises par un ou o o plusieurs champs du document. C'est ´galement le widget qui contr^le e o l'apparence prise par l'´l´ment qu'il contr^le, suivant le mode de visualiee o sation (typiquement, la vue simple, la vue de cr´ation et la vue d'´dition e e du document). Les widgets sont ´troitement li´s au layout. e e Le layout Le layout est la fa¸on dont sont pr´sent´s les champs d´finis dans le c e e e sch´ma. La d´finition d'un layout passe obligatoirement par la d´finition e e e des widgets qui seront utilis´s dans ce layout. Il permet de contr^ler leur e o pr´sentation (leur ordre, leurs places respectives) ainsi que leur style (les e templates qu'il utilise). Un m^me document peut utiliser plusieurs layouts. e Le typ e du do cument Le type du document donne les informations essentielles ` la cr´ation du document : on sp´cifie donc quelle est la fonction a e e qui sera appel´e ` la cr´ation du document, ainsi que le(s) sch´ma(s) et ea e e layout(s) qui seront utilis´s par ce type de document. e Apr`s avoir cr´´ le nouveau type de document ` via l'interface, le travail sera saue ee a vegard´ dans les scripts getCustomDocumentSchemas.py, getCustomDocumentLayouts.py, e et getCustomDocumentTypes.py. Ces scripts permettent de mettre en place tout 29
´ 3.1. CREER NOS TYPES DE DOCUMENTS ce qui est n´cessaire ` nos propres types de document. Ils sont consult´s lors e a e de l'ex´cution du script d'installation ou de mise ` jour de CPSDocument : il e a vous suffit donc d'ex´cuter ce script pour que vos modifications soient prises en e compte. Nous allons voir dans les sections suivantes comment mettre en place un nouveau type de document, en cr´ant un sch´ma, un layout, ainsi que le type de e e document. Ensuite, nous activerons ce type dans le portail. Enfin, nous rendrons ce document flexible.
3.1.1
Les sch´mas e
L'aventure d´marre dans la ZMI, dans l'outil portal schemas. Cliquez sur le e bouton Add CPS Schema. L'identifiant demand´ est, vous l'avez compris, le e nom du sch´ma. L'usage qui s'est impos´ est de l'´crire en minuscules : saisissez e e e dzfp_article et validez. L'´cran suivant nous informe que le sch´ma est vide. e e Que pourrions-nous bien y a jouter ? «Il faut au moins un titre et une description ` mes documents. Et m^me, il faut a e qu'ils aient les m´ta-donn´es de Dublin Core1 !» e e Du calme. Les d´veloppeurs de CPS 3 y ont pens´ pour vous. Si vous jetez un e e coup d'oeil dans la liste des sch´mas existants, vous verrez common et metadata. e Le premier est un sch´ma qui r´unit tout ce qui est commun aux documents e e du portail et qui peut faciliter leur int´gration ` l'application. Le second r´unit e a e l'essentiel de ces fameuses m´ta-donn´es. Vous profitez ainsi de : e e Title Le titre du document. Description Sa description. Creator Son cr´ateur. e Contributors Personnes qui ont particip´ ` son ´laboration. ea e Format Le format de consultation (text/html sauf exception). Rights Les droits qui le prot`gent (droit d'auteur). e Source Son origine. Language La langue de son contenu. Coverage La port´e du document, quels domaines il concerne. e Relation A quel autre document se r´f´rer sur la m^me probl´matique. ee e e Sub ject Une liste de sujets (mots-cl´s) couverts par ce document. e CreationDate Date de cr´ation. e Mo dificationDate Derni`re date de modification. e EffectiveDate Date ` laquelle il prend effet. a ExpirationDate Date d'expiration. Inutile de vous dire qu'il est plus que conseill´ d'utiliser ce sch´ma dans vos types. e e Nous verrons comment au moment de cr´er le type de document lui-m^me. Le e e sch´ma common est moins vital mais tout de m^me pratique : e e
1 http://dublincore.org/
30
´ 3.1. CREER NOS TYPES DE DOCUMENTS preview Une image qui sert de vignette, d'ic^ne au document. o allow discussion Si CPSForum peut activer les commentaires sur ce document, en passant outre le r´glage global du type de document. e ` A vous de voir s'il vous est utile, ` moi oui. a Revenons ` notre propre sch´ma. Que nous reste-t-il que les sch´mas standard a e e ne couvrent pas ? Le contenu ´videmment. Dans le formulaire du bas, saisissez e comme Field Id, contenu et comme Field Type, CPS String List. Le type est simplement la fa¸on dont sera stock´ le contenu. Nous verrons sa repr´sentation c e e plus tard. L'´cran suivant permet d'affiner le comportement de des donn´es et e e surtout les droits d'acc`s. Rien de particulier de ce c^t´ mais cochez par contre e oe la case Indexed in SearchableText. Ce champ sera ainsi pris en compte quand le catalogue indexera les articles. En clair, les utilisateurs pourront effectuer une recherche sur le contenu des articles.
Fig. 3.1 Aspect de l'´cran de cr´ation d'un sch´ma. e e e Sauvegardons ce travail titanesque en retournant dans l'´cran du sch´ma dzfp article. e e Cliquez sur l'onglet Export et copiez le texte du dictionnaire python qui s'affiche alors. Il va nous falloir personnaliser un fichier de CPS, celui qui s'appelle getCustomDocumentSchemas.py 31
´ 3.1. CREER NOS TYPES DE DOCUMENTS et que vous trouverez dans CPSDocument/skins/cps_document. Copiez-le dans ´ le r´pertoire skins/install de votre produit. Editez ce script pour a jouter e cette d´finition de dictionnaire, au-dessus de celle de schemas et a joutez une e entr´e ` ce dernier pour associer l'identifiant du sch´ma ` sa d´finition. Voici ce ea e a e que j'obtiens au final :
dzfp_article_schema = { ' contenu ': { ' type ': ' CPS String Field ' , ' data ': { ' default_expr ': '', ' i s _ s e a r c h a b l e t e x t ': True , ' acl_read_permissions ': '', ' acl_read_roles ': '', ' acl_read_expr ': '', ' acl_write_permissions ': '', ' acl_write_roles ': '', ' acl_write_expr ': '', ' r e a d _ i g n o r e _ s t o r a g e ': False , ' read_process_expr ': '', ' r e a d _ p r o c e s s _ d e p e n d e n t _ f i e l d s ' : [] , ' w r i t e _ i g n o r e _ s t o r a g e ': False , ' write_process_expr ': '', }, }, } s c h e m a s = {} schemas [ ' dzfp_article '] = dzfp_article_schema return schemas
Fig. 3.2 D´finition des sch´mas de nos propres types e e Tout ce que nous avons fait sera ainsi restaur´ par le script d'installation. Noe tez que les cl´s utilis´es dans schemas deviendront les noms des sch´mas dans e e e p ortal schemas. Passons ` la repr´sentation de nos articles. a e
3.1.2
Les widgets
Un widget est un composant utilis´ pour repr´senter une ou plusieurs donn´es du e e e sch´ma et valider les valeurs qu'entre l'utilisateur. CPS 3 propose de nombreux e types de widgets mais nous verrons pour le sport comment cr´er le n^tre dans le e o chapitre ?. L'avantage de la s´paration des widgets et des sch´mas est ing´nieuse : e e e vous pouvez utiliser un autre widget pour repr´senter vos donn´es sans «casser» e e les documents existants. Vous n'avez m^me pas besoin de relancer un quelconque e script si vous passez par la ZMI, les effets sont imm´diats. Pensez par contre e ` synchroniser les scripts ` la getCustomDocument* si vous voulez conserver ce a a changement. Passez dans l'outil p ortal layouts et cliquez sur le bouton Add CPS Layout. Quel identifiant porte-t-il ? Le m^me que le sch´ma, c'est le plus simple. Saisissez e e 32
´ 3.1. CREER NOS TYPES DE DOCUMENTS donc dzfp_article et validez. Quelle t^te doivent avoir ces articles... il nous e faut un titre, une description et bien sur le contenu. Le reste est laiss´ ` la ^ ea discr´tion de l'auteur de l'article. Les d´tails seront acessibles dans le formulaire e e des m´ta-donn´es. e e Encore une fois, le travail est presque fait. Si au niveau des donn´es (sch´ma), e e common propose l'utilisation d'une vignette et du forum, sa mise en page par contre propose un affichage standard des documents. En pratique, CPS propose d'afficher le titre suivi de la description. L'affichage est ainsi concordant dans tout le portail, des r´pertoires aux documents. L'utilsation de common se fera e dans la cr´ation du type. Il s'agit maintenant d'afficher notre bloc de contenu. e Je vous conseille d'utiliser un TextWidget. Allez dans le layout de dzfp article et a joutez-le par le formulaire habituel de la ZMI. Le plus est de choisir le m^me e identifiant que pour le sch´ma : contenu. Validez le tout et pr´parez-vous ` e e a affronter le formulaire suivant : Title Le titre de ce widget . Les widgets manipulables dans les documents flexibles ont tout int´r^t ` proposer un titre car il sera utilis´ pour g´n´rer la liste ee a e ee d'a jout en bas de la page. Ce n'est pas le cas de notre ind´boulonnable e widget donc inutile de le renseigner. Fields Le ou les champs que manipule ce widget : contenu. Required widget Si coch´, le widget n'accepte pas de valeur vide. Je le coche e pour interdire les articles vides. Lab el in view layout mo de L'´tiquette qui pr´c`de le widget quand le doe ee cument est consult´. Je n'en ai pas besoin. e Lab el in edit layout mo de L'´tiquette mais cette fois quand le document est e ´dit´. Il est par contre n´cessaire d'aiguiller le contributeur. Toujours dans ee e un soucis d'internationalisation, je donne un identifiant plut^t qu'un vrai o texte : dzfp_article_contenu_label_edit. Description La description du widget est rarement utilis´e. Je fais de m^me. e e Help Le texte d'aide que l'utilisateur peut faire afficher ` la demande. Mes a contributeurs sont de grandes personnes, ils s'en passeront :-) Lab el is i18n Nos ´tiquettes sont-elles destin´es ` ^tre traduites ? C'est le cas. e e ae Read-only in layout mo des Dans quel mode (view, edit, create) la valeur ne peut ^tre modifi´e. Pas besoin de sp´cifier view. e e e Hidden in layout mo des Dans quel mode (view, edit, create) le widget est cach´. Aucun. e Hidden if readonly in layout modes Si le widget se retrouve en lecture seule dans ce mode, faut-il le cacher. Pas touche ! Hidden if empty Le cacher si la valeur est vide. Bien ´videmment ignor´ en e e mode edit. Hide the widget if the given TAL expression returns true Heu non merci ! CSS class for view Quelle classe CSS sera utilis´e dans la g´n´ration du wide ee get . Vous pouvez utiliser dcontent fournit par la feuille de style de CPSDo cument. Get the widget mo de from the given TAL expression N'insistez pas, merci ! Width Largeur de la zone de texte. Soyons g´n´reux : 60. ee 33
´ 3.1. CREER NOS TYPES DE DOCUMENTS
Fig. 3.3 Aspect de l'´cran de cr´ation d'une instance de widget. e e
34
´ 3.1. CREER NOS TYPES DE DOCUMENTS Height Hauteur de la zone de texte. 10 pour obtenir quelque chose de proportionnel. Max size Nombre maximum de caract`res autoris´s, 0 pour ne pas imposer de e e limites (autres que celles li´es aux protocoles du web). e Render p osition Pour forcer le positionnement sur la page. Cette zone de texte doit occuper la largeur donc normal. Render format Comment sera interpr^t´ le contenu. text se contente de reee produire les sauts de ligne, stx applique les r`gles du format Structured e Text et html autorise les balises HTML. What is user configurable, require extra fields Dans sa grande mansu´e tude, l'administrateur peut autoriser la modification des deux derniers choix. Je n'autorise pour ma part que le changement de format.
3.1.3
Le layout
De retour dans le layout de notre article, cliquez sur l'onglet Layout. Cette interface va vous permettre de mettre en page l'article. Ajoutez une ligne en cliquant sur le bouton Add row. Vous pourrez alors attribuer le widget contenu ` cet emplacement. Cliquez sur le bouton Change et votre document est mis en a page !
Fig. 3.4 Aspect de l'´cran de cr´ation d'un layout. e e Remarquez qu'il y avait de quoi s'amuser, placer des widgets c^te ` c^te, ce o ao genre de chose. Si vous voulez voir une mise en page avanc´e, regardez le layout e de metadata. Cliquez maintenant sur l'onglet properties. Cette interface vous permet d'a jouter un style de pr´fixe et des layouts flexibles. Nous utiliserons le style par d´faut et e e nous n'a joutons pas de layout flexible pour le moment : ne changez rien, nous y reviendrons dans les chapitres suivants. Il reste ` sauvegarder tout ceci. Vous trouverez ´galement un onglet Export qui a e fera afficher un dictionnaire. R´cup´rez-le pour l'a jouter dans getCustomDocumentLayouts.py. e e Le mode op´ratoire est le m^me que pour les sch´mas. Je vous laisse admirer le e e e r´sultat final : e
35
´ 3.1. CREER NOS TYPES DE DOCUMENTS
dzfp_article_layout = { ' widgets ': { ' contenu ': { ' type ': ' Text Widget ', ' data ': { ' title ': '', ' fields ': [ ' contenu '], ' i s _ r e q u i r e d ': True , ' label ': '', ' label_edit ': ' dzfp_article_contenu_label_edit ', ' description ': '', ' help ': '', ' i s _ i 1 8 n ': True , ' r e a d o n l y _ l a y o u t _ m o d e s ' : [] , ' h i d d e n _ l a y o u t _ m o d e s ' : [] , ' h i d d e n _ r e a d o n l y _ l a y o u t _ m o d e s ' : [] , ' hid den_empty ': False , ' hidden_if_expr ': '', ' css_class ': ' dcontent ', ' w i d t h ' : 60 , ' h e i g h t ' : 10 , ' size_max ': 0, ' render_position ': ' normal ', ' render_format ': ' text ', ' configurable ': ' format ', }, }, }, ' layout ': { ' style_prefix ': ' layout_default_ ', ' f l e x i b l e _ w i d g e t s ' : [] , ' ncols ': 1, ' rows ': [ [{ ' w i d g e t _ i d ' : ' c o n t e n u ' , ' n c o l s ' : 1} ,] , ], }, } l a y o u t s = {} layouts [ ' dzfp_article '] = dzfp_article_layout return layouts
Fig. 3.5 D´finition de la mise en page de nos types e Notez que les cl´s utilis´es dans layouts deviendront les noms des layouts dans e e p ortal layouts. Il ne manque plus que le ciment entre le sch´ma et la mise en e page : le type de document.
3.1.4
Le typ e de do cument
Rendez-vous pour finir dans l'outil portal types et a joutez par le menu en haut ` droite, un CPS Flexible Type Information. Ces informations d´crivent la fa¸on a e c de construire une instance de la classe CPSDocument du produit du m^me e nom. Saisissez DZFP_Article comme identifiant et validez. 36
´ 3.1. CREER NOS TYPES DE DOCUMENTS Vous vous retrouvez dans p ortal types, cliquez alors sur notre nouveau type de document. La page des propri´t´s est vide mais pourtant charg´e. D´taillons ee e e chacune d'entre elles avec la valeur dont j'ai besoin. Title L'intitul´ de ce type de document. Je lui fait suivre les conventions pour e la traduction : portal_type_DZFP_Article_title. Description La description qui accompagne le titre, par exemple dans la vue quand vous cliquez sur l'action Nouveau. Encore une fois, ce nom est destin´ ` ^tre traduit : portal_type_DZFP_Article_description. eae Icon Le nom de l'ic^ne pour repr´senter ce type de document. Comme celleo e ci sera cherch´e par votre navigateur au moment du rendu de la page, e assurez-vous simplement qu'une image de ce nom appara^t dans une des i skins de votre application. Je r´cup`re celle du type Nouvel le : news_icon.gif e e Pro duct meta typ e Le nom du type d'ob jet tel que l'entend Zope ` sa base, a aucune notion de type de document ici. Notre ob jet ´tant une instance de e CPSDo cument, laissez CPS Document. Pro duct name De quel produit provient ce type d'ob jet. Laissez CPSDocument. Pro duct factory method Quelle m´thode permet de cr´er un document de e e ce type. Laissez addCPSDocument. Initial view name Vers quelle m´thode de vue rediriger une fois que le docue ment est cr´´. Si vous voulez voir le document, utilisez cpsdocument view. ee Si vous voulez le modifier, utilisez cpsdocument edit form, c'est mon cas. Implicitly addable ? TODO. Laissez cette case coch´e. e Filter content typ es ? Si CPS doit restreindre les types de documents que les documents de ce type peuvent accepter. Bien que ce type ne soit pas un conteneur, laissez cette case tel quel. Allowed content typ es Le cas ´ch´ant, quels types de documents un docuee ment de ce type peut accepter. La remarque pr´c´dente s'applique. ee Allow Discussion ? CPSForum doit-il s'immiscer parmi les actions pour pou` voir commenter les documents de ce type ? A vous de voir, pour moi c'est le cas. CPS Searchable La recherche est-elle activ´e pour les documents de ce type ? e Si oui, ils seront index´s par l'outil portal catalog et ce type de document e appara^tra dans la liste des types du formulaire de recherche avanc´e. i e Assurez-vous dans les sch´mas utilis´s que les champs pertinents soient e e eux-m^mes index´s. e e CPS Proxytyp e Nous touchons ici un point sensible. Si les documents de ce type utilisent les proxies, ils profiteront du moteur de publication de CPS. C'est ce qu'il nous faut. Le type de proxy qui nous convient est document. Le type folderishdocument est con¸u pour les documents qui c peuvent en contenir d'autres, par exemple la galerie d'images. le type folder peut contenir des documents mais n'est pas publiable, par exemple les sections et les espaces de travail. Nous reviendrons sur le fonctionnement des proxies et le m´canisme du publication dans le chapitre concernant les e workflows. CPS Portal Box Ce type est-il un type de bo^te ? non, bien sur. i ^ 37
´ 3.1. CREER NOS TYPES DE DOCUMENTS Schemas La liste des sch´mas qui d´crivent notre document : metadata common e e dzfp_article. Layouts Par quelle mise en page est repr´sent´e les documents de ce type : e e common dzfp_article Flexible layouts Quelle combinaison de sch´mas et de layout (hors mise en e page sp´cifi´e dans l'onglet Layout ), s´par´s par le caract`re deux-points, ee ee e forme la partie flexible du document ? Nous verrons ce point un peu plus tard. Pour l'instant, laissez le champ tel quel. Storage metho ds TODO Comment sont stock´s les attributs des documents, e par exemple dans une base SQL. Cela d´passe le cadre de ce livre. e Validez le tout et cliquez sur l'onglet Export. Oui, les types de documents se sauvegardent aussi. Le mode op´ratoire doit maintenant vous ^tre familier. Le e e fichier final ressemble ` : a
""" Return custom document types . """ dzfp_article_type = { ' title ': ' portal_type_DZFP_Article_title ', ' description ': ' portal_type_DZFP_Article_description ', ' content_icon ': ' news_icon . gif ' , ' content_meta_type ': ' CPS Document ' , ' product ': ' CPSDocument ', ' factory ': ' addCPSDocument ', ' immediate_view ': ' cpsdocument_edit ', ' g l o b a l _ a l l o w ': True , ' f i l t e r _ c o n t e n t _ t y p e s ': True , ' a l l o w e d _ c o n t e n t _ t y p e s ' : [] , ' a l l o w _ d i s c u s s i o n ': True , ' c p s _ i s _ s e a r c h a b l e ': True , ' cps_proxy_type ': ' document ', ' c p s _ d i s p l a y _ a s _ d o c u m e n t _ i n _ l i s t i n g ': False , ' c p s _ i s _ p o r t a l b o x ': False , ' schemas ': [ ' metadata ', ' common ', ' dzfp_article '], ' layouts ': [ ' common ', ' dzfp_article '], ' f l e x i b l e _ l a y o u t s ' : [] , ' s t o r a g e _ m e t h o d s ' : [] , } types = {} types [ ' DZFP_Article '] = dzfp_article_type return types
Fig. 3.6 D´finition de nos types de documents e Voil` pour d´finir un type de document. Notez que les cl´s utilis´es dans types a e e e deviendront les noms des types dans portal types.
38
´ 3.1. CREER NOS TYPES DE DOCUMENTS
3.1.5
Activer ce typ e dans le p ortail
Pour tester le type de document que nous avons cr´´, nous allons configurer son ee workflow manuellement. Nous reviendrons plus pr´cis´ment sur le m´canisme ee e de workflow dans le chapitre suivant. Allez d'abord dans l'outil p ortal types, puis dans Workspace (Espace de travail). Le formulaire ressemble ` celui pr´c´demment rempli pour notre article. a ee Allez ` la propri´t´ Allowed content types et a joutez notre nouveau type ` a ee a la s´lection, probablement en maintenant la touche «Ctrl» appuy´e avant de clie e quer sur l'entr´e DZFP_Article, selon le navigateur utilis´. Validez le formulaire e e et les espaces de travail supportent d´sormais la cr´ation de nos articles en leur e e sein. Ce n'est pas suffisant car pour l'instant, ils ne suivent aucun workflow . Allez ensuite, toujours par la ZMI, dans workspaces ` la racine de CPS. L'ob jet a .cps_workflow_configuration donne les associations locales (placeful ) entre les types de documents et les workflows existants. Cliquez dessus et observons le formulaire. La premi`re partie (Local workflow chains ) indique quel workflow est associ´ e e ` chaque type ` partir de ce r´pertoire. Les types non-list´s sont consid´a a e e e r´s comme utilisant le workflow d´clar´ au niveau sup´rieur, dans l'outil pore e e e e tal workflow. Il est tr`s peu probable que cette valeur fonctionne, dans un espace comme dans une section. La seconde partie (Below workflow chains ) indique quel workflow est associ´ ` ea chaque type sous ce r´p ertoire. Les documents cr´´s ` cet endroit m^me ne e ee a e sont donc pas concern´s par ces r`gles-l`. Vous pouvez utiliser cette particularit´ e e a e pour configurer des espaces ou sections sp´ciaux ou la racine se comporte diff´e ` e remment de ses fils. C'est par exemple le cas de notre section des articles qui ne doit accepter que ce type de document. Plut^t que de restreindre manuellement o dans chaque sous-section, c'est la racine qui est configur´e. e Ainsi, dans la premi`re partie, descendez ` la liste d´roulante et choisissez notre e a e type, DZFP_Article. Il faut ensuite renseigner le nom du workflow ad´quat. Si e vous n'avez pas cherch´ les complications, la r`gle est simple. Si vous avez choisi e e comme type de proxy , folder, alors il vous faut saisir workspace_folder_wf. Pour document, c'est workspace_content_wf et pour folderishdocument c'est workspace_folderish_content_wf. Une cha^ne vide signifie que ce type n'est i tout simplement pas autoris´ ici et plus loin dans l'arborescence (sauf cha^ne e i renseign´e dans un .cps workflow configuration d'un r´pertoire fils). Pour nos e e articles, il faut donc renseigner workspace_content_wf. Cliquez ensuite sur le bouton Add. Il reste ` informer les sections pour qu'elles sachent quoi faire de notre nouveau a type. Allez dans le .cps_workflow_configuration des sections, s´lectionnez e notre type dans la liste et validez sans renseigner la cha^ne. Nous allons autoriser i la publication des articles uniquement ` l'emplacement ad´quat. a e Retournez dans le contenu de sections, toujours par la ZMI, puis copiez .cps_workflow_configuration. Allez ensuite dans Articles et collez cet ob jet. Cliquez dessus et dans la premi`re partie du formulaire, effacez le nom des workflows (` l'image de Workse a pace ), sauf peut-^tre pour Section si vous voulez laisser les administrateurs des e 39
´ 3.1. CREER NOS TYPES DE DOCUMENTS sections en cr´er de nouvelles sous Articles. e Ne supprimez pas les cha^nes elles-m^mes, sinon CPS remontera toutes les confii e gurations jusqu'` trouver quel workflow est associ´ (ou celui d´clar´ dans pora e e e ae tal workflow ` d´faut). C'est d'ailleurs pour cela que je copie la configuration de la racine, car elle est compl`te et m'´vite donc de devoir a jouter les types e e a ` cacher un par un. D'autant que tous les types list´s n'ont pas besoin d'^tre e e d´clar´s. Pour un simple changement de workflow local, qui ne remet pas en e e cause la configuration des autres types, vous pouvez bien sur vous contenter de ^ cr´er un nouveau .cps_workflow_configuration par la Add list de la ZMI et e de n'a jouter que la cha^ne qui diff`re. i e Dans la seconde partie du formulaire (Below workflow chains ), s´lectionnez e DZFP_Article dans la liste et la cha^ne section_content_wf. Pour un r´peri e toire, vous auriez choisi section_folder_wf. Ne confondez pas avec les documents conteneurs comme la galerie d'images qui suivent aussi le workflow section_content_wf. Validez et nos articles seront alors publiables uniquement sous la section Articles de notre site, sans inclure cette racine.
3.1.6
Rendre le do cument flexible
Plut^t que de se conformer ` un squelette fig´, les documents flexibles peuvent o a e ^tre modifi´s par leur auteur. Il peut par exemple a jouter une image ou un bloc e e de texte. Que les administrateurs se rassurent, ils peuvent tout de m^me imposer e une structure de base et ce sont eux d´terminent la liste des widgets a joutables e et leur quantit´. Au final, chaque document g`re son propre sch´ma et sa liste e e e de widgets , ceux sp´cifi´s comme non-flexibles ´tant les seuls communs ` tous ee e a les documents de ce type. Nous allons rendre le type de document d´fini pr´c´demment flexible. Pour e ee cela, nous allons modifier son layout, ainsi que le type du document. Il n'est pas n'´cessaire de modifier le sch´ma, car celui-ci, pour les ´l´ments flexibles du e e ee document, n'est pas pr´d´fini. ee Revenez dans l'outil p ortal layouts et cliquez sur le layout dzfp_article. La magie des documents flexibles commence dans l'onglet Properties. Vous y voyez deux propri´t´s : ee Prefix for zpt Ceci est le nom g´n´rique des templates utilis´s pour afficher ce ee e layout . Utilisez layout_default si vous ne savez pas. Le mode actuel sera accol´ ` ce nom pour savoir quel template appeler. Par exemple, en mode ea cr´ation, c'est la template layout_default_create qui sera utilis´e. Vous e e la trouverez dans CPSDocument/skins/cps_document. Nous verrons plus loin comment en cr´er une nouvelle. e Allowed widgets in flexible Ceci est la fameuse liste des widgets autoris´s. e Ce sont les noms de widgets pr´sents dans votre layout mais non g´e e r´s par la mise en page. Je cr´e pour ma part, les widgets texte (Text e e Widget ), image (Image Widget ), liste_ordonnee (Ordered List Widget ) et liste_simple (Unordered List Widget ). Il y a deux choses ` retenir. a D'abord, pensez ` leur donner un titre pour les raisons sus-mentionn´es. a e Ensuite, le secret du dynamisme de ces documents r´side dans le fait que e les champs seront cr´´s et supprim´s ` la vol´e. La fa¸on de sp´cifier ceci ee ea e c e 40
´ 3.1. CREER NOS TYPES DE DOCUMENTS est de donner ? comme valeur pour Fields. Une fois ceci fait, vous pouvez alors sp´cifier les widgets autoris´s : texte image liste_ordonnee e e liste_simple. Vous voulez limiter leur nombre ? il faut a jouteur le caract`re deux-points e suivi du nombre maximum, par exemple : texte :5 image :2 liste_ordonnee liste_simple afin de n'autoriser que cinq blocs de texte (en plus du bloc de contenu obligatoire), deux images et autant de listes qu'il pla^ra au i contributeur. Il vous suffit ensuite de modifier le code du fichier getCustomDocumentLayouts en utilisant l'onglet export. Le fichier final devrait se pr´senter de la fa¸on suie c vante :
dzfp_article_layout = { ' widgets ': { ' contenu ': { ' type ': ' Text Widget ', ' data ': { ' title ': '', ' fields ': [ ' contenu '], ' i s _ r e q u i r e d ': True , ' label ': '', ' label_edit ': ' dzfp_article_contenu_label_edit ', ' description ': '', ' help ': '', ' i s _ i 1 8 n ': True , ' r e a d o n l y _ l a y o u t _ m o d e s ' : [] , ' h i d d e n _ l a y o u t _ m o d e s ' : [] , ' h i d d e n _ r e a d o n l y _ l a y o u t _ m o d e s ' : [] , ' hid den_empty ': False , ' hidden_if_expr ': '', ' css_class ': ' dcontent ', ' w i d t h ' : 60 , ' h e i g h t ' : 10 , ' size_max ': 0, ' render_position ': ' normal ', ' render_format ': ' text ', ' configurable ': ' format ', }, }, ' texte ': { ' type ': ' Text Widget ', ' data ': { ' title ': ' dzfp_article_texte_title ', ' fields ': [ '? '], ' i s _ r e q u i r e d ': True , ' label ': '', ' label_edit ': ' dzfp_article_texte_label_edit_title ', ' description ': '', ' help ': '', ' i s _ i 1 8 n ': True , ' r e a d o n l y _ l a y o u t _ m o d e s ' : [] , ' h i d d e n _ l a y o u t _ m o d e s ' : [] , ' h i d d e n _ r e a d o n l y _ l a y o u t _ m o d e s ' : [] , ' hid den_empty ': False , ' hidden_if_expr ': '', ' css_class ': '', ' w i d t h ' : 60 , ' h e i g h t ' : 10 ,
41
´ 3.1. CREER NOS TYPES DE DOCUMENTS
' size_max ': 0, ' render_position ': ' normal ', ' render_format ': ' text ', ' configurable ': ' format ', }, }, ' image ': { ' type ': ' Image Widget ', ' data ': { ' title ': ' dzfp_article_image_title ', ' fields ': [ '? '], ' is_required ': False , ' label ': '', ' label_edit ': ' dzfp_article_image_label_edit ', ' description ': '', ' help ': '', ' i s _ i 1 8 n ': True , ' r e a d o n l y _ l a y o u t _ m o d e s ' : [] , ' h i d d e n _ l a y o u t _ m o d e s ' : [] , ' h i d d e n _ r e a d o n l y _ l a y o u t _ m o d e s ' : [] , ' hid den_empty ': False , ' hidden_if_expr ': '', ' css_class ': '', ' d e l e t a b l e ': True , ' size_max ': 1048576 , ' display_width ': 0, ' display_height ': 0, ' a l l o w _ r e s i z e ': True , }, }, ' liste_ordonnee ': { ' type ': ' Ordered List Widget ', ' data ': { ' title ': ' dzfp_article_liste_ordonnee_title ', ' fields ': [ '? '], ' is_required ': False , ' label ': '', ' label_edit ': ' dzfp_article_liste_ordonnee_label_edit ', ' description ': '', ' help ': '', ' is_i18n ': False , ' r e a d o n l y _ l a y o u t _ m o d e s ' : [] , ' h i d d e n _ l a y o u t _ m o d e s ' : [] , ' h i d d e n _ r e a d o n l y _ l a y o u t _ m o d e s ' : [] , ' hid den_empty ': False , ' hidden_if_expr ': '', ' css_class ': '', ' w i d t h ' : 60 , ' h e i g h t ' : 10 , ' format_empty ': '', }, }, ' liste_simple ': { ' type ': ' Unordered List Widget ', ' data ': { ' title ': ' dzfp_article_liste_simple_title ', ' fields ': [ '? '], ' is_required ': False , ' label ': '', ' label_edit ': ' dzfp_article_liste_simple_label_edit ', ' description ': '', ' help ': '',
42
´ 3.1. CREER NOS TYPES DE DOCUMENTS
' i s _ i 1 8 n ': True , ' r e a d o n l y _ l a y o u t _ m o d e s ' : [] , ' h i d d e n _ l a y o u t _ m o d e s ' : [] , ' h i d d e n _ r e a d o n l y _ l a y o u t _ m o d e s ' : [] , ' hid den_empty ': False , ' hidden_if_expr ': '', ' css_class ': '', ' w i d t h ' : 60 , ' h e i g h t ' : 10 , ' format_empty ': '', }, }, }, ' layout ': { ' style_prefix ': ' layout_default_ ', ' flexible_widgets ': [ ' texte ', ' image ', ' liste_ordonnee ', ' liste_simple '], ' ncols ': 1, ' rows ': [ [{ ' w i d g e t _ i d ' : ' c o n t e n u ' , ' n c o l s ' : 1} , ], ], }, } l a y o u t s = {} layouts [ ' dzfp_article '] = dzfp_article_layout return layouts
Fig. 3.7 D´finition du layout flexible e Nous allons ´galement rendre le type de document flexible : passez dans l'outil e e ee p ortal typ es et cliquez sur le type d´fini pr´c´demment, dzfp_article. Modifiez la propri´t´ Flexible Layout en y a joutant : dzfp_article :dzfp_article. ee Ces deux ´l´ments portent g´n´ralement le m^me nom, mais je vous pr´cise que ee ee e e le premier ´l´ment correspond au layout, et le second au sch´ma. ee e Voici le fichier getCustomDocumentTypes final :
""" Return custom document types . """ dzfp_article_type = { ' title ': ' portal_type_DZFP_Article_title ', ' description ': ' portal_type_DZFP_Article_description ', ' content_icon ': ' news_icon . gif ' , ' content_meta_type ': ' CPS Document ' , ' product ': ' CPSDocument ', ' factory ': ' addCPSDocument ', ' immediate_view ': ' cpsdocument_edit ', ' g l o b a l _ a l l o w ': True , ' f i l t e r _ c o n t e n t _ t y p e s ': True , ' a l l o w e d _ c o n t e n t _ t y p e s ' : [] , ' a l l o w _ d i s c u s s i o n ': True , ' c p s _ i s _ s e a r c h a b l e ': True , ' cps_proxy_type ': ' document ',
43
` ´ ´ 3.2. CHANGER LES REGLES DE SECURITE
' c p s _ d i s p l a y _ a s _ d o c u m e n t _ i n _ l i s t i n g ': False , ' c p s _ i s _ p o r t a l b o x ': False , ' schemas ': [ ' metadata ', ' common ', ' dzfp_article '], ' layouts ': [ ' common ', ' dzfp_article '], ' flexible_layouts ': [ ' dzfp_article : dzfp_article '], ' s t o r a g e _ m e t h o d s ' : [] , } types = {} types [ ' DZFP_Article '] = dzfp_article_type return types
Fig. 3.8 D´finition du type de document flexible e
3.2
3.2.1
Changer les r`gles de s´curit´ e e e
Restreindre l'acc`s aux annuaires e
Le sc´nario de CPSDefault en ce qui concerne l'acc`s aux annuaires ne convient e e pas ` zopefr.org. Les informations personnelles et surtout les adresses de coura riel ne peuvent pas rester accessibles aussi facilement. Nous allons donc modifier les droits d'acc`s de la fa¸on suivante : l'administrae c teur peut toujours faire son travail et le membre ne peut voir et modifier que son entr´e. e TODO
3.3
Les workflows
Dans ce chapitre, nous allons revenir sur le m´canisme de workflow, et allons e d´crire les workflows qui existent dans CPS. Ensuite, nous modifierons un de e ces workflows. La cr´ation d'un nouveau workflow sera abord´e dans le chapitre e e suivant.
3.3.1
Le m´canisme de workflow et les workflows existants e
Un workflow est un processus m´tier qui permet de faire circuler un ob jet - le e plus souvent un document - selon un parcours pr´´tabli. Ce parcours repr´sente ee e le «cycle de vie» du document, et sp´cifie quelles sont les actions possible sur le e document ` chaque ´tape de ce cycle. On d´finit quel workflow sera suivi par un a e e type de document particulier, et ` quel endroit particulier du site il sera suivi. a Un workflow est caract´ris´ par ses ´tats et ses transitions . Un document passe ee e d'un ´tat ` un autre en suivant une transition. Il existe ´galement des transie a e tions initiales (sans ´tat initial), des transitions finales (sans ´tat final), et des e e transitions ayant le m^me ´tat de d´part et de destination. Plusieurs transitions e e e 44
3.3. LES WORKFLOWS peuvent partir d'un m^me ´tat, et plusieurs transitions peuvent ´galement y e e e aboutir. Par convention, on utilise des noms communs pour nommer les ´tats, et des e verbes pour nommer les transitions. Le sch´ma suivant pr´sente les conventions e e utilis´es pour la repr´sentation d'un workflow. e e
Fig. 3.9 La repr´sentation de workflows. e Des permissions sont ´tablies sur un ´tat : ainsi, les documents dans cet ´tat e e e suivront les permissions d´finies. e De la m^me mani`re, des acteurs sont d´sign´s pour une transition ` accomplir. e e e e a Ces acteurs sont d´finis par un m´canisme plus ou moins complet de droits. e e Dans le cas qui nous concernent, ces acteurs seront d´finis par leur r^les locaux. e o Ainsi, seuls les acteurs d´finis pourront accomplir la transition en question. e Des variables, sur lesquelles nous ne nous apesantirons pas, accompagnent ces deux ´l´ments. Disons simplement que les variables contiennent de l'information ee concernant le parcours du document dans le workflow, comme par exemple le nom d'utilisateur de la personne qui a effectu´ la derni`re transition, la date de e e la derni`re transition,... e Nous allons expliciter ces notions, pour l'instant assez vagues, ` travers un a exemple de workflow : le workflow de publication. Nous verrons tout d'abord la d´finition de ce workflow dans CMF, puis nous pr´senterons le workflow de e e publication de CPS. Le m´canisme de publication repose sur le processus qui consiste ` valider un e a document de travail, lorsque l'on consid`re qu'il est suffisamment abouti pour e ^tre pr´sent´. e e e Trois ´tats peuvent donc ^tre d´finis : l'´tat de travail (Work ), l'´tat d'attente de e e e e e validation (Pending ) et l'´tat de publication (Published ). Quatre transitions sont e ´galement identifi´es : la transition initiale de cr´ation (Create ), la transition e e e de soumission pour publication (Submit ), la transition de refus de publication (Reject ), et la transition d'acceptation de publication (Publish ). Ces ´tats et transitions ont ´t´ repr´sent´s sur le sch´ma suivant. Ce workflow e ee e e e correspond au workflow de publication de CMF, m^me si ce dernier pr´sente e e 45
3.3. LES WORKFLOWS en fait d'autres transitions que nous n'aborderons pas ici.
Fig. 3.10 Le workflow de CMF. TODO - a completer. Le workflow de publication de CPS diff`re de celui de CMF du fait de la distince tion entre les espaces de travail («workspaces ») et les rubriques («sections ») : les espaces de travail sont d´di´s ` contenir les documents de travail, tandis que eea les rubriques sont d´di´es ` contenir les documents finis. ee a Du fait de cette distinction, le workflow de publication initial est coup´ en deux, e de mani`re ` obtenir, en fait, deux workflows distincts ; le premier ´tant suivi ea e dans les espaces de travail, et le second dans les rubriques. Seules les transitions sont modifi´es : les ´tats d´finis pr´c´demment ne changent pas. e e e ee D´crivons le workflow de publication de CPS repr´sent´ sur la figure pr´c´dente. e e e ee Les acteurs ayant la possibilit´ d'effectuer la transition initiale de cr´ation sont : e e un membre de l'espace de travail, un responsable de l'espace de travail, et un administrateur du portail. Un autre acteur ne pourra donc pas cr´er de nouveau e document. Dans l'´tat de travail Work, les personnes ayant le droit de voir le document e sont : un lecteur, un membre ou un responsable de l'espace de travail, et un administrateur du portail. Les personnes ayant le droit de modifier ce document sont un membre ou un responsable de l'espace de travail, le cr´ateur du e document, et un administrateur du portail. La transition suivante, Copy Submit, peut ^tre ´galement effectu´e par un membre ee e ou un responsable de l'espace de travail, ou un administrateur du portail. Cette transition effectue une copie du document ` l'endroit sp´cifi´ par le demandeur a ee 46
3.3. LES WORKFLOWS
Espace de travail
Section
Create Copy_Submit Submit
Reject
Work
Pending
Accept
Published
Fig. 3.11 Le workflow de CPS.
47
3.3. LES WORKFLOWS (plus pr´cis´ment, elle effectue une copie du proxy pointant sur le document). ee C'est une transition qui ne change pas d'´tat dans le workflow de publication e dans les espaces de travail. La transition Submit est un transition initiale dans le deuxi`me workflow, celui e op´rant dans les sections. Elle peut ^tre effectu´e par un membre du portail ou e e e un administrateur du portail. En pratique, elle est initi´e par la transition Copy e Submit. Dans l'´tat d'attente de validation Pending, les personnes ayant le droit de voir e et modifier le document sont un valideur ou un responsable de la section, ou un administrateur du portail. Les transitions Accept et Reject peuvent ^tre effectu´es par les m^mes acteurs e e e (valideur ou un responsable des sections, ou un administrateur du portail). Si c'est la transition Reject qui est effectu´e, le document est d´truit (ou plus e e exactement, son proxy). Cette transition est une transition finale du workflow de publication dans les sections. Si c'est la transition Accept qui est effectu´e, le document est dans l'´tat Pue e blished. Les permissions sur cet ´tat font que le document est visible par un e lecteur, un membre ou un responsable de la section, et par un administrateur du portail. Les workflows de publication de CPS pr´sentent en fait d'autres ´tats et transie e tions que nous n'avons pas abord´s ici. Vous pouvez consulter ces worklows dans e la ZMI, dans p ortal workflow, dans l'onglet Contents : ce sont les workflows workspace_content_wf et section_content_wf.
3.3.2
Changer les r`gles des workflows e
Nos documents suivent pour l'instant le workflow par d´faut, le m^me que pour e e les types de CPS. Ils sont donc au m^me titre, autoris´s ` manipulation dans e ea les espaces de travail et ` publication dans les sections, apr`s acceptation par a e mod´ration. e Voyons comment modifier leur workflow . Le plus simple pour faire un nouveau workflow est de partir d'un autre existant. Ce qui sous-entend qu'il est pr´f´rable que les ´tats et les transitions portent les ee e m^mes noms si possible. Vous ´viterez ainsi des mauvaises surprises. e e ` A titre d'exemple, je vais faire un workflow de publication directe, sans mod´rae tion. Il sera utilis´ par les journaux. Tout ce qui suit se passe dans la ZMI. Ale lez dans p ortal workflow, dans l'onglet Contents et copiez-collez le workflow section_content_wf. Renommez-le en section_direct_wf et cliquez dessus pour acc´der ` son contenu. e a Dans l'onglet States, supprimez pending. Dans l'onglet Transitions, supprimez accept, cut_copy_paste, reject et submit. Entrez dans la transition publish et choisissez pour les r^les Manager ; Member (les m^mes que pour l'ancienne o e transition submit. Passez ensuite dans la transition unpublish et Ajoutez Owner
48
3.4. L'INTERNATIONALISATION DE L'APPLICATION ` la liste des r^les. L'auteur du journal pourra ainsi le d´publier par lui-m^me. a o e e Le reste est bon. Les permissions de l'´tat published conviennent toujours. Evitez e de toucher aux variables g´r´es par ce workflow, ce sera une occasion de moins ee de faire des b^tises. e Associons-le maintenant ` nos documents de type journal... qui n'existent pas a que dans mon imagination, regardez les scripts complets ` la fin. Copiez l'ob jet a .cps_workflow_configuration ` la racine des sections, copiez-le dans la seca tion Journaux et interdisez tous les types sauf Section. Si vous ^tes perdu, c'est e que vous n'avez pas du lire les explications pr´c´dentes... ^ ee La configuration va consister ` a jouter une cha^ne pour associer les journaux et a i ce nouveau workflow . Dans la partie du bas (Below workflow chains ), Choisissez DZFP_Journal dans la liste, renseignez section_direct_wf puis validez. Les journaux ne pourront donc ^tre publi´s qu'ici. . .sauf .cps_workflow_configuration e e en amont ou en aval de l'arborescence qui contredit nos r`gles. V´rifiez ` ce sujet e e a quelle est la cha^ne de workflow des journaux dans la configuration ` la racine i a des sections.
3.4
TODO
L'internationalisation de l'application
49
Chapitre
4
D´velopp er p our CPS e
En restant seul Je deviens un danger pour moi-m^me e Etienne Daho, La baie
4.1
Cr´er un typ e de b o^te e i
Nous allons maintenant aller plus loin en ´crivant notre propre code plut^t qu'en e o personnalisant celui de CPS. Pour d´buter, je vais vous montrer comment ´crire e e un nouveau type de bo^te qui fera afficher des fortunes. Il s'agit de ces petits i messages, h´rit´s des fortune cookies chinois, qui contiennent le plus souvent ee une citation c´l`bre ou une phrase humoristique. Les utilisateurs des syst`mes ee e Unix les connaissent par la commande fortune. C'est ` cette derni`re que nous a e allons faire appel pour les obtenir. Parlons entre programmeurs. Les bo^tes sont des instances de classes, avec leur i ´tat et leur comportement, soit de la classe BaseBox soit d'une classe qui en e h´rite. Vous trouverez ces classes dans CPSDefault, par exemple BaseBox.py. e ` quoi doit ressembler une classe de bo^te ? Elle ne se contente pas d'h´riter A i e de BaseBox. Une bo^te est un Portal Type et ` ce titre, elle doit avoir une i a factory type information qui indique ` CMF comment se comportent ces ob jets. a Il ne faut pas non plus oublier la gestion de la s´curit´ propre ` Zope et bien e e a sur nos m´thode de vue pour contr^ler et faire afficher le r´sultat de l'appel ` ^ e o e a la commande fortune. Cr´ez le fichier FortuneBox.py ` la racine de notre produit et copiez-y les ime a ports n´cessaires : e
from Globals import InitializeClass from AccessControl import ClassSecurityInfo f r o m z L O G i m p o r t LOG , I N F O from P r o d u c t s . C M F C o r e . C M F C o r e P e r m i s s i o n s i m p o r t View , M o d i f y P o r t a l C o n t e n t from Products . CPSDefault . BaseBox import BaseBox from os i m p o r t s y s t e m as os_system , r e m o v e as o s _ r e m o v e
50
´ 4.1. CREER UN TYPE DE BO^TE I
from tempfile import mktemp
Fig. 4.1 Imports n´cessaire ` la bo^te de fortunes e a i Viens ensuite la d´claration de la factory type information. Avec celle-ci, CMF e sera en mesure de cr´er une nouvelle instance dans l'outil portal types : e
factory_type_information = ( { # requis par CMF ' id ': ' F o rt u n e Box ' , ' title ': ' portal_type_FortuneBox_title ', ' description ': ' portal_type_FortuneBox_description ', ' meta_type ': ' Fortune Box ' , ' icon ': ' box . gif ' , ' product ': ' DaZopeFrenchPage ', ' factory ': ' addFortuneBox ', ' immediate_view ': ' fortunebox_edit_form ', ' filter_content_types ': 0, ' actions ': ( { ' id ': ' view ' , ' name ': ' View ', ' action ': ' basebox_view ', ' p e r m i s s i o n s ' : ( View ,) , }, { ' id ': ' edit ' , ' name ': ' Edit ', ' action ': ' fortunebox_edit_form ', ' p e r m i s s i o n s ' : ( M o d i f y P o r t a l C o n t e n t ,) , }, ), # requis par CPS ' cps_is_portalbox ': 1, }, )
Fig. 4.2 D´claration de la factory type information e J'utilise un bloc d'instruction afin de tester si la commande fortune est accessible ` Zop e. Celui-ci sera ex´cut´ par Zope ` chaque import de notre produit a ee a (d´marrage ou rafra^chissement). e i
# v ´ r i f i e la p r ´ s e n c e de la c o m m a n d e ' f o r t u n e ' au d ´ m a r r a g e e e e if o s _ s y s t e m ( ' f o r t u n e > / dev / null 2 >&1 ' ): # si pas 0 alors erreur _FORTUNE_IS_INSTALLED = 0 LOG ( ' D a Z o p e F r e n c h P a g e ' , INFO , " The ' f o r t u ne ' c o m ma n d is not " \ " i n s t a l l e d or not c o v e r e d by the same PATH v a r i a b l e as " \ " the Zope process . Fortune Boxes cannot work . " ) else : LOG ( ' D a Z o p e F r e n c h P a g e ' , INFO , " F o r t u n e s are a v a i l a b l e to the " \ " Fortune Box . " ) _FORTUNE_IS_INSTALLED = 1
51
´ 4.1. CREER UN TYPE DE BO^TE I
Fig. 4.3 V´rification au d´marrage de la commande fortune e e Viens ensuite la classe elle-m^me. Remarquez qu'elle h´rite de BaseBox et que e e j'a joute une propri´t´ : ee
class F o r t u n e B o x ( B a s e B o x ): """ Display fortune messages . """ meta_type = ' Fortune Box ' portal_type = ' Fortune Box ' s e c u r i t y = C l a s s S e c u r i t y I n f o () _properties = BaseBox . _properties + ( { ' id ': ' s i z e _ m a x ' , ' type ': ' int ' , ' mode ': 'w ' , ' label ': ' Maximum text size '}, )
Fig. 4.4 D´claration de la classe FortuneBox e Il y a une subtilit´ avec le constructeur, il faut changer de provider car sinon, la e macro fortunebox default pour afficher la bo^te sera cherch´e dans boxes_nuxeo.pt : i e
d e f _ _ i n i t _ _ ( s el f , id , s i z e _ m a x = 1 6 0 , * * k w ) : B a s e B o x . _ _ i n i t _ _ ( s e l f , id , p r o v i d e r = ' d z f p ' , c a t e g o r y = ' f o r t u n e b o x ' , ** kw ) self . size_max = size_max
Fig. 4.5 Constructeur de la classe FortuneBox Vient ensuite la m´thode pour r´cup´rer une fortune. La complication vient e e e du fait qu'il n'existe pas de commande permettant d'appeler un ex´cutable et e de r´cup´rer sa sortie. Il faut rediriger celle-ci dans un fichier (temporaire et e e s´curis´) puis lire ce fichier. Remarquez que je garde les lignes du fichier dans e e une liste :
security . declarePublic ( ' getFortuneLines ') def g e t F o r t u n e L i n e s ( self ): " " " Invoke the ' f o r t u n e ' c o m m a n d and return the result as a list of lines . The -n option is p r o v i d e d if s i z e _ m a x is not 0. """ if not _ F O R T U N E _ I S _ I N S T A L L E D : return [ " fortune : command not found " ] tempfile = mktemp ( ' fortunebox ') if self . s i z e _ m a x : c o m m a n d = ' f o r t u n e -n % d > % s 2 >&1 ' % ( self . size_max , t e m p f i l e ) else : c o m m a n d = ' f o r t u n e > % s 2 >&1 ' % t e m p f i l e
52
´ 4.1. CREER UN TYPE DE BO^TE I
os_system ( command ) f = open ( tempfile , "r") lines = f . r e a d l i n e s () f . close () os_remove ( tempfile ) return lines
Fig. 4.6 M´thode de r´cup´ration des fortunes e e e J'a joute alors deux m´thodes de plus haut niveau, ou front-ends disons, pour e r´cup´rer la fortune sous forme de texte ou de HTML, avec les retours de ligne e e sp´cifiques ` chaque format : e a
security . declarePublic ( ' getFortuneAsText ') def g e t F o r t u n e A s T e x t ( self ): " " " Return the f o r t u n e as a block of text . """ return '\ n '. join ( self . getFortuneLines ()) security . declarePublic ( ' getFortuneAsHtml ') def g e t F o r t u n e A s H t m l ( self ): " " " Return the f o r t u n e as a f o r m a t t e d HTML block . """ r e t u r n ' < br > ' . j o i n ( s e l f . g e t F o r t u n e L i n e s ( ) )
Fig. 4.7 M´thodes de mise en forme du texte de la fortune e Il reste ` faire initialiser la classe et a jouter un constructeur Zope pour l'intera face web :
InitializeClass ( FortuneBox ) d e f a d d F o r t u n e B o x ( d i s p a t c h e r , id , R E Q U E S T = N o n e , * * k w ) : " " " Add a Fortune Box . """ o b = F o r t u n e B o x ( id , * * k w ) c o n t a i n e r = d i s p a t c h e r . D e s t i n a t i o n () c o n t a i n e r . _ s e t O b j e c t ( id , o b ) if R E Q UE S T is not None : url = d i s p a t c h e r . D e s t i n a t i o n U R L () REQUEST . RESPONSE . redirect ( '% s / manage_main ' % url )
Fig. 4.8 Initialisation et constructeur Zope de la classe Maintenant que ce module est fini, vous pouvez faire dans le fichier __init__.py du produit les d´clarations n´cessaires afin de pouvoir a jouter une instance de e e bo^te de fortune par la ZMI. Les voici : i
53
´ 4.1. CREER UN TYPE DE BO^TE I
# ... from Products . CMFCore . utils import ContentInit from Products . CMFCore . CMFCorePermissions import AddPortalContent import FortuneBox c o n t e n t C l a s s e s = ( F o r t u n e B o x . FortuneBox ,) c o n t e n t C o n s t r u c t o r s = ( F o r t u n e B o x . addF ortuneBox ,) fti = ( FortuneBox . factory_type_information + ()) # ... def i n i t i a l i z e ( r e g i s t r a r ): ContentInit ( ' DaZopeFrenchPage Content ', content_types = contentClasses , permission = AddPortalContent , extra_constructors = contentConstructors , fti = fti , ). i n i t i a l i z e ( r e g i s t r a r )
Fig. 4.9 D´claration des ob jets de notre module e Vous pouvez maintenant red´marrer Zope afin qu'il d´tecte notre nouveau code. e e Vous pourrez ensuite a jouter un fichier refresh.txt ` la racine du produit afin a de faire prendre en compte le code chang´ sans avoir ` tout red´marrer. Ceci a e a e aussi pour avantage de laisser Zope vous montrer les erreurs de syntaxe depuis la page concern´e dans le panneau de contr^le. e o Il sera n´cessaire de faire a jouter ce nouveau Portal Type par notre script d'inse tallations mais vous pouvez d`s maintenant faire cette ´tape manuellement afin e e de tester. Pour cela, allez dans l'outil portal types et choisissez d'a jouter une Factory-based Type Information. L'identifiant est Fortune Box et choisissez dans la liste DaZopeFrenchPage : Fortune Box. Il reste ` d´clarez les diff´rentes types de notre bo^te de fortunes. Il n'y a besoin ae e i pour l'instant que de default. Ouvrez pour cela le fichier getCustomBoxTypes.py pour a jouter ` la fin du dictionnaire : a
{ ' category ': ' fortunebox ', ' title ': ' portal_type_FortuneBox_title ', ' desc ': ' portal_type_FortuneBox_description ', ' types ': [{ ' p r o v i d e r ': ' dzfp ' , ' id ': ' d e fa u l t ' , ' desc ': ' description_dzfp_fortunebox_default ', ' c o n f i g ' : {} , }, ], },
Fig. 4.10 D´claration des variantes de la bo^te de fortunes e i Vous pourrez alors utiliser l'interface de gestion des bo^tes de CPS pour tester i cette petite merveille. Les traductions seront faites plus tard. 54
´ 4.1. CREER UN TYPE DE BO^TE I Voyons, pour finir, le code ` a jouter dans le script d'installation pour a jouter a ce nouveau Portal Type :
class D Z F P I n s t a l l e r ( B a s e I n s t a l l e r ): # ... def i n s t a l l ( self ): # ... self . log ( " Ajout des nouveaux types " ) self . s e t u p T y p e s () # ... # ... def s e t u p T y p e s ( self ): " " " I n s t a l l e l e s n o u v e a u x t y p e s d a n s ' p o r t a l _ t y p e s '. """ from Products . DaZopeFrenchPage import FortuneBox fortunebox_fti = FortuneBox . factory_type_information [0] types = ( { ' id ': f o r t u n e b o x _ f t i [ ' id '] , ' meta_type ': fortunebox_fti [ ' meta_type '], ' title ': fortunebox_fti [ ' title '], ' description ': fortunebox_fti [ ' description '], }, ) ttool = self . portal . portal_types ptypes = ttool . o b j e c t I d s () for type in types : id = type [ ' id '] if id in p t y p e s : self . log ( " S u p p r e s s i o n de l ' a n c i e n " + id ) ttool . m a n a g e _ d e l O b j e c t s ( id ) self . log ( " Ajout de " + id ) ttool . manage_addTypeInformation ( i d = id , add_meta_type = ' Factory - based Type Information ', t y p e i n f o _ n a m e = ' D a Z o p e F r e n c h P a g e : ' + id , ) ttool [ id ]. m a n a g e _ c h a n g e P r o p e r t i e s ( title = type [ ' title '], description = type [ ' description '], content_meta_type = type [ ' meta_type '], ) # ...
Fig. 4.11 Code d'a jout du nouveau type dans le script d'installation Rappelez-vous aussi que vous pouvez exporter la d´finition de votre instance e ` de bo^te depuis la ZMI, afin de l'a jouter au dictionnaire des nouvelles bo^tes. A i i vous de voir la mise en page qui vous convient le mieux. Voici ce que ¸a donne c sur zopefr.org :
55
´ 4.2. CREER UN TYPE DE WIDGET
4.2
TODO
Cr´er un typ e de widget e
4.3
TODO
Cr´er un workflow e
56
´ 4.3. CREER UN WORKFLOW
Fig. 4.12 La bo^te de fortune ins´r´e dans le site. i ee
57
Annexe
A
Pour aller plus loin
And in the end The love you take Is equal to the love you make Paul McCartney, The end
TODO
58
Annexe
B
Ressources sur CPS
B.1
CPS Pro ject
http://www.cps- project.org/ Le site communautaire de CPS. Les contributions y sont post´es sous forme de e documentations ou de produits.
B.2
cps-users-fr
cps- users- fr@lists.nuxeo.com La liste de diffusion francophone des utilisateurs de CPS.
B.3
cps-users
cps- users@lists.nuxeo.com La liste de diffusion anglophone des utilisateurs de CPS.
B.4
cps-devel
cps- devel@lists.nuxeo.com La liste de diffusion anglophone des d´veloppeurs de CPS. e
B.5
CPS 3 Bo ok
http://cps3book.zopefr.org/ L'adresse de ce livre.
59
B.6. DA ZOPE FRENCH PAGE
B.6
Da Zop e French Page
http://www.zopefr.org/ Et bien ´videmment notre propre site :-) e
60
Annexe
C
Ressources sur Zop e et CMF
C.1
Zop euse.org
http://www.zopeuse.org/ Un site d'astuces et de documentation sur Zope et Plone en fran¸ais. c
C.2
Zop e Bo ok
http://www.zope.org/Documentation/Books/ZopeBook/ L'indispensable Zope Book, la r´f´rence technique. ee
C.3
French Zop e Bo ok
http://zopebook.oursours.net Le pro jet de traduction du Zope Book en fran¸ais. Encore un coup de votre c serviteur, heureusement aid´ dans cette t^che titanesque. e a
C.4
Zop e Develop er Guide
http://www.zope.org/Documentation/Books/ZDG/ Le Developer Guide pour apprendre ` ´crire un produit pour Zope. ae
C.5
Zop e Labs
http://www.zopelabs.com/ Une mine d'astuces pour Zope en anglais.
61
C.6. DOCUMENTATION DCWORKFLOW
C.6
Do cumentation DCWorkflow
http://www.zope.org/Members/hathawsh/DCWorkflow_docs Une documentation sur le module de gestion des workflows, utilis´ dans CMF, e en anglais.
62
Annexe
D
Script d'initialisation
from Products . CMFCore . DirectoryView import registerDirectory from Products . CMFCore . utils import ContentInit from Products . CMFCore . CMFCorePermissions import AddPortalContent import FortuneBox c o n t e n t C l a s s e s = ( F o r t u n e B o x . FortuneBox ,) c o n t e n t C o n s t r u c t o r s = ( F o r t u n e B o x . addF ortuneBox ,) fti = ( FortuneBox . factory_type_information + ()) registerDirectory ( ' skins ' , globals ()) def i n i t i a l i z e ( r e g i s t r a r ): ContentInit ( ' Fortune Boxes ', content_types = contentClasses , permission = AddPortalContent , extra_constructors = contentConstructors , fti = fti , ). i n i t i a l i z e ( r e g i s t r a r )
63
Annexe
E
Script d'installation
from Products . CPSDefault . Installer import BaseInstaller # p r o p r i ´ t ´ s du p o r t a i l ee PROPERTIES = ( { ' id ': ' title ' , ' value ': " Da Zope French Page " } , { ' id ': ' d e s c r i p t i o n ' , ' value ': " News , journaux , forums et a s t uc e s sur Zope ! " } , ) # skins pour s u r c h a r g e r celles de CPS SKINS = ( ( ' dzfp_default ', ' Products / DaZopeFrenchPage / skins / default '), ( ' dzfp_images ', ' Products / DaZopeFrenchPage / skins / images '), ( ' dzfp_styles ', ' Products / DaZopeFrenchPage / skins / styles '), ) # liste des noms de bo^tes ` e f f a c e r i a BOITES_EFFACEES = ( ' welcome ', ' l10n_select ', ' navigation ', ' search ', ' action_folder ', ' action_object ', ) # dictionnaire des bo^tes dont les propri´t´s sont ` changer i ee a BOITES_CHANGEES = { ' a c t i o n _ p o r t a l ' : { ' o r d e r ' : 20 , }, ' action_user ': { ' provider ': ' dzfp ', ' slot ': ' top ' , }, ' footer ': { ' provider ': ' dzfp ', }, ' logo ': { ' provider ': ' dzfp ', ' o r d e r ' : 10 , }, ' menu ': { ' provider ': ' dzfp ', }, } # dictionnaire des bo^tes ` ajouter avec leurs propri´t´s i a ee NOUVELLES_BOITES = { ' dernieres_breves ': { ' type ': ' Content Box ' , ' title ': ' Derni`res br`ves ', e e ' provider ': ' dzfp ', ' btype ': ' dernieres_breves ', ' box_skin ': ' here / box_lib / macros / box ' , ' minimized ': 0,
64
' closed ': 0, ' slot ': ' center ', ' order ': 2, ' display_in_subfolder ': 0, ' display_only_in_subfolder ': 0, ' locked ': 0, }, ' en_attente ': { ' type ': ' Content Box ' , ' title ': ' P u b l i c a t i o n s en a t te n t e ' , ' provider ': ' dzfp ', ' btype ': ' en_attente ', ' box_skin ': ' here / box_lib / macros / mmcbox ', ' minimized ': 0, ' closed ': 0, ' slot ': ' left ', ' o r d e r ' : 20 , ' display_in_subfolder ': 1, ' display_only_in_subfolder ': 0, ' locked ': 0, }, ' barre_de_liens ': { ' type ': ' Base Box ' , ' title ': ' Barre de liens ' , ' provider ': ' dzfp ', ' btype ': ' linkbar ', ' box_skin ': ' here / box_lib / macros / box ' , ' minimized ': 0, ' closed ': 0, ' slot ': ' top ' , ' order ': 1, ' display_in_subfolder ': 1, ' display_only_in_subfolder ': 0, ' locked ': 0, }, ' actions_contexte ': { ' type ': ' Action Box ' , ' title ': ' Actions contextuelles ', ' provider ': ' dzfp ', ' btype ': ' actions_contexte ', ' box_skin ': ' here / box_lib / macros / box ' , ' minimized ': 0, ' closed ': 0, ' slot ': ' center_top ', ' order ': 0, ' display_in_subfolder ': 1, ' display_only_in_subfolder ': 0, ' locked ': 0, }, ' fortune ': { ' type ': ' Fortune Box ' , ' title ': ' Fortune ! ', ' provider ': ' dzfp ', ' btype ': ' default ', ' box_skin ': ' here / box_lib / macros / mmcbox ', ' minimized ': 0, ' closed ': 0, ' slot ': ' left ', ' order ': 1000 , ' display_in_subfolder ': 1, ' display_only_in_subfolder ': 0, ' locked ': 0, ' size_max ': 0, }, }
65
BOITE_PLAN = { ' plan_site ': { ' type ': ' Tree Box ' , ' title ': ' Plan d