logo

Extra Block Types (EBT) - Nuova esperienza con Layout Builder❗

Extra Block Types (EBT) - tipi di blocchi stilizzati e personalizzabili: Slideshows, Tabs, Cards, Accordion e molti altri. Impostazioni integrate per sfondo, DOM Box, plugin javascript. Vivi oggi il futuro della costruzione dei layout.

Demo moduli EBT Scarica moduli EBT

❗Extra Paragraph Types (EPT) - Nuova esperienza con Paragraphs

Extra Paragraph Types (EPT) - insieme di moduli basati su paragrafi in modo analogo.

Demo moduli EPT Scarica moduli EPT

Scorri

Struttura di base di un modulo Drupal

04/10/2025, by Ivan

Menu

Parte II della guida pratica alla creazione di moduli base in Drupal 8
Dallo .info ai test, solo le basi

Struttura di base

loremipsum.info.yml

name: Lorem ipsum
type: module
description: 'Generatore di Lorem ipsum per Drupal'
package: Development
core: 8.x
configure: loremipsum.form

I file info sono ora formattati come YML, e c’è differenza tra moduli e temi, che deve essere chiara tramite la dichiarazione del tipo. La dichiarazione config punta a una rotta (ne parleremo più avanti), ma a parte questo non c’è nient’altro. In effetti, questo è l’unico file di cui avrai bisogno per il tuo modulo. Dopo averlo salvato (nella cartella root/modules) puoi attivare il tuo modulo in /admin/modules senza rompere il tuo sito. Ma, come vedrai dopo, non è sufficiente.

loremipsum.module

<?php

use Drupal\Core\Routing\RouteMatchInterface;

/**
 * Implements hook_help().
 */
function loremipsum_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'help.page.loremipsum':
      return t('
        <h2>Generatore di Lorem ipsum per Drupal.</h2>
        <h3>Istruzioni</h3>
        <p>Lorem ipsum dolor sit amet... <strong>Scherzo!</strong></p>
        <p>Estrai nella cartella <em>modules</em> (attualmente nella root della tua installazione Drupal 8) e abilita in <strong>/admin/modules</strong>.</p>
        <p>Poi, visita <strong>/admin/config/development/loremipsum</strong> ed inserisci il tuo set di frasi per costruire testo generato casualmente (oppure utilizza il Lorem ipsum predefinito).</p>
        <p>Infine, visita <strong>www.example.com/loremipsum/generate/P/S</strong> dove:</p>
        <ul>
          <li><em>P</em> è il numero di <em>paragrafi</em></li>
          <li><em>S</em> è il numero massimo di <em>frasi</em></li>
        </ul>
        <p>C’è anche un blocco generatore in cui puoi scegliere quanti paragrafi e frasi generare e farà il resto.</p>
        <p>Se necessario, esiste anche un permesso specifico <em>generate lorem ipsum</em>.</p>
        <h3>Attenzione</h3>
        <p>La maggior parte dei bug è stata risolta, le falle coperte, nuove funzioni aggiunte. Ma questo modulo è ancora in lavorazione. Per favore segnala bug e suggerimenti, ok?</p>
      ');
  }
}

È buona pratica inserire qui almeno una chiamata a hook_help(). Nota anche l’istruzione use che punta alla classe RouteMatchInterface. Questo principalmente perché hook_menu() non esiste più.

... E man mano che andrai avanti, noterai che il file .module verrà usato anche per memorizzare informazioni di theming. Quindi tienilo.

loremipsum.install

<?php

/**
 * @file
 * Funzioni di installazione per il modulo Lorem ipsum.
 */

use Drupal\user\RoleInterface;

/**
 * Implements hook_install().
 */
function loremipsum_install() {
  user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array(
    'generate lorem ipsum' => TRUE,
  ));
}

Qui usiamo un’altra classe: RoleInterface. In sostanza, questo file dice a Drupal: «non appena questo modulo è abilitato, trova il permesso per generare lorem ipsum e attivalo».

Ma dove viene definito questo permesso?

loremipsum.permissions.yml

generate lorem ipsum:
  title: 'Generate Lorem ipsum'

Come puoi vedere, è molto più semplice della chiamata a hook_permission(). La sintassi completa si trova nella documentazione di PermissionHandler.

loremipsum.routing.yml

