Customizzazione degli skin layers
medio
Tradizionalmente, la customizzazione in Zope si effettuava tramite acquisizione. Per esempio, uno sviluppatore poteva posizionare una page template in una cartella e acquisirla per generare un oggetto in una sottocartella /foo/bar. Se lo sviluppatore desiderava un rendering differente per l'oggetto ma solo in /foo/bar/baz, poteva creare un template con lo stesso nome (id) in quella cartella, che avrebbe avuto precedenza.
Dato che l'idea di Plone (e del CMF) è proprio quella di dare la libertà agli utenti di creare le loro proprie gerarchie di contenuti, includere templates e codice all'interno della struttura del sito diventerebbe una fonte di confusione e di disordine. E' per questo motivo che gli sviluppatori hanno inventato lo strumento portal_skins. Se visualizzi questo strumento nella ZMI troverai una o più skins nel tab Properties, in particolare Plone Default. Una skin, (che tendenzialmente chiameremo tema, per evitare confusione) è semplicemente una lista ordinata di skin layers. Gli skin layers elencate nel tab Properties corrispondono a cartelle contenute in portal_skins. Quando Zope cerca una risorsa, (logo.jpg, per esempio) sfoglierà la cartella corrente (current folder), e successivamente la parent folders, fino alla root del sito. Se la risorsa non viene trovata, il CMF la cercherà negli skin layers del tema corrente, partendo dalla cima dell'elenco e scendendo fino a quando non trova ciò che cerca.
Notiamo subito il fatto che custom è il primo termine della lista. E' così che funziona la customizzazione attraverso il web. Copia un elemento in questa cartella, e la nuova copia avrà la precedenza su tutti gli altri. Notiamo anche che tutte le altre cartelle sono in sola lettura, perché non sono cartelle dello ZODB: sono Filesystem Directory Views, cartelle che riflettono i files contenuti in una particolare cartella nel filesystem.
Perciò, per creare un prodotto riscrivendo alcune risorse in uno skin layer che lavora con Plone bisogna:
- Registrare una nuova filesystem directory view
- Inserirla nella lista degli skin layers per la skin corrente, che normalmente si trova appena sotto la cartella custom
- Copiare la risorsa pertinente nella nuova directory dello skin layer, mantenendo lo stesso nome
- Personalizzare la copia appena creata
Nota Bene: Alcune risorse avranno un file .metadata associato. In questo caso devi copiare anche il file .metadata per customizzare la risorsa.
Tradizionalmente, tutte le risorse di Plone - immagini, fogli di stile, file Javascript, page templates e script Python come form handlers - erano contenute negli skin layers. Tuttavia, come puoi immaginare, tutto ciò diventava un po' "ingombrante" man mano che Plone cresceva, dato che il meccanismo degli skin layers presuppone che ogni risorsa abbia un nome unico (id). Ancora, la maggior parte delle principali visualizzazioni, immagini e fogli di stile che sono parte di Plone sono contenute in skin layers che hanno nomi prefissati e che iniziano con plone_, come plone_images, o plone_templates. Nel filesystem, li troverai all'interno di CMFPlone/skins. Puoi navigare tra le sottocartelle di queste cartelle per trovare le diverse risorse.
In generale, se una risorsa è menzionata nel codice di Plone (per esempio da un url, un'azione in portal_actions o un alias in portal_types) e non è prefissata con @@ (come in @@view) oppure ++resource++ (come ++resource++stylesheet.css), allora è probabile che si trovi in uno skin layer.
Registrare e installare un nuovo skin layer filesystem-based
Nel prodotto example.costumization, abbiamo una subdirectory skins/, con una singola directory skin layer, example_customization. Per essere in grado di registrarla come una filesystem directory view, dobbiamo comunicare al CMF la directory dei top-level skins. Possiamo farlo nel file __init__.py del pacchetto:
from Products.CMFCore.DirectoryView import registerDirectory
GLOBALS = globals()
registerDirectory('skins', GLOBALS)
def initialize(context):
"""Intializer called when used as a Zope 2 product.""" Perché funzioni, dobbiamo inoltre assicurarci che il pacchetto sia un prodotto Zope 2. Se è nel magico namespace Products.* (ad esempio un tipico prodotto che si trova nella directory Products in un'istanza Zope), tutto ciò accadrà automaticamente. Se stiamo usando un prodotto egg-based in un namespace differente, dobbiamo aggiungerlo nel configure.zcml del pacchetto:
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
xmlns:five="http://namespaces.zope.org/five"
i18n_domain="example.customization">
<five:registerPackage package="." initialize=".initialize" />
...
</configure> Ora dobbiamo creare la directory view e installarla per la skin corrente quando il prodotto viene installato in un sito Plone. Possiamo farlo usando GenericSetup. Prima di tutto, dobbiamo registrare un nuovo profilo di estensione in modo che il prodotto sia installabile. Agiamo in configure.zcml, come segue:
<genericsetup:registerProfile name="default" title="Example customizations" directory="profiles/default" description='Install various customizations from the example.customization package' provides="Products.GenericSetup.interfaces.EXTENSION" />
Poi usiamo l'import handler skins.xml per configurare lo strumento portal_skins:
<?xml version="1.0"?>
<!-- This file holds the setup configuration for the portal_skins tool -->
<object name="portal_skins">
<object name="example_customization"
meta_type="Filesystem Directory View"
directory="example.customization:skins/example_customization"/>
<skin-path name="*">
<layer name="example_customization"
insert-after="custom"/>
</skin-path>
</object> Possiamo registrare quante directory views vogliamo.
Per fare un breve esempio, posizionando un logo vivace in skins/example_customizations/logo.jpg, riscrivendo logo.jpg da CMFPlone/skins/plone_images, quando il prodotto sarà installato, vedremo il nuovo logo al posto di quello di default. Potrebbe essere necessario ricaricare la pagina.
