logo

Extra Block Types (EBT) - Nieuwe Layout Builder ervaring❗

Extra Block Types (EBT) - gestileerde, aanpasbare bloktypes: Slideshows, Tabs, Cards, Accordions en vele andere. Ingebouwde instellingen voor achtergrond, DOM Box, javascript-plugins. Ervaar vandaag al de toekomst van layout building.

Demo EBT-modules Download EBT-modules

❗Extra Paragraph Types (EPT) - Nieuwe Paragraphs ervaring

Extra Paragraph Types (EPT) - analoge op paragrafen gebaseerde set modules.

Demo EPT-modules Download EPT-modules

Scroll

Basisstructuur van een Drupal-module

04/10/2025, by Ivan

Menu

Deel II van de praktische handleiding voor het maken van basis Drupal 8-modules
Van .info tot tests, alleen de basis

Basisstructuur

loremipsum.info.yml

name: Lorem ipsum
type: module
description: 'Lorem ipsum generator for Drupal'
package: Development
core: 8.x
configure: loremipsum.form

Info-bestanden zijn nu geformatteerd als YML, en er is een verschil tussen modules en thema’s dat duidelijk moet zijn via de type-aanduiding. De aanduiding configure verwijst naar een route (meer hierover later), maar verder is er niets bijzonders. In feite is dit het enige bestand dat je nodig hebt voor je module. Nadat je dit hebt opgeslagen (in de map root/modules), kun je je module inschakelen in /admin/modules zonder dat je site kapot gaat. Maar, zoals je verder zult zien, is dit niet genoeg.

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>Lorem ipsum generator for Drupal.</h2>
        <h3>Instructions</h3>
        <p>Lorem ipsum dolor sit amet... <strong>Just kidding!</strong></p>
        <p>Unpack in the <em>modules</em> folder (currently in the root of your Drupal 8 installation) and enable in <strong>/admin/modules</strong>.</p>
        <p>Then, visit <strong>/admin/config/development/loremipsum</strong> and enter your own set of phrases to build random-generated text (or go with the default Lorem ipsum).</p>
        <p>Last, visit <strong>www.example.com/loremipsum/generate/P/S</strong> where:</p>
        <ul>
          <li><em>P</em> is the number of <em>paragraphs</em></li>
          <li><em>S</em> is the maximum number of <em>sentences</em></li>
        </ul>
        <p>There is also a generator block in which you can choose how many paragraphs and
phrases and it\'ll do the rest.</p>
        <p>If you need, there\'s also a specific <em>generate lorem ipsum</em> permission.</p>
        <h3>Attention</h3>
        <p>Most bugs have been ironed out, holes covered, features added. But this module is a work in progress. Please report bugs and suggestions, ok?</p>
      ');
  }
}

Een goede gewoonte is om hier ten minste een aanroep van hook_help() neer te zetten. Let ook op de use-verklaring die naar de klasse RouteMatchInterface verwijst. Dit is voornamelijk omdat hook_menu() niet langer bestaat.

... En naarmate je verder gaat, zul je merken dat het .module-bestand ook gebruikt zal worden om thematische informatie op te slaan. Dus hou dat bestand.

loremipsum.install

<?php

/**
 * @file
 * Installation functions for Lorem ipsum module.
 */

use Drupal\user\RoleInterface;

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

Hier gebruiken we een andere klasse: RoleInterface. In wezen vertelt dit bestand Drupal: “zodra deze module is ingeschakeld, zoek de permissie om lorem ipsum te genereren en zet die aan.”

Maar waar is die permissie gedefinieerd?

loremipsum.permissions.yml

generate lorem ipsum:
  title: 'Generate Lorem ipsum'

Zoals je ziet, is dit veel eenvoudiger dan een aanroep naar hook_permission(). De volledige syntaxis staat in de documentatie van 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: 'Lorem ipsum settings'
  requirements:
    _permission: 'administer site configuration'

Het routingbestand vervangt de aanroep naar hook_menu(). Elke invoer (zonder inspringing) verwijst naar een route, met de regels eronder (ingesprongen) die de specifieke instellingen detailleren.

De route loremipsum.generate verwijst naar een pagina die twee argumenten tussen {} accepteert; deze komt overeen met een controller (meer hierover later), in tegenstelling tot loremipsum.form, die naar een (instellingen) formulier met titel verwijst.

Voor beide routes zijn permissies vereist, maar je kunt ze vervangen door _access: 'TRUE' voor onbeperkte toegang.

loremipsum.services.yml

Hiermee kun je een eigen service declareren.

loremipsum.links.menu.yml

loremipsum.form:
  title: 'Lorem Ipsum settings'
  description: 'Configure settings for the Lorem Ipsum module.'
  route_name: loremipsum.form
  parent: 'system.admin_config_development'

Terwijl het routingbestand de pagina aanmaakt in /admin/config/development/loremipsum, zijn deze definities nodig om pagina’s aan het menu Beheer toe te voegen.

loremipsum.links.task.yml

Definities om extra lokale taken (tabs) aan te maken voor een specifieke route.

loremipsum.links.action.yml

Definities om extra lokale acties (knoppen) aan te maken voor een specifieke route.

loremipsum.links.contextual.yml

Definities om extra contextuele acties aan te maken voor een specifiek UI-element.

loremipsum.libraries.yml

Wordt gebruikt om afhankelijkheden voor CSS- en Javascript-bibliotheken vast te leggen. Meer details in de betreffende sectie.

