Modules maken (de makkelijke manier)

Moeilijkheidsgraad

trefwoorden

Voorwoord

We gaan bestaande code integreren in een Drupal 8 module. In een paar uurtjes heb je een werkende module.

Op het net zijn er talrijke interessante scripts te vinden waarbij de auteursrechten het mogelijk maken om met deze scripts verder te werken en er zelfs Drupal 8 modules mee te maken.

Het enige wat de makers van deze codes vragen is om vermeld te worden. Dit is iets wat we zeker altijd gaan doen. We maken dus gebruik van bestaande code en gaan dus het warm water geen tweede keer uitvinden.. Afbeeldingsgalerijen, kalenders, teksteffecten... Het bestaat al... maar nog niet altijd voor Drupal 8...

Algemeen

Elke module is anders. Er is echter een algemeen principe...

De originele code is meestal een combinatie van HTML, CSS en Javascript. In de HTML zie je bijvoorbeeld de verwijzing naar een afbeelding op de server. Iemand die zo'n pagina wilt gebruiken moet dus in de code zelf de aanpassingen doen om met andere afbeeldingen te kunnen werken. Logisch maar niet de CMS (Drupal) manier van werken. 

Wij hebben namelijk in Drupal een veldstructuur die de afbeeldingen beheert. Vraag is nu hoe we deze velden kunnen combineren met de originele HTML code. Er is meer... soms worden er ook variabelen gebruikt... bijvoorbeeld hoeveel rijen en kolommen wil je in een afbeeldingsrooster. Welke start- en einddata heb je voor een activiteit om een kalender te maken,... Ook daar hebben we velden voor nodig. Het principe is dus duidelijk.. Maak dat de gebruiker niet in de code moet werken en dat hij/zij met de gekende veldstructuur van Drupal alles kan instellen.

De velden van Drupal kan je met behulp van PHP inlezen. De verkregen waarden zijn dan op hun beurt op de juiste plaats in te lassen, ook weer met PHP, in de HTML pagina van de originele code. Waar in bovenstaande print de afbeeldingen staan, komt dus mijn php code die dynamisch de afbeeldingen genereert. Ook CSS en JS kan met deze techniek herschreven worden.

 

Werkwijze

1) Controleer de originele script op zijn kwaliteit. Multibrowser, multidevice,... Dit kan je doen door hun demo's te nemen en te testen.

2) Download de code en de afhankelijke mappen en bestanden. Zet deze laatste als third party in de map libraries.

3) Kopieer en plak de HTML code in een tekstveld van een nieuw inhoudstype. Gebruik de php tekstfilter. (https://www.drupal.org/project/php). Dit hebben we later nodig.  Pas de verwijzingen naar de bestanden aan. In dit stadium kan je zien of je thema niet stoort met de script. Als het thema stoort kan je nog altijd met de module 'Clever theme switcher', instellen dat je voor dit inhoudstype een ander thema wilt gebruikt.

4) Kijk in de HTML code wat er dynamisch moet vervangen worden. Afbeeldingen, variabelen,... Maak daar de nodige velden voor aan.

5) Voeg een php gedeelte toe aan je pagina dat de waarden van je velden inleest.

6) Vervang de statische HTML inhoud door je php waarden. Doe dit in de HTML, CSS en JS indien nodig.

7) Verberg de php code voor de gebruiker bij het inputformulier in je inhoudstype. Verberg alles behalve de php code voor de weergave.

8) Maak met Features een module. Voorzie ook een gecomprimeerd bestand voor een mogelijke third party.

Uitgewerkt voorbeeld

We maken deze module: Animated Responsive Image Grid (Zie module bespreking)

We bekijken en analyseren de originele code en besluiten om volgende velden aan te maken. Deze velden zullen dan de variabelen brengen die in de HTML code gebruikt worden. Merk op dat ik alleen nieuwe velden gebruik, zelfs geen body. Kwestie om niet met andere instellingen van andere modules in conflict te komen.

Ingevuld ziet dit er zo uit:

Het belangrijkste veld is de script. Ik maak daarvoor een speciale tekstfilter aan. Zo kom ik nooit in het vaarwater van andere modules.


We beginnen met een php gedeelte boven de html te zetten.  Het eerste gedeelte verzamelt de waarden van de velden van de node. Je kunt bvb de breedte van het rooster, het aantal rijen en kolommen bepalen. Daar zijn velden voor gemaakt en hier leest de php de waarden van deze velden.