loremipsum.generate:
  path: '/loremipsum/generate/{paragraphs}/{phrases}'
  defaults:
    _controller: '\Drupal\loremipsum\Controller\LoremIpsumController::generate'
  requirements:
    _permission: 'generate lorem ipsum'

loremipsum.form:
  path: '/admin/config/development/loremipsum'
  defaults:
    _form: '\Drupal\loremipsum\Form\LoremIpsumForm'
    _title: 'Impostazioni Lorem ipsum'
  requirements:
    _permission: 'administer site configuration'

Il file di routing sostituisce la chiamata a hook_menu(). Ogni voce (senza rientro) punta a una rotta, con le linee successive indentate che dettagliano impostazioni specifiche.

La rotta loremipsum.generate punta a una pagina che accetta due argomenti tra {}; essa corrisponde a un controller (ne parleremo più avanti), al contrario di loremipsum.form, che punta a un form (di configurazione) con un titolo.

Entrambe le rotte richiedono permessi, ma puoi sostituirli con _access: 'TRUE' per accesso illimitato.

loremipsum.services.yml

Permette di dichiarare un servizio personalizzato.

loremipsum.links.menu.yml

loremipsum.form:
  title: 'Impostazioni Lorem Ipsum'
  description: 'Configura le impostazioni per il modulo Lorem Ipsum.'
  route_name: loremipsum.form
  parent: 'system.admin_config_development'

Se il file di routing crea la pagina in /admin/config/development/loremipsum, queste definizioni sono necessarie per aggiungere le pagine nel menu di Amministrazione.

loremipsum.links.task.yml

Definizioni per creare ulteriori attività locali (schede) per una determinata rotta.

loremipsum.links.action.yml

Definizioni per creare ulteriori azioni locali (bottoni) per una determinata rotta.

loremipsum.links.contextual.yml

Definizioni per creare ulteriori azioni contestuali per un determinato elemento dell’interfaccia utente.

loremipsum.libraries.yml

Usato per dichiarare dipendenze per librerie CSS e Javascript. Maggiori dettagli nella sezione corrispondente.

README.md

Estrai nella cartella *modules* (attualmente nella root della tua installazione di Drupal 8) e abilita in `/admin/modules`.

Poi vai su `/admin/config/development/loremipsum` e inserisci il tuo set di
frasi per costruire testo generato casualmente (o usa il Lorem ipsum predefinito).

Infine, visita `www.example.com/loremipsum/generate/P/S`, dove:
- *P* è il numero di *paragrafi*
- *S* è il numero massimo di *frasi*

C’è anche un blocco generatore, in cui puoi scegliere quanti paragrafi e
frasi generare, e farà tutto il resto.

Se necessario, esiste anche un permesso specifico *generate lorem ipsum*.

Attenzione
---------

La maggior parte degli errori è stata corretta, le falle chiuse, nuove funzionalità aggiunte. Ma questo modulo è ancora in fase di sviluppo. Per favore segnala bug e suggerimenti, va bene?

Sì, i file README ora sono scritti in formato Markdown. Abbastanza figo, se me lo chiedi.

Ora addentriamoci nelle cartelle per un’analisi più dettagliata dei singoli elementi.

LICENSE.TXT

Non includere il file LICENSE.txt (o simile). Lo script di packaging lo aggiungerà automaticamente.

/config/install/loremipsum.settings.yml

loremipsum:
page_title: 'Lorem ipsum'
source_text: "Lorem ipsum dolor sit amet, consitteur adipisci elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua". in rappresentazione in curl velit esse cillum dolore eu fugiat nulla pariatur. \nExcepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est labour."

Questo file memorizza le impostazioni predefinite che vengono assegnate ai campi corretti tramite il file seguente:

loremipsum:
  page_title: 'Lorem ipsum'
  source_text: "Lorem ipsum dolor sit amet, consectetur adipisci elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \nUt enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \nDuis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \nExcepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. "

Questo file memorizza le impostazioni predefinite che vengono assegnate ai campi corretti tramite il file seguente:

/config/schema/loremipsum.schema.yml

loremipsum.settings:
  type: config_object
  label: 'Impostazioni Lorem Ipsum'
  mapping:
    loremipsum:
      type: mapping
      mapping:
        page_title:
          type: text
          label: 'Titolo della pagina del generatore Lorem ipsum:'
        source_text:
          type: text
          label: 'Testo sorgente per la generazione di lorem ipsum:'
