Svart bälte: template.php och temafunktioner

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
Itangalo's picture

Detta är den sjunde delen i guiden Sju steg mot svart bälte i att tema Drupal 6.

Med det svarta bältet tar vi oss in i vad som ibland beskrivs som the theming ninja’s weapon of choice: template.php. Det är en fil som brukar innehålla olika funktioner och lite mer avancerad logik för temat.

I detta avsnitt kommer vi att titta på temafunktioner som alternativ till tippelfippar. Vi ska se hur man kan skapa sina egna versioner av temafiler, och även hur man kan ersätta temafiler med tippelfippar. Till slut ska vi också gå igenom hur man kan flytta knölig logik från tippelfippar till template.php.

Temafunktioner

De element på en Drupalsajt som inte temas genom tippelfippar använder i stället temafunktioner – som sköter logik och bearbetning av data, för att skicka ut snyggt formaterad (X)HTML-kod.

Temafunktioner är ett lite mer omständligt sätt att formatera utdata än vad tippelfippar är. Temafunktioner är ren PHP, men i utdatan från funktionerna finns (X)HTML med i de allra flesta fall.

Precis som med tippelfippar vill man inte ändra i originalen, utan istället skapar man egna kopior som man redigerar i. Men istället för att ge företräde åt funktioner genom deras placering i filstrukturen blir man tvungen att ändra namnet på funktionen för att åsidosätta defaultfunktionerna.

Ett standardrecept för att skapa egna temafunktioner ser ut som följer:

  • Du använder Theme Developer för att ta reda på hur ett visst element fått sin formatering/struktur. Theme Developer säger att det kommer från en temafunktion (theme_xyz) och inte en tippelfipp (xyz.tpl.php).
  • Du letar upp originalfunktionen på ett av fyra sätt:
    • Genom en php-fil i lämplig modul eller include-fil. (Theme Developer borde ge information om var du ska leta.)
    • Genom funktionsregistret i Devel-modulen.
    • Genom api.drupal.org, som innehåller dokumentation om alla funktioner och filer som används för drupal.org.
    • Genom ett eget API-register som du skapat genom att installera API-modulen. Det kan vara fiffigt om du har många moduler som inte finns med på drupal.org.
  • När du väl hittat funktionen kopierar du hela funktionen, inklusive funktionsnamn och avslutande måsvinge, till template.php i katalogen för ditt undertema. Vanligtvis brukar man lägga funktionen sist i filen, men det ska inte spela någon roll så länge du inte råkar lägga den mitt i en annan funktion.
  • Byt namn på funktionen, från theme_xyz (eller möjligtvis phptemplate_xyz) till temanamn_xyz. (Det är detta som ser till att Drupal ger företräde för din funktion framför originalfunktionen.)
  • Genomför de ändringar du vill i funktionen.
  • Spara. Testa. Rensa cachen om du inte ser någon effekt. (Det görs på administrera > inställningar > prestanda, eller genom länkar i ett Devel-block.)

Att förvandla temafunktioner till tippelfippar

I många lägen kan det vara mer praktiskt att ha en tippelfipp istället för en temafunktion. Det gäller inte minst om en designer vill arbeta vidare med formateringen, utan att behöva svepa in all utdata i PHP-kod. (Däremot gäller det förmodligen inte om temafunktionen innehåller tung logik.)

Att förvandla en temafunktion till en tippelfipp är en överraskande snabb och enkel process. Det hela går ut på att skapa en tippelfipp med rätt namn och fylla den med den output som kommer från temafunktionen (inklusive eventuella villkor). Filnamnet ska vara samma som funktionsnamnet, men utan theme_ (eller motsvarande) och med understreck utbytta mot bindestreck. Exempelvis kan en funktion theme_xyz_abc() {print “<h2>Hello world!</h2>”;} mot en tippelfipp med namnet xyz-abc.tpl.php och innehållet <h2>Hello world!</h2>.

Inte alla temafunktioner gör sig bra som tippelfippar. Temafunktioner som använder for each-loopar är till exempel svåra att omvandla till tippelfippar på ett bra vis. En annan svårighet är att hålla avancerad logik utanför mallfilerna. Det är föremål för nästa avsnitt.

Lägga till variabler

En likhet mellan page.tpl.php och tippelfippar är att man bör hålla avancerad logik borta från tippelfipparna. Det beror på flera saker. Det mest uppenbara är att mallen blir svår att överblicka om det dyker upp flera rader långa if-satser eller variabler som byggs upp med många olika villkor. Men det kan också påverka webbplatsens prestanda på otrevliga sätt. (Om din comment.tpl.php innehåller villkor som kräver att data hämtas från databasen kan det bli jobbigt om en nod har 200 kommentarer eller så.)

I stället för att lägga in avancerad logik i tippelfippar bör man flytta den till en separat php-fil, nämligen template.php. I den filen kan man vanligtvis hitta diverse PHP-sjok och deklarationer som avancerade teman använder.

Ett praktiskt sätt att hålla tippelfippar rena från knölig kod är att ersätta all den knöliga koden med en enda variabel. Om man exempelvis har omständliga villkor för hur användarnamn ska matas ut tillsammans med noder ersätter man alla dessa villkor med en variabel, exempelvis $formatted_user_data, och låter template.php befolka den variabeln med den data som behövs. Resultatet är en tippelfipp som är renare och snyggare, och om man har tur också en del vinst i prestanda.

För att skapa nya variabler till en tippelfipp behöver man använda temalagrets preprocess-funktioner. Mallen för detta ser ut som följer:

temanamn_preprocess (&$vars) {
$vars['variabelnamn'] = uttryck;
}

Alternativt:
temanamn_preprocess_tippelfipp (&$vars) {
$vars['variabelnamn'] = uttryck;
}

I det första fallet blir variabeln tillgänglig i samtliga tippelfippar (inklusive page.tpl.php), men i det senare fallet blir den bara tillgänglig i mallfilen tippelfipp.tpl.php. Om variabeln bara kommer att användas i en enda tippelfipp är det senare att föredra, eftersom det minskar risken för krockar i variabelnamn och dessutom medför små prestandavinster.

Funktionerna läggs in i template.php, som kommer att hittas och köras automatiskt. Om template.php tidigare var tom bör man se till att inleda filen med <?php – däremot är det best practice att inte avsluta filen med ?>.