Menu di Navigazione con z3c.menu e Viewlet
z3c.menu è un pacchetto molto minimale che fornisce alcune classi di aiuto utili a generare menu.
La vera potenza proviene da un pacchetto zope core, zope.viewlet. Questa è l'idea: invece di lavorare con i vecchi menu zope, piuttosto poco flessibili, vogliamo utilizzare dei viewlet per definire più facilmente come e quando mostrare voci di menu. Il nostro menu di navigazione sarà un viewlet manager, e ogni link nel menu sarà un viewlet. Nel caso non abbiate mai lavorato con i viewlet, proverò a spiegarvi di che si tratta.
Impostiamo un Viewlet Manager
Cos'è un viewlet manager? In un certo senso un viewlet manager vuole rappresentare una certa regione di una pagina web dove si vuol contenere un qualsiasi numero di pezzi di contenuto generati dinamicamente.
Un semplice esempio è la regione presente nella maggior parte dei blog in cui viene mostrata un'immagine del blogger, una breve descrizione del blog, la lista dei post recenti, un piccolo calendario e a volte un gruppo di tag. In termini Zope potremmo considerare ciascuno di questi pezzi di contenuto come un viewlet, tutti racolti insieme in un viewlet manager.
Arrivando al punto, creiamo un viewlet manager. Iniziate aprendo src/zcontact/skin.py e aggiungendo il seguente codice:
from zope.viewlet.interfaces import IViewletManager
from zope.viewlet.manager import WeightOrderedViewletManager
class INavigationMenu(IViewletManager):
"""Navigation Menu Viewlet Manager."""
class NavigationMenu(WeightOrderedViewletManager):
zope.interface.implements(INavigationMenu)
Quando generate delle viewlet, vengono registrate ad uno specifico viewlet manager in base ad una interfaccia. Così iniziamo creando la nostra interfaccia chiamata INavigationMenu proprio per il menu di navigazione, che eredita da IViewletManager (linee 4-5). Poi creiamo un'implementazione dell'interfaccia INavigationMenu (linee 7-8). La classe WeightOrderedViewletManager può ordinare i viewlet secondo un dato peso, che potrebbe tornare utile per un menu di navigazione.
Quindi vogliamo registrare la nostra istanza di ViewletManager in zcml, in modo da poter essere renderizzata da un page template. Aprite src/zcontact/skin.zcml e aggiungete la seguente registrazione:
<browser:viewletManager
name="INavigationMenu"
provides="zcontact.skin.INavigationMenu"
class="zcontact.skin.NavigationMenu"
layer="zcontact.layer.IZContactBrowserLayer"
permission="zope.Public"
/>
Dovrete aggiungere xmlns:browser="http://namespaces.zope.org/browser" al tag di configure per ottenere il namespace browser.
Ora disponiamo di un viewlet manager che rappresenta la regione dove finiranno i nostri link di navigazione. Ma dobbiamo ancora renderizzare il viewlet manager nella nostra skin modificando src/zcontact/layout.pt. Potete mettere il seguente frammento di HTML nel template in qualsiasi punto in cui volete far apparire il menu. Io ho scelto di metterlo proprio sotto l'intestazione "ZContact":
<div tal:content="structure provider:INavigationMenu">Navigation Menu</div>
Aggiungiamo i Viewlet
Ora che abbiamo impostato il nostro viewlet manager per il menu di navigation dobbiamo aggiungere dei viewlet per le voci dei menu. Tutto ciò che dobbiamo fare per i viewlet è predisporre alcune registrazioni zcml nello stesso punto in cui abbiamo registrato i pagelet a cui le nostre voci di menu punteranno. Quindi apriamo zcontact/browser/configure.zcml e aggiungiamo le seguenti due configurazioni zcml:
<viewlet
name="Add Contact"
viewURL="@@addContact.html"
for="*"
manager="zcontact.skin.INavigationMenu"
class="z3c.menu.simple.menu.GlobalMenuItem"
permission="zope.Public"
layer="zcontact.layer.IZContactBrowserLayer"
weight="2"
/>
<viewlet
name="Contact List"
viewURL="@@index.html"
for="*"
manager="zcontact.skin.INavigationMenu"
class="z3c.menu.simple.menu.GlobalMenuItem"
permission="zope.Public"
layer="zcontact.layer.IZContactBrowserLayer"
weight="1"
/>
L'attributo name specifica cosa dirà il link e il viewURL specifica l'url relativo dalla radice del sito alla vista in questione. Fatto ciò impostiamo l'interfaccia INavigationMenu che abbiamo creato nella precedente sezione come manager. Infine vediamo il nostro primo pezzetto di z3c.menu usando la classe GlobalMenuItem per il viewlet. Questa classe calcola quella che dovrebbe essere l'url di base e le attacca in coda l'attributo viewURL.
Fatto ciò potete riavviare il vostro server e dare un'occhiata ad un menù di navigazione lucido di nuovo che funziona perfettamente su ogni pagina della nostra applicazione.
Come sempre, ecco uno screenshot:
