traversal personnalisée et modèles de page
Question
Utilisation de Marius Gedminas de excellent post blog , j'ai créé un transbordeur personnalisé pour un dossier dans mon site.
Cela me permet de montrer: http://foo.com/folder/random_id
Au lieu de: http://foo.com/folder/object.html?id=random_id
Le côté configuration fonctionne très bien, je peux attraper les random_ids et la recherche à travers mes messages pour le bon, prêt à afficher.
Mon problème est que je ne suis pas sûr comment afficher ensuite les données via mes modèles habituels page - au point TODO dans son code d'origine;)
if name == 'mycalendar':
mycalendar = ... # TODO: do something to get the appropriate object
return mycalendar
En général, j'utiliser quelque chose de similaire à:
class Test(BrowserPage):
template = ViewPageTemplateFile('atest.pt')
def __call__(self):
return self.template()
Mais je ne peux pas travailler comment faire cela correctement dans le contexte du traversal personnalisé.
UPDATE : Pour être clair, je veux éviter ajouter quoi que ce soit d'autre à l'URL ( Non : http://foo.com/folder/random_id/read ).
ne pas besoin de la vue d'être disponible via une autre adresse ( Non : http://foo.com/folder/read )
Le ZCML pour la vue que je voudrais utiliser est:
<browser:page
for="foo.interfaces.IFooFolderContainer"
name="read"
template="read.pt"
permission="zope.ManageContent"
/>
Je devine (sur plus de conseils), quelque chose le long des lignes de:
return getMultiAdapter((mycalendar, self.request), IPageTemplate, name=u'read')
Ou même une vue par défaut pour le type d'objet (un dict dans ce cas) qui est retourné:
<browser:page
for="dict"
name="read"
template="read.pt"
permission="zope.ManageContent"
/>
La solution
Il serait plus facile de répondre à votre question si vous montriez ce que fait votre transbordeur sur mesure.
Essentiellement, vous voulez quelque chose comme ceci:
def publishTraverse(self, request, name):
if name in self.context:
return MyMessageView(self.context[name], request)
# fall back to views such as index.html
view = queryMultiAdapter((self.context, request), name=name)
if view is not None:
return view
# give up and return a 404 Not Found error page
raise NotFound(self.context, name, request)
où MyMessageView peut être quelque chose d'aussi simple que
class MyMessageView(BrowserPage):
__call__ = ViewPageTemplateFile('read.pt')
Disclaimer: Je ne sais pas si la vue que vous instancier sera protégé par une enveloppe de sécurité; assurez-vous que vos tests fonctionnels que les utilisateurs anonymes ne peuvent pas afficher les messages si c'est ce que vous voulez.
Autres conseils
Si vous vous retrouvez à un objet approprié avec votre transbordeur personnalisé, vous pouvez simplement virer de bord sur le nom du modèle et l'utilisateur « contexte » dans ce modèle. Alors http://foo.com/folder/random_id/my_template
et dans le modèle font les choses de <h1 tal:content="context/title" />
normal.
IIUC, ce que vous voulez est de rendre la vue « lire » quand quelqu'un demande / dossier / random_id. Si tel est le cas, tout ce que vous devez faire est de rendre votre traversal retourner un objet (IFolderContent, peut-être) représentant un random_id et préciser la page « vue » comme defaultView pour IFolderContent.
Le defaultView est nécessaire parce qu'il n'y a pas de vue spécifié pour l'objet random_id dans votre URL.