README.md

Plaats in de map *modules* (momenteel in de root van je Drupal 8-installatie) en schakel in via /admin/modules.

Ga daarna naar /admin/config/development/loremipsum en voer je eigen set
zinnen in om willekeurig gegenereerde tekst te maken (of gebruik de standaard Lorem ipsum).

Bezoek tenslotte www.example.com/loremipsum/generate/P/S, waar:
- *P* = aantal *paragrafen*
- *S* = maximaal aantal *zinnen*

Er is ook een generatorblok waarin je kunt kiezen hoeveel paragrafen en
zinnen, en het doet de rest.

Indien nodig is er ook een specifieke permissie *generate lorem ipsum*.

Let op
---------

De meeste bugs zijn opgelost, gaten gedicht, functies toegevoegd. Maar deze module is nog in ontwikkeling. Meld bugs en suggesties, oké?

Ja, README-bestanden worden nu geschreven in Markdown. Best gaaf, als je het mij vraagt.

Laten we nu dieper ingaan op de mappen om specifieke details nader te bekijken.

LICENSE.TXT

Neem het bestand LICENSE.txt (of iets dergelijks) niet op. Het verpakkingsscript voegt dit zelf toe.

/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 view in curl vel esse cillum dolore eu fugiat nulla pariatur. \ nExcepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est labour. "

In dit bestand worden de standaardinstellingen opgeslagen, die aan de juiste velden worden toegewezen via het volgende bestand:

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. "

In dit bestand worden de standaardinstellingen opgeslagen, die aan de juiste velden worden toegewezen via het volgende bestand:

/config/schema/loremipsum.schema.yml

loremipsum.settings:
  type: config_object
  label: 'Lorem Ipsum settings'
  mapping:
    loremipsum:
      type: mapping
      mapping:
        page_title:
          type: text
          label: 'Lorem ipsum generator page title:'
        source_text:
          type: text
          label: 'Source text for lorem ipsum generation:'
block.settings.loremipsum_block:
  type: block_settings
  label: 'Lorem ipsum block'
  mapping:
    loremipsum_block_settings:
      type: text
      label: 'Lorem ipsum block settings'

Het schema-bestand wordt gebruikt, zelfs als je geen aangepaste tabel voor je module definieert – hier kun je de standaardwaarden zien die aan de configuratieformuliervelden worden toegewezen.

Toen ik deze code ontwikkelde, ontdekte ik dat het vooraf invullen van velden “out of the box” een van de moeilijkste taken was. Maar gelukkig is er een module voor: Config Inspector voor Drupal 8, die je helpt bij het debuggen van de standaardinstellingen.

Bovendien is het YML-schema-bestand erg handig op veel manieren.

/src/Controller/LoremIpsumController.php

<?php

namespace Drupal\loremipsum\Controller;

// Change following https://www.drupal.org/node/2457593
// See https://www.drupal.org/node/2549395 for deprecate methods information
// use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Html;
// use Html instead SAfeMarkup

/**
 * Controller routines for Lorem ipsum pages.
 */
class LoremIpsumController {

  /**
   * Constructs Lorem ipsum text with arguments.
   * This callback is mapped to the path
   * 'loremipsum/generate/{paragraphs}/{phrases}'.
   * 
   * @param string $paragraphs
   *   The amount of paragraphs that need to be generated.
   * @param string $phrases
   *   The maximum amount of phrases that can be generated inside a paragraph.
   */
  public function generate($paragraphs, $phrases) {

We zijn nu bij de kern van deze module, de klasse met een enkele methode die de placeholdertekst genereert. Zoals je ziet, verwijst de methode die binnen de klasse LoremIpsumController wordt gegenereerd naar de vermelding in het YML-routingbestand:

04_3

In het witte kader staat de code van het bestand: loremipsum.routing.yml en de achtergrond is het bestand waar we mee werken.

Laten we nu doorgaan, het volgende codefragment haalt de instellingen van de module op en slaat ze op voor verder gebruik:

    // Default settings.
    $config = \Drupal::config('loremipsum.settings');
    // Page title and source text.
    $page_title = $config->get('loremipsum.page_title');
    $source_text = $config->get('loremipsum.source_text');

De hierboven opgegeven parameters (loremipsum.page_title en loremipsum.source_text) worden gehaald uit het YAML-configuratiebestand:

05_3

Daarna splitsen we de zinnen uit $source_text in een array:

$repertory = explode(PHP_EOL, $source_text);

En we gebruiken die array om paragrafen tekst te genereren:

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

    // Generate X paragraphs with up to Y phrases each.
    for ($i = 1; $i <= $paragraphs; $i++) {
      $this_paragraph = '';
      // When we say "up to Y phrases each", we can't mean "from 1 to Y".
      // So we go from halfway up.
      $random_phrases = mt_rand(round($phrases / 2), $phrases);
      // Also don't repeat the last phrase.
      $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);

    }

Merk op dat ['#source_text'] een render-array is die aan de template wordt doorgegeven, en dat elk element in die array door Html::escape() gaat voor veiligheid.

Tot slot geven we onze render-array een titel, wijzen we een themfunctie toe en geven we deze terug:

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

}

Maar voordat we deze variabele aan onze template doorgeven, moeten we daar nog voor zorgen.

Volgende stap:

Theming van de module.

Daarna:

Een instellingenformulier toevoegen.

Een blok definiëren voor deze module.

Tests schrijven voor deze module.