Création d'un produit zope minimal

La création d'un produit dans zope n'est pas des plus aisée. Mais je vais tenter avec mes maigres et fraiches connaissances de vous expliquer pas à pas le moyen de créer un produit minimal.

Je suppose que vous avez déjà installé zope et que vous avez créé une instance. J'ai développé l'exemple de produit dans un environnement GNU/Linux avec zope 2.9.4, et python 2.4.4. Je pense que c'est aisément portable sous un autre système. Je suppose aussi que vous connaissez un minimum zope: la ZMI, démarrer/arréter le serveur, ...Je suppose que vous connaissez aussi un tout petit peu python.

Encore une fois, je ne vais pas être très original: on va créer un produit qui affiche Hello World! Un grand classique.

Le produit HelloWorld que l'on va créer va permettre de créer un objet zope. La "vue" de cet objet va simplement afficher "Bonjour le Monde"!

L'objet HelloWorld minimal (hello.py) pourrait ressembler à ça:

class Hello:
   def index_html(self):
      return "Bonjour le monde"

On a alors un objet python. Ce n'est pas encore un produit zope. La première chose à savoir est que zope ne publit pas les objets qui n'ont pas de chaînes de documentation. Tout objet zope doit avoir un identifiant unique. On va donc ajouter le constructeur de l'objet Hello qui assignera un identifiant à notre objet:

class Hello:
    "Objet Hello plein de fonctionalités"

    def __init__(self, id):
        "Initialise l'objet"
        self.id = id

    def index_html(self):
        "affiche Bonjour le monde"
        return "Bonjour le monde"

On a maintenant un produit zope. Il ne reste plus qu'à le déclarer auprès de zope. Tout produit zope est organisé en "package". On va mettre notre classe dans un répertoire HelloWorld et on va placer le répertoire à l'endroit qui va bien. On peut placer le produit soit dans le répertoire Products de zope (lib/python/Products/) et le produit existera pour toutes les instances, soit le placer dans le répertoire Products de l'instance que l'on utilise et il n'existera que pour cette instance. Il y a juste une dernière chose à ajouter pour que notre produit apparaissent dans la liste des produits installables: lui donner un nom unique! Cela se fait avec la propriété meta_type. Notre objet installable ressemble désormais à ceci:

class Hello:
    "Objet Hello plein de fonctionalités"

    meta_type = "Hello World"

    def __init__(self, id):
        "Initialise l'objet"
        self.id = id

    def index_html(self):
        "affiche Bonjour le monde"
        return "Bonjour le monde"

Si on place le répertoire dans le répertoire Products, on doit voir apparaitre le produit dans la liste des produits installables. On va ajouter un peu de code pour créer une instance de notre objet. Tout d'abord pour bénéficier de plein de fonctionnalités (copier/coller, vue, support webdav, support ftp, support annuner (undo), ...) accessibles à partir de la ZMI, on va dériver la classe SimpleItem du package zope OFS. On va ajouter une méthode (add_HelloProduct) qui crée une instance de notre objet dans un dossier: _setObject(), qui est une méthode de la classe ObjectManager. Cette méthode attend deux paramètres: le premier est un identifiant (que je nommerais hello_id), le deuxième est l'appel au constructeur de l'objet:

self._setObject('hello_id', Hello('hello_id'))

Toutes les instances auront le même identifiant. C'est mal! Mais ce n'est qu'un objet minimal et on verra par la suite comment changer cela. On ne pourra évidemement créer qu'une seule instance de notre objet. Notre classe ressemble alors à ceci:

from OFS import SimpleItem

class Hello(SimpleItem.SimpleItem):
    "Objet Hello minimal"

    meta_type = "Hello World"

    def __init__(self, id):
        """Initialise l'objet"""
        self.id = id

    def index_html(self):
        "affiche Bonjour le monde"
        return "Bonjour le monde"


def add_HelloProduct(self):
    """Ajout d'un produit Hello minimal"""
    self._setObject('hello_id', Hello('hello_id'))

Il ne reste plus qu'à ajouter un constructeur (__init__.py) pour notre produit qui va automatiquement créer une instance lorsqu'on va sélectionner le produit pour l'ajouter. Lorsque l'on fait cela zope appelle une méthode initialize() qui reçoit le contexte (la classe context). On va utiliser la méthode regsiterClass de la classe context pour déclarer notre instance. Cette méthode attend en paramètres le nom de la classe du produit (hello.Hello) et une liste d'arguments permettant de créer l'instance. C'est là que l'on va faire appel à la méthode add_HelloProduct. Notre constructeur ressemble à ceci:

import hello

def initialize(context):
    "Fonction pour ajouter le produit dans la liste des produits disponibles."
    context.registerClass(hello.Hello,
                          constructors = (hello.add_HelloProduct,)
                          )

Le produit zope que l'on vient de créer à la structure suivante:

HelloWorld

Vous pouvez aussi récupérer directement le package que vous désarchivez dans le répertoire Products de votre instance. Il suffit alors de redémarrer zope pour voir apparaitre le produit HelloWorld dans la liste des produits installables. On peut alors l'installer et créer une instance en ajoutant le produit. Pour avoir la vue de l'instance il suffit d'accéder à l'url suivante: index_html. Mon instance tournant sur le port 8080.

Problèmes connus:

  • Lorsqu'on ajoute le produit à partir de la liste des produits installables il ne se passe rien en apparence. En fait l'instance est bien créée mais comme la méthode _setObject() ne renvoie rien, on à l'impression qu'il ne se passe rien. Si vous listez le contenu du dossier dans lequel vous avez créer l'instance vous devriez voir un nouvel objet nommé hello_id.
  • Il n'y a pas d'onglet "Vue" dans les onglets accessibles pour l'objet hello_id, il faut y accéder manuellement en ajoutant index_html derrirère le nom de l'objet.
  • On ne peut créer qu'une seule instance. Si on essaie d'ajouter un nouvel objet Hello World, zope nous prévient qu'un objet de même identifiant existe déjà.

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.