block.settings.loremipsum_block:
  type: block_settings
  label: 'Blocco Lorem ipsum'
  mapping:
    loremipsum_block_settings:
      type: text
      label: 'Impostazioni del blocco Lorem ipsum'

Il file di schema viene usato anche se non definisci una tabella personalizzata per il tuo modulo – qui puoi vedere i valori predefiniti assegnati ai campi del form di configurazione.

Durante lo sviluppo di questo codice ho scoperto che il popolamento dei campi “out of the box” era una delle attività più difficili. Ma fortunatamente c’è un modulo per questo: Config Inspector per Drupal 8, che ti aiuterà a fare debug delle impostazioni predefinite.

Inoltre, il file di schema YML è molto utile in molti modi.

/src/Controller/LoremIpsumController.php

<?php

namespace Drupal\loremipsum\Controller;

// Cambiamenti seguendo https://www.drupal.org/node/2457593
// Vedi https://www.drupal.org/node/2549395 per informazioni sui metodi deprecati
// use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Html;
// usa Html invece di SafeMarkup

/**
 * Routine di controller per le pagine Lorem ipsum.
 */
class LoremIpsumController {

  /**
   * Costruisce testo Lorem ipsum con argomenti.
   * Questo callback è mappato al percorso
   * 'loremipsum/generate/{paragraphs}/{phrases}'.
   * 
   * @param string $paragraphs
   *   Il numero di paragrafi che devono essere generati.
   * @param string $phrases
   *   Il numero massimo di frasi che possono essere generate in un paragrafo.
   */
  public function generate($paragraphs, $phrases) {

Siamo arrivati al cuore di questo modulo, una classe con un unico metodo che genera testo segnaposto. Come puoi vedere, il metodo generato all’interno della classe LoremIpsumController corrisponde a una voce nel file di routing YML:

04_3

Nella cornice bianca è mostrato il codice del file: loremipsum.routing.yml e sullo sfondo il file con cui stiamo lavorando.

Ora proseguiamo: il frammento di codice seguente ottiene le impostazioni del modulo e le memorizza per un uso successivo:

    // Impostazioni predefinite.
    $config = \Drupal::config('loremipsum.settings');
    // Titolo pagina e testo sorgente.
    $page_title = $config->get('loremipsum.page_title');
    $source_text = $config->get('loremipsum.source_text');

I parametri sopra (loremipsum.page_title e loremipsum.source_text) sono presi dal file di configurazione YAML:

05_3

Poi dividiamo le frasi da $source_text in un array:

$repertory = explode(PHP_EOL, $source_text);

E usiamo questo array per costruire paragrafi di testo:

    $element['#source_text'] = array();

    // Genera X paragrafi con fino a Y frasi ciascuno.
    for ($i = 1; $i <= $paragraphs; $i++) {
      $this_paragraph = '';
      // Quando diciamo "fino a Y frasi", non possiamo intendere "da 1 a Y".
      // Quindi andiamo da metà fino a Y.
      $random_phrases = mt_rand(round($phrases / 2), $phrases);
      // Inoltre non ripetere l’ultima frase.
      $last_number = 0;
      $next_number = 0;
      for ($j = 1; $j <= $random_phrases; $j++) {
        do {
          $next_number = floor(mt_rand(0, count($repertory) - 1));
        } while ($next_number === $last_number && count($repertory) > 1);
        $this_paragraph .= $repertory[$next_number] . ' ';
        $last_number = $next_number;
      }
      //$element['#source_text'][] = SafeMarkup::checkPlain($this_paragraph);
        $element['#source_text'][] = Html::escape($this_paragraph);

    }

Nota che ['#source_text'] è un array di rendering passato al template, e che ogni elemento in questo array passa attraverso Html::escape() per sicurezza.

Infine, diamo al nostro array di rendering un titolo, assegniamo la funzione di tema e lo restituiamo:

    //$element['#title'] = SafeMarkup::checkPlain($page_title);
    $element['#title'] = Html::escape($page_title);
     
    // Funzione di tema.
    $element['#theme'] = 'loremipsum';
    
    return $element;
  }

}

Ma prima di passare questa variabile al nostro template, dobbiamo occuparcene.

Prossimo passo:

Theming del modulo.

A seguire:

Aggiungere un form di configurazione.

Definire un blocco per questo modulo.

Scrivere test per questo modulo.