Theming views in Drupal

In Drupal kan je vooral met combinatie van de Views module data precies zo tonen als jij dat wil. Je kan daarbij alle html-code overriden in je template zonder dat je in de core modules aanpassingen hoeft te maken. Maar dit vereist wel een wat lastig proces met de phptemplate engine.

Stel dat...
Stel dat je een Drupal (5) site hebt waarbij je ook een blog hebt. Je wilt nu bijvoorbeeld de laatste 3 items van de blog tonen op de frontpage in een bepaalde region. Dan maak je dus de betreffende View aan, type block. In dit geval wordt het een teaser-view want je wilt natuurlijk niet de hele posts tonen.

Aangenomen dat dit gelukt is (dit was is het makkelijke gedeelte) zal je zien dat de items getoond worden volgens de html-opmaak van block.tpl.php. Hierbij wordt de content wegeschreven via:
<?php print $block->content; ?>
Maar daar kan je op dus niets meer aanpassen om die content anders te tonen. Zo wil je er misschien wel de auteur bij of de datum.

De oplossing
Je moet phptemplate vertellen welke functie hij moet overriden en welke template daarvoor gebruikt moet worden. Dit doe je allemaal in template.php in je template folder. Eerst moet je dus weten welke functie gebruikt wordt zodat je deze kan overrulen. Alle functies die door drupal 5 gebruikt worden om html te tonen en die dus overridden kunnen worden (bestaat er eigenlijk wel een goed Nederlands woord voor override/overrule?) beginnen met theme_.

In dit geval wordt met de Views module iets getoond dus moet je daar op zoek. Je vind dan in modules/views/views.module deze functie:
/**
* Display the nodes of a view as teasers.
*/
function theme_views_view_teasers($view, $nodes, $type) {
return views_theme('views_view_nodes', $view, $nodes, $type, true);
}
Dat is de functie die wij in dit voorbeeld gebruiken: een teaser-view zoals ik boven aangaf.

Nu kunnen we dus in template.php aangeven dat we hier zelf ons eigen ding willen doen. Dat doen we door dezelfde functie te declareren en theme te vervangen door phptemplate:

function phptemplate_views_view_teasers($view, $nodes, $type, $teasers = true, $links = true) { ... }

In de functie zetten we een phptemplate callback zodat de goede .php file uiteindelijk aangestuurd wordt (idealiter wil je in template.php geen html-code daar dit alleen voor php functies bedoeld is) :
return _phptemplate_callback('views_view_teasers', array('view'=>$view, 'nodes'=>$nodes, 'type'=>$type, 'teasers'=>$teasers,'links'=>$links));
De $hook is 'views_view_teasers' en dat moet dezelfde string zijn achter phptemplate_ in de functienaam.

Als we nu in onze template folder een bestand aanmaken dat views_view_teasers.tpl.php heet zal deze nu gebruikt worden voor teaser-views. We zijn er echter nog niet omdat de $nodes die we nu doorgeven alleen een node-id doorgeven. Om daadwerkelijk de hele nodes (met alle velden) door te krijgen kunnen we onze functie een beetje uitbreiden met een foreach en node_load.
function phptemplate_views_view_teasers($view, $nodes, $type, $teasers = true, $links = true) {
foreach ($nodes as $n) {
$node = node_load($n->nid);
$output .= _phptemplate_callback('views_view_teasers', array('view'=>$view, 'node'=>$node, 'type'=>$type, 'teasers'=>$teasers,'links'=>$links));
}
return $output;
}
Nu hebben we in views_view_teasers.tpl.php een object $node waar we dus complete vrijheid hebben om dit op te maken.

We zijn er bijna!
Er is echter nog een probleem. We hebben nu een template gemaakt voor alle teaser views. Dus als we elders op de site een nieuwe view aanmaken die ook een teaser overzicht geeft dan zal ook deze template gebruikt worden. Waarschijnlijk willen we dat niet - we willen specifiek voor deze View een template.

Dat doe je door de functie in template.php een nog wat langere naam te geven: achter phptemplate_views_view_teasers plak je _De_Naam_Van_Je_View. Vul dit ook in in de _phptemplate_callback en natuurlijk ook de naam van de tlp.php file.

Je kunt dus wel bizar lange functie en bestandsnamen krijgen maar je weet in ieder geval zeker dat het dan alleen voor die betreffende View gebruikt wordt. Het werkt eigenlijk een beetje vergelijkbaar zoals CSS werkt om een specifiek, diepgelegen element te stylen.

Een vergelijkbare uitleg vindt ook hier op drupal.org met op de volgende pagina een voorbeeld.

De week van ... sociale media

Read More »

About

This is the company blog of
Drupal specialist Merge.nl

We are located in Breda (Netherlands) and build websites using Drupal. More about us.

Content on this blog is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Netherlands License.

Creative Commons License

Recent Comments

Social