In een tweede gedeelte gaan we de afbeeldingen, uit een afbeeldingsveld van een gekozen inhoudstype, inlezen.Voor een afbeeldingsveld moet er gewerkt worden met een matrix (array). Een afbeeldingsveld kan ook meervoudig zijn. Daarom moet er een lus doorlopen worden. Tenslotte worden alle gegevens bewaard in variabelen. Deze zullen dan op de gepaste plaats tussen de HTML code worden ingevoegd. Ook onthouden we per afbeelding van welke node ze afkomstig zijn omdat we een link leggen op de afbeelding naar de node.

<?php

$eigennid = \Drupal::routeMatch()->getRawParameter('node');
$eigennode = \Drupal::entityTypeManager()->getStorage('node')->load($eigennid);

$inhoudstype= $eigennode->get('field_anigrid_target_content_typ')->getString();  
$afbeeldingsveld= $eigennode->get('field_anigrid_target_image_field')->getString();  
$breedte= $eigennode->get('field_animated_grid_width')->getString();  
$rijen=$eigennode->get('field_animated_grid_rows')->getString();
$kolommen=$eigennode->get('field_animated_grid_columns')->getString();
$link=$eigennode->get('field_animated_grid_link')->getString();
if ($link==0){
$link="true";
}
else{
$link="false";
}

use Drupal\file\Entity\File;
use Drupal\image\Entity\ImageStyle;

$node_storage = \Drupal::entityTypeManager()->getStorage('node');
$file_storage = \Drupal::entityTypeManager()->getStorage('file');

$nids = \Drupal::entityQuery('node')
         ->condition('type', $inhoudstype)
         ->condition('status', 1)
         ->execute();
        
$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($nids);
$imgcount=0;
foreach ($nids as $nid) {

$node = $node_storage->load($nid);
$node_url = $node->toUrl()->toString();
$node_title= $node->get('title')->getString();
$terms = $node->get($afbeeldingsveld)->getValue();


$x=0;
foreach ($terms as $term){

$image_alt= $node->$afbeeldingsveld[$x]->alt;
$alt[$imgcount]=$image_alt;
//$image_title= $node->$afbeeldingsveld[$x]->title;
$fid = $node->get($afbeeldingsveld)[$x]->entity->fid->value;
$file = File::load($fid);
$image_uri = $file->getFileUri();
$style=  ImageStyle::load('anigrid_square');

$url= $style->buildUrl($image_uri);
$relative_url = file_url_transform_relative($url);
$img_url[$imgcount]=$relative_url;
$img_link[$imgcount]=$node_url;
 

$x++;
$imgcount++;
}
}

?>    

Nu gaan we kijken in de code waar we onze Drupal gegevens moeten plaatsen.

Zo zie je dat er een gedeelte dynamisch werd gemaakt voor de afbeeldingen. Ik doorloop een lus voor elke afbeelding die ik verzameld heb en ik herschrijf die naar de originele code.

<div id="ri-grid" class="ri-grid ri-grid-size-1 ri-shadow">
                    <img class="ri-loading-image" src="/libraries/AnimatedResponsiveImageGrid/images/loading.gif"/>
                    <ul>
<?php
$y=0;
while ($y<$imgcount){
echo "<li><a href='".$img_link[$y]."'><img src='".$img_url[$y]."'/></a></li>\n";

$y++;
}
?>
                    
                    </ul>
                </div>

 

Ook in de javascript kan je php gebruiken. Hier zie je dat ik het aantal rijen en kolommen invoeg die in de velden werd ingevoegd.

$( '#ri-grid' ).gridrotator( {
                    rows : <?php echo $rijen?>,
                    columns : <?php echo $kolommen?>,
                    maxStep : 2,
                    interval : 2000,
                    w1024 : {
                        rows : 3,
                        columns :  6
                    },

 

Tenslotte kan je ook CSS aanpassen naar je wensen. Ik heb een gedeelte van de CSS uit de third party gehaald en op de pagina gezet. Zo kan de breedte dynamisch ingevoegd worden.

 <style type="text/css">
/* Grid wrapper sizes */
.ri-grid-size-1{
    width: <?php echo $breedte?>%;
}
.ri-grid-size-2{
    width: 100%;
}
.ri-grid-size-3{
    width: 100%;
    margin-top: 0px;
}
</style>

De module

Zet in je inhoudstype de script als standaard. Elke gebruiker zal dan de code automatisch gebruiken bij nieuwe nodes. Schakel dit veld uit in de formulierweergave.Een gebruiker moet de code niet zien.

Gebruik Features om de module te maken... Verzamel al wat je nodig hebt.

 

Vergeet het tekstformaat niet aan te vinken.


Deze werkwijze komt ruim aan bod in de Drupal trainingen gegeven aan het PCVO Scheldeland...Deze samenvatting helpt je op weg om als autodidact te kunnen starten. Opgelet... het is verslavend...