Utilizzare la regione hidden di Display Suite in modo smart

Tempo stimato di lettura
5 m 48 sec

Display suite risulta estremamente comodo per la stilizzazione del nodo in molte occasioni, ma potrebbe non sempre sembrare lo strumento migliore per il theming delle entity di Drupal; ci sono delle situazioni in cui in un certo senso si può rimpiangere la modalità di theming predefinita di Drupal basata sull'uso intensivo dei file di template.

Prendiamo il seguente esempio. Supponiamo di avere due field, uno alternativo all'altro. Una situazione che si potrebbe verificare è quella di avere un nodo che può avere sia un'immagine che un video di apertura. Quello che ci viene chiesto è che se l'editor dovesse aggiungere entrambi, il campo immagine non deve essere stampato, ma andrebbe stampato da Drupal il solo campo video.

Con un file di template questa cosa risulta piuttosto semplice. Supponiamo che i due field si chiamino rispettivamente field_image e field_video. In un file di template classico, andremo a risolvere questo problema con una semplice condizione if che potrebbe essere scritta come:

<?php if ($content['field_image'] || $content['field_video']) : ?> <div class="article_media"> <?php if ($content['field_image'] && !$content['field_video']) : ?> <?php print render($content['field_image']); ?> <?php else : ?> <?php print render($content['field_video']); ?> <?php endif; ?> </div> <?php endif; ?>

Abbiamo stampato i field utilizzando il renderable array (<?php print render($content['field_image']); ?>), questo permette di gestire tramite UI le impostazioni di configurazione del field ed è la modalità consigliata per stampare un field in Drupal 7.

Il codice di cui sopra cosa fa? Semplicemente controlla se abbiamo uno dei due campi valorizzati (potrebbero esserlo anche entrambi), se lo sono, stampa il campo immagine solo se il campo video non è valorizzato, in caso contrario stampa il campo video.

Questo tipo di problematiche, utilizzando Display Suite, potrebbero sembrare di non semplice risoluzione. In realtà utilizzando la hidden region e un custom field di tipo function, possiamo soddisfare la stessa richiesta in modo altrettanto rapido, mantenendo il vantaggio di avere un controllo completo sul markup dei due field direttamente da interfaccia.

Come prima cosa dobbiamo aver attivato il modulo Display Suite Extras:

In secondo luogo verifichiamo di aver attivato la Hidden region:

Fatto questo, creiamo un custom field di tipo function per Display suite, questo codice lo andremmo a scrivere in un nostro modulo oppure nella feature dove avremmo esportato il nostro content type (qui ipotizziamo di avere un content type di tipo article):

``` /** * Define fields. These fields are not overridable through the interface. * If you want those, look at hook_ds_custom_fields_info(). * * @param $entity_type * The name of the entity which we are requesting fields for, e.g. 'node'. * * @return $fields * A collection of fields which keys are the entity type name and values * a collection fields. * * @see ds_get_fields() / // Replace MYMODULE with the name of your module. function MYMODULE_fields_info($entity_type) { $fields = array(); if ($entity_type === 'node') { // The name of our custom field is printed_media $fields['printed_media'] = array( // The field readable name is the title 'title' => t('DS FUNC: printed media'), 'field_type' => DS_FIELD_TYPE_FUNCTION, // The name of the function that will return the field content 'function' => '_my_printed_media', // We are limiting the custom field to the article bundle 'ui_limit' => array('article|'), 'properties' => array( 'formatters' => array( 'text_default' => t('Default') ), ) ); } return array($entity_type => $fields); }

/** * Print the right media file (image or video). * * @param array $entity */ function _my_printed_media($entity) { $markup = ''; // All renderable fields are available in the build array // of our entity, even the image_field and video_filed that // we have moved to the hidden region. $renderable_fields = $entity['build']; // If the field_image is setted but the field_video is not setted, we print the field_image. if (isset($renderable_fields['field_image']) && !isset($renderable_fields['field_video'])) { $markup = render($renderable_fields['field_image']); } // Else if the field_video is setted, we print the video filed. elseif (isset($renderable_fields['field_video'])) { $markup = render($renderable_fields['field_video']); } // If neither field_image nor field_video are setted, // we return an empty string and our custom field printed_media // will not be printed by Drupal. return $markup; } ```

Tutta la logica di stampa del field è nella funzione _printed_media che vedete qui sopra.

Il codice è ben commentato, quindi non dovrebbero essere necessarie altre spiegazioni, voglio solo sottolineare una cosa, ovvero che l'array $entity['build'] contiene tutti i field renderizzabili, ovvero stampabili utilizzando la funzione render() di Drupal.

Ora possiamo configurare la visualizzazione del nodo utilizzando l'interfaccia di field UI in Display Suite:

Come potete vedere nell'immagine qui sopra (in cui ho attivato per la visualizzazione di default del nodo il layout ad una colonna disponibile in Display Suite), tutto il meccanismo si basa nello spostare i due campi Image (field_image) e Video (field_video) nella regione "Hidden" (area cerchiata in verde).

Così facendo, questi campi vengono renderizzati ma non stampati nella pagina di visualizzazione del nodo, ma essendo stati renderizzati sono disponibili come renderable array, e questo è molto comodo, in quanto significa che possiamo configurare le impostazioni del campo ed il suo markup direttamente dall'interfacci di field UI come mostrato qui sopra, ed avere questo markup quando stampiamo il campo utilizzando la funzione render() di Drupal, come abbiamo fatto nella nostra funzione scritta sopra: $markup = render($renderable_fields['field_image']);

Quello che andiamo a stampare nella pagina di visualizzazione del nodo non è altro che il nostro field custom printed_media (area cerchiata in rosso). In base alla funzione _my_printed_media che abbiamo scritto sopra, il campo conterrà il markup prodotto da field_image nel caso questo sia valorizzato (ovvero sia stata caricata un'immagine) oppure il markup prodotto dal campo Video nel caso sia stato inserito un video. La logica inserita in _my_printed_media farà sì che se entrambi i campi sono stati valorizzati, verrà comunque stampato il solo campo video. Se nessuno dei due campi è invece stato valorizzato, il field custom printed_media non stamperà nulla.

Quello che abbiamo appena visto è un breve esempio che mostra come sia possibile risolvere sfruttando la regione Hidden una situazione apparentemente problematica utilizzando Display Suite per la stilizzazione del nodo, e che invece avremmo potuto risolvere in modo piuttosto semplice con un file di template.

Come potete capire, Display Suite non è necessariamente la soluzione migliore in assoluto, è una delle possibilità offerte da Drupal per la personalizzazione del markup delle entity. Resta l'indubbio vantaggio che con Display Suite si può controllare direttamente da interfaccia tutto il markup del field, cosa che non è possibile fare ad esempio utilizzando l'interfaccia di default di Drupal se non utilizzando altri moduli.

Tutto questo per dire che quando si lavora in Drupal probabilmente non esiste il modo migliore per fare una data cosa; vi sono vari modi di risolvere lo stesso problema, ed ogni soluzione può avere i suoi pro ed i suoi contro. L'importante è attenersi a quelle che sono le logiche dello strumento e le best practices assodate per lo sviluppo e la scrittura del codice; si tratta poi di una questione di gusti personali su quale soluzione tecnica alla fine utilizzare, basta che sia fatta a la "Drupal way".

Voi cosa ne pensate? Volete condividere qualcosa in merito? Avete qualche altra soluzione da proporre? A presto con un nuovo articolo.

Gli ultimi post di Andrea Panisson

Restiamo in contatto

Enter your email address below to receive all our latest articles and announcements via email.