Één van de krachtigste onderdelen van Drupal is het templating systeem. Drupal kan een aantal template engines gebruiken, waarvan PHPTemplate de bekendste en meestgebruikte is. Een template engine is een stuk script dat een developer in staat stelt op een gemakkelijke manier content in zijn HTML te gieten. Nou is een template vaak meer dan één bestand, want veel dynamisch gegenereerde content moet tijdens het aanmaken al HTML om zich heen krijgen, zoals lijsten. De markup van content wordt zoals net beschreven dus tijdens het genereren gedaan in de modules van het CMS. Het is vaak bad practice om in de kern van een CMS te gaan timmeren. Als er een keer geupdate wordt, dan ben je namelijk al je wijzigingen kwijt. Om toch te zorgen dat je makkelijk de markup van de content kan aanpassen, kan je via de PHPTemplate engine de zogenaamde theme-functies overriden. Dit houdt in dat niet de standaard functie wordt aangeroepen, maar die van jou.
In de map van je template staat - of misschien nog niet - het bestand template.php. Als deze er nog niet staan kan je deze even aanmaken. Je kan dit bestand zien als een soort coördinator voor de template. Als je bijvoorbeeld Views wil aanmaken of net zoals wij Theme functies wil overriden, dan handelt template.php dit af. Om te beginnen zetten we PHP tags in het bestand in het lange formaat: <?php /*content*/ ?>. Het korte formaat (zonder 'php' in de openingstag) wordt niet altijd door alle servers ondersteund.
De volgende stap is aangeven dat je de bestaande functie wil overriden. We gaan dit nu doen voor theme_menu_tree():
<?php
function theme_menu_tree($pid = 1) {
if ($tree = menu_tree($pid)) {
return "\n<ul class=\"menu\">\n" . $tree . "\n</ul>\n";
}
}
?>Als eerste maken we in template.php een nieuwe functie met bijna dezelfde naam als de originele functie. Het verschil is dat theme vervangen wordt door phptemplate. Daardoor krijg je geen fout, doordat je twee dezelfde functies declareert, maar weet Drupal toch dat je hiermee een originele functie overschrijft en weet het systeem ook welke functie dat is:
<?php
function phptemplate_menu_tree($pid = 1) {
}
?>Onze overridefunctie krijgt ook dezelfde argumenten als de originele functie. Als laatste vertellen we PHPTemplate dat het systeem voor de code van deze functie moet kijken in een los bestand:
<?php
function phptemplate_menu_tree($pid = 1) {
return _phptemplate_callback('menu_tree', array('pid' => $pid));
}
?>_phptemplate_callback() roept PHPTemplate aan. Het tweede argument is altijd de naam van de theme functie minus het voorvoegsel theme_. Door middel van het derde argument geven we alle variabelen van de functie door aan het template bestand voor onze eigen functie. Dit gebeurt in de vorm van een array, hoeveel variabelen er ook aan de functie doorgegeven moeten worden. Dit was al het werk in template.php. Het systeem weet nu dat het de originele functie niet moet gebruiken, maar in plaats daarvan een template bestand moet laden voor de afhandeling van die functie.
Als derde stap maken we een nieuw template bestand aan. Dit soort bestanden heeft altijd de extensie *.tpl.php. De naam van het bestand wordt in ons geval menu_tree.tpl.php. Zoals je ziet gebruiken we voor de naam ook hier weer de naam van de functie, maar zonder het voorvoegsel theme_. Wij willen nu gewoon een kleine wijziging in de originele code aanbrengen, dus zetten we deze eerst in het bestand en gaan we dat later aanpassen. Let er op dat in een functie-template geen functie hoeft te staan. Je verwerkt de data puur en aan het einde print/echo je deze op het scherm:
<?php
if ($tree = menu_tree($pid)) {
echo "\n<ul class=\"menu\">\n" . $tree . "\n</ul>\n";
}
?>class="menu" voor wat andere elementen, dus voor deze dingen willen we daar graag menu-sidebar van maken, omdat menu's die hieruit komen toevallig allemaal in de sidebar staan:<?php
if ($tree = menu_tree($pid)) {
echo "\n<ul class=\"menu-sidebar\">\n" . $tree . "\n</ul>\n";
}
?>In het begin van deze tutorial legde ik al uit dat je op deze manier niet in de kern van Drupal bezig hoeft. We hebben nu ook gezorgd dat we al onze eigen code netjes in onze eigen template hebben staan. Het is zo heel makkelijk om een template met andere markup naast de onze te draaien of onze template naar een ander systeem te verplaatsen. Doordat je alle 'wijzigingen' aan het systeem onderbrengt in eigen modules of je eigen template, heb je een mooie scheiding en dus geen problemen als je iets wil vervangen of verhuizen. Mocht je door deze tutorial zin hebben gekregen meer te customizen aan je eigen systeem, dan staat op Drupal.org een lijst met themeable functions. Bedenk wel dat dit alleen de functies zijn die in de Drupal Core zitten. Modules van derden kunnen ook nog theme-functies hebben. Als je deze nodig hebt, zoek dan even in de betreffende module naar functies die met theme_ beginnen en je weet wat er mogelijk is. Succes!