Usare le viste standard di Plone ed evitare di pagare il dazio

18 novembre 2009

Spesso nel costruire le nostre viste (template ZPT puri vecchia maniera, o browser view in stile Zope 3) abbiamo bisogno di richiamare informazioni dal contesto, o servizi di Plone come il portal_catalog o il portal_membership.

Un modo di farlo è quello “spontaneo” di richiamarli esattamente dove ci servono usando i meccanismi di base, tipicamente l’acquisizione di Zope 2. Efficace, ma piuttosto inefficiente! Anche perchè frequentemente coincide con il dover usare espressioni python nel template.
Le seguenti sono scorciatoie funzionanti, ma piuttosto da evitare:

<div tal:define="catalog here/portal_catalog">...</div>
<div tal:define="parent_title python:here.aq_inner.aq_parent.Title()>titolo</div>

Un paio di considerazioni

Plone costruisce la sua interfaccia utente in modo “efficiente“: andando a vedere come fa scopriamo che esistono alcune viste di base, calcolate una tantum e debitamente mantenute in cache, che sarebbe molto consigliabile usare anche per le nostre esigenze.

Quando costruiamo le nostre browser view, spesso richiamiamo altre browser view, e questo può essere fatto senza scomodare l’acquisizione e tutti i calcoli che comporta (traversing, sicurezza, etc.).

Le viste di base di Plone

La prima vista utile si chiama proprio “@@plone“.

Richiamarla in un template è molto semplice:

<div tal:define="vista context/@@plone"/>

Per sapere cosa possiamo fare con la vista basta dare uno sguardo alla sua interfaccia, che per Plone 4 trovate in http://dev.plone.org/plone/browser/Plone/trunk/Products/CMFPlone/browser/interfaces.py col nome di IPlone.

Tra le cose interessanti a disposizione segnalo: getCurrentUrl (restitusce l’url currente compresa di querystring), getCurrentObjectUrl (retituisce l’url dell’oggetto corrente, o della sua cartella, nel caso sia la pagina di default), toLocalizedTime (per formattare le date secondo le impostazioni del portale), getParentObject (restituisce l’oggetto padre del contesto corrente), cropText (per ottenere una versione ridotta di un certo testo da mostrare all’utente).

Altre tre viste permettono di accedere in modo efficiente ed efficace a buona parte di quel che ci serve in Plone: plone_portal_state, plone_context_state e plone_tools.

Queste viste sono parte del pacchetto plone.app.layout (http://dev.plone.org/plone/browser/plone.app.layout/trunk/plone/app/layout/globals/configure.zcml).

Come facile intuire, possiamo scoprire cosa trovare in tali viste dalle loro interfacce: http://dev.plone.org/plone/browser/plone.app.layout/trunk/plone/app/layout/globals/interfaces.py

NOTA: In Plone 3 è possibile accedere a tutta una serie di “nomi” disponibili nelle ZPT (l’equivalente dei global defines delle precedenti versioni di Plone: checkPermission, mtool, portal_url tanto per citarni qualcuno). Questo in Plone 4 non ci sarà (cfr. http://plone.org/documentation/manual/upgrade-guide/version/upgrading-plone-3-x-to-4.0/updating-add-on-products-for-plone-4.0/no-more-global-definitions-in-templates), quindi prendiamo da subito l’abitudine di calcolarci quello di cui abbiamo bisogno dalle viste di base!

Richiamare una Browser View da un’altra Browser View

Durante l’implementazione di una nostra vista ammettiamo di aver bisogno di una delle viste sopra menzionate. Un modo rapido di farlo consiste nel richiamare sul contesto il traversing verso la vista, con qualcosa del genere:

self.context.restrictedTraverse('@@plone')

Questa invocazione è perfettamente lecita, ma dal punto di vista prestazionale non è la cosa più efficiente che possiamo fare: di fatto sveglia i meccanismi di traversing e sicurezza di Zope 2, non propriamente dei fulmini di guerra.

Piuttosto, dato il caso, sarebbe opportuno usare direttamente la Component Architecture di Zope 3 per ottenere la vista che ci interessa, ad esempio con un’invocazione come la seguente:


from zope.component import getMultiAdapter
getMultiAdapter((self.context, self.request), name=u'plone')

Quanto costa mantenere i vecchi vizi

Un modo per cercare di evitare brutte pratiche? Paghiamo il dazio per le nostre malefatte!

  • 50 centesimi per ogni espressione python ricalcolata, ma già disponibile
  • 1 euro per ogni espressione python in una ZPT pura (senza browser view intorno) 🙂
  • 2 euro per ogni espressione python in una ZPT con browser view intorno 🙂
  • 2 euro per ogni restrictedTraverse nei moduli python delle browser view non indiscutibilmente necessari
Annunci

3 Risposte to “Usare le viste standard di Plone ed evitare di pagare il dazio”

  1. Bruno Ripa Says:

    Uhm…sacrosanto…e se adottassi la pratica del pagare dazio sarei in miseria 🙂

    Scherzi a parte, senza andare a scomodare l’ovvio side effect delle prestazioni ridotte, il corretto utilizzo di tali strumenti permette di scrivere zpt molto piu’ leggibili.

    Chi si ricorda in plone 2.1 le zpt che sembravano codice python malformattato ? 🙂

  2. vito Says:

    Post utile! 🙂

  3. miziodel Says:

    addendum: per ottenere una browser view da codice con la chiamata a getMultiAdapter è necessario sia il context che la request, ma a volte capita di non averli.

    facendo attenzione a quando farlo, un modo di aggirare questa mancanza e’:

    from zope.app.component.hooks import getSite

    context = getSite() ….
    request = getSite().REQUEST


Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger hanno fatto clic su Mi Piace per questo: