Utilisation de INameChooser
Pour un blog, on veut pouvoir créer des post sans avoir à définir leurs ids.
On en fait de même pour les folders. Voici le principe:
- Si nous sommes dans le dossier racine, on créé un dossier pour l'année.
- Si on est dans une année, on créé un dossier pour le mois
- Si on est dans un mois, on créé une post qui a son id basé sur le jour et l'heure courante.
Dans Zope cela donnes:
>>> from zope.app.container.interfaces import INameChooser
>>> from zope.app.container.contained import NameChooser
>>> import datetime
>>> class IWeblog(zope.interface.Interface):pass
>>> class WeblogNameChooser(NameChooser):
... zope.interface.implements(INameChooser)
... zope.component.adapts(IWeblog)
... def __init__(self,context):
... self.context = context
... def chooseName(self,name,object):
... container = self.context
... now = datetime.datetime.now()
... year = now.strftime('%Y')
... month = now.strftime('%m')
... if 'log' in str(container.__name__):
... return unicode(year)
... elif str(container.__name__) == year:
... return unicode(month)
... elif str(container.__name__) == month:
... return unicode(now.strftime('%Y%m%d%H'))
... return NameChooser.chooseName(self,name,object)
L'interface INameChooser définit un adapter qui permet de modifier la façon dont zope génère ses ids. Ici, on utilise la date et l'id du parent pour générer l'id de nos objets.
On peut tester que l'exemple fonctionne bien:
>>> now = datetime.datetime.now()
>>> year = now.strftime('%Y')
>>> month = now.strftime('%m')
On créé un folder root:
>>> from zope.app.folder import Folder
>>> folder = Folder()
>>> folder.__name__ = 'weblog'
On instancie notre INameChooser et on vérifie qu'il génère bien une année:
>>> chooser = WeblogNameChooser(folder)
>>> chooser.chooseName('',None) == unicode(year)
True
Même exemple. Mais ici, le chooser renvois le mois:
>>> folder.__name__ = unicode(year)
>>> chooser = WeblogNameChooser(folder)
>>> chooser.chooseName('',None) == unicode(month)
True
Bien que l'interface soit définit pour un dossier, elle est utilisée pour définir l'id de l'objet que l'on ajoute dans un dossier et non l'id du dossier lui même. C'est ainsi que l'on peut aussi définir l'id d'un post.
On peut donc aussi basé le choix de l'id sur le type de contenu que l'on ajoutes dans le dossier.
On voit ici la puissance des interfaces de Zope3 car il est possible par ce moyen de redéfinir la façon dont seras généré l'id de n'importe qul objet simplement en implémentant un NameChooser pour l'interface de ces objets.