Module bouwen

Image
Multiline entry in default settings YAML
Multiline entry in default settings YAML

Veel met configuratie bestanden OOP maken mymodule.module bijna overbodig

Module skelet opzetten met Drupal console:

$ drupal generate:module --module='GG Begroting' --machine-name=gg_begroting
  --module-path=/modules/custom/ --description='Begroot je reis' 
  --core=8.x --package=GG --composer --no-interaction

Configuratie formulier toevoegen

drupal generate:form:config

Blok toevoegen

drupal generate:plugin:block

Config

multiline in textarea

In mijn configuratiepagina wil ik een textarea opnemen waarin per regel een optie kan worden opgegeven voor een select list.

de default waarden voor het configuratieformulier staan in modules/custom/MYMODULE/config/install/MYMODULE.settings.yml

De multiline entry voor de textarea moet dus in YAML formaat worden vastgelegd. Hiervoor bestaat binnen YAML het zogenaamde block scalar type (|)

routes:
  section_1:
    foot: |-
      1-1335|Vessem - Parijs - St-Jean of Irun (1335km)
      2-1910|Vessem - Vézelay - St-Jean (1910km)
      3-1990|Vessem - Le Puy - St-Jean (1990km)

Het min-teken achter de block scalar geeft aan dat er geen nieuwe regel aan het eind moet worden toegevoegd.

Op yaml-multiline.info wordt kun je uitproberen welk effect de verschillende instellingen van block en flow scalar types hebben.

Namen van variabelen:

Hoewel het is toegestaan om dashes te gebruiken in de namen van variabele (keys) in de configuratiebestanden kan dit problemen geven wanneer de variable uiteindelijk wordt gebruikt in Twig. Twig ziet de dash als een min-teken en zal de variable als een 0 renderen. Gebruik daarom bij voorkeur underscores.

Vertalingen toevoegen

JS en CSS toevoegen

JS en CSS als libraries in modules

In het bestand mymodule.libraries.yml kunnen verschillende libraries worden beschreven waarna ze op verschillende manieren later kunnen worden aangeroepen. Een library is bijvoorbeeld een set van CSS en JS bestanden. In deze sets kun je ook afhankelijkheden opnemen (zoals een javascript bestand dat jQuery nodig heeft).

mymodule:
  version: 1.x
  css:
    theme:
      css/mymodule.css: {}
  js:
    js/mymodule.js: { preprocess: false }
  dependencies:
    - core/jquery

mymodule is de identifier van de library waarmee we die later kunnen aanroepen.

theme bepaald op welk moment van de cascading het mymodule.css moet worden ingevoegd (hierarchie)

Argumenten die je aan het css kunt doorgeven zijn bijvoorbeeld print of screen, het javascript mymodule.js wordt in dit geval niet preprocessed maar dat zal later weggehaald worden.

We richten ons hier op libraries in modules maar in feite is er geen verschil met libraries in themes. Hoe Drupal omgaat met themes en modules die dezelfde naam dragen moet ik nog uitzoeken maar liever vermijd ik het.

een library toevoegen aan een module

een library toevoegen aan een blok

  /**
   * {@inheritdoc}
   */
  public function build() {
    $settings = \Drupal::config('begroting.settings');
    $button = $settings->get('button');
    $headers = $settings->get('headers');
    $results = $settings->get('results');
    $config = $this->getConfiguration();
    $types = ['foot','bike'];
    foreach($types as $type) {
      $forms[$type] = \Drupal::formBuilder()->getForm('Drupal\begroting\Form\BegrotingForm', $type);
    }
    $renderArray['#theme'] = 'begroting_all_in_one_block';
    $renderArray['#types'] = $types;
    $renderArray['#labels'] = $button;
    $renderArray['#headers'] = $headers;
    $renderArray['#results'] = $results;
    $renderArray['#forms'] = $forms;
    $renderArray['#attached']['library'][] = 'begroting/begroting';
    return $renderArray;
}

een library toevoegen aan een formulier

$form['#attached']['library'][] = 'mymodule/mylibrary';

een library toevoegen aan een thema

function mytheme_preprocess_page(&$variables) {
  $variables['#attached']['library'][] = 'mymodule/mylibrary';
}

een library toevoegen met twig

{{ attach_library('mymodule/mylibrary') }}

Formulieren

Argumenten meegeven aan een formulier

In de aanroep (bijvoorbeeld in een blok waarbij de configuratie door de MymoduleBlock klasse wordt beschreven)

public function build() {
  $config = $this->getConfiguration();
  $type = isset($config['config_name']) ? $config['config_name'] : 'default';
  $builtForm = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\MymoduleForm', $type);
  $renderArray['form'] = $builtForm;
  $renderArray['#attached']['library'][] = 'mymodule/mylibrary';
  return $renderArray;
}

In het formulier wordt het argument achteraan toegevoegd:

public function buildForm(array $form, FormStateInterface $form_state, $type=null) {

Het hoeft geen betoog dat je op deze manier ook meerdere argumenten als array kunt aanbieden.

Twig

Array elementen renderen in Twig

Meestal gebruiken we daar een . voor zoals in et onderstaande voorbeeld meermalen wordt gedaan:

{% for type in types %}
<div id="wrapper-begroting-{{ type }}" class="wrapper-begroting rounded wrapper-begroting-{{ type }}">

  <table class="begroting">
    <tr><td class="titel" colspan="4"><h4 class="begroot-titel begroot-{{ type}}">{{ headers.head }}</h4></td></tr>
    <tr class="first"><th class="col1"></th><th class="col2"> {{ results.distance }}</th><th class="col3">{{ results.days }}</th><th class="col4">{{  results.costs }}</th></tr>
    <tr class="normal"><td class="col1">{{ headers.towards_spain }}</td><td class="{{ type }}-distance-1">0</td><td class="{{ type }}-days-1">0</     td><td class="{{ type }}-cost-1">0</td></tr>
    <tr class="normal"><td class="col1">{{ headers.through_spain }}</td><td class="{{ type }}-distance-2">0</td><td class="{{ type }}-days-2">0</     td><td class="{{ type }}-cost-2">0</td></tr>
    <tr class="last"><td class="col1">{{ results.total }}</td><td class="{{ type }}-distance-3">0</td><td class="{{ type }}-days-3">0</td><td         class="{{ type }}-cost-3">0</td></tr>
    <tr><td class="description small" colspan="4">{{ results.remark }}</td></tr>
  </table>
    {{ forms[type] }}
</div>
{% endfor %}

Een uitzondering zie je hierboven voor het renderen van het formulier (form) De key van het array is hier zelf een variable en in dat geval schrijven we het array met blokhaken.

Javascript in een blok

Wanneer javascript moet handelen op elementen in een blok zijn die elementen niet aanwezig tijdens het laden van het javascript en moet het javascript worden opgeborgen in Drupal.behaviors:

(function ($) {
  Drupal.behaviors.mymodule = {
    attach: function (context) {

    /*
     * Javascriptcode hier plaatsen
    /*

    }
  };
})(jQuery);

Action handler op een HTML5 number element

Op het traditionele tekstveld werkte een keyup event prima om een verandering in een tekstveld te identificeren. HetHTML5 number veld is een afgeleide va het tekstveld waarbij pijltjes zijn toegevoegd om het nummer te verhogen en te verlagen. Wanneer het veld hiermee wordt bedient werkt het keyup event uiteraard niet. Om dit te verhelpen moet ook het mouseup event worden toegevoegd. Dit doe je als volgt:

$('#identifier').find('input.classname').bind('keyup mouseup', function () {myfunction();});  

Reactie toevoegen