Fat Free Framework Template Engine

Wenn man sich den Quellcode der beiden Beispiele aus der Hello-World-Seite ansieht, dann stellt man fest, dass das gar keine vollständige HTML-Seite ist mit all den Strukturen, wie sie eine reguläre HTML-Seite verlangt. Woher sollte die Information auch kommen!

Eine Lösung könnte nun darin bestehen, den F3-Code-Teil so in echo-Befehle einzubetten, dass eine ordentliche HTML-Seite entsteht. Das ist aber nicht besonders effektiv, denn für jede einzelne Seite müsse dieser Code wieder und wieder eingegeben werden.

Alle mehr oder weniger professionellen PHP-Programme arbeiten daher mit so genannten Templates. Das sind in der Regel Dateien, die das Grundgerüst der Website beinhalten, die vom PHP-Programm mit den variablen Inhalten gefüllt werden. Das Fat Free Framework unterstützt diese Herangehensweise mit einer eigenen Template-Engine.

Angenommen, es existiert eine Template-Datei layout-01.htm im Unterverzeichnis ui (abgekürzt für Userinterface), so wird diese Templatedatei so angezeigt.

Code der Datei template-demo-01.php

<?php
//Framework einbinden
require_once 'lib/base.php';
//nicht zwingend erforderlich:
F3::set('DEBUG',3);

// Pfad zu den Templates setzen
F3::set('GUI','ui/');
F3::route(
  'GET /template-demo-01.php',
  function() {
    echo Template::serve('layout-01.htm');
  }
);
F3::run();
?>

Und die Template-Datei layout-01.htm dazu:

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Powered by {{ @VERSION }}</title>
<style type="text/css">
</style>
</head>
<body>
  <div class="header">
    <h1>Template Datei</h1>
    <h2>Anzeige eine eingebauten Variablen</h2>
    <h3>{{@VERSION}}</h3>
  </div>
</body>
</html>

Template Demo 01 anzeigen

Die Template-Datei ist eher schlicht und einfach. Sie dient ja auch nur einer ersten Demonstration. Demonstriert wird aber gleich, wie man Variablen verwendet. So, wie im erweiterten Hello-World-Beispiel auf die eingebaute Variable VERSION direkt aus PHP zugegriffen wurde, kann auch aus dem Template heraus auf diese Variable zugegriffen werden. Das geschieht, in dem man {{@VERSION}} in den HTML-Code der Template-Datei einfügt.

Erweitertes Beispiel mit Variablenübergabe, CSS-Komprimierung und Subtemplate

In dem folgenden Beispiel habe ich einige Erweiterungen vorgenommen.

Zunächst wurden im PHP-Code die Variablen text1 und text2 initialisiert. Diese finden sich dann auch in der Templatedatei mit {{@text1}} und {{@text2}}.

Außerdem wurde im Template eine CSS-Datei integriert, allerdings nicht auf dem herkömmlichen Weg sondern mit {{ Web::minify(@GUI,array('style.css'),FALSE) }}. Die in einem F3-Plugin enthaltene Klasse Web verfügt über eine Funktion minify, die eine CSS-Datei verkleinert und direkt in den HTML-Code einfügt. Dabei wird die in der PHP-Datei festgelegte Variable GUI verwendet, um das korrekte Verzeichnis zu ermitteln. An Stelle einer CSS-Datei kann so auch eine JavaScriptdatei eingefügt werden.

Schließlich habe ich noch eine Art Subtemplate eingefügt. Mit so einem Subtemplate kann man immer wiederkehrende Bestandteile unterschiedlicher Einzelseiten auslagern. Zunächst wurde in der PHP-Datei die Variable reindamit mit dem Wert in-layout-02 belegt. Das ist der Name der Subtemplatedatei (ohne Dateierweiterung). In der ersten Templatedatei wird dann die F3-Funktion include ausgeführt.

Code der Datei template-demo-02.php

<?php
//Framework einbinden
require_once 'lib/base.php';
//nicht zwingend erforderlich:
F3::set('DEBUG',3);

// Pfad zu den Templates setzen
F3::set('GUI','ui/');
// Eigene Variablen
F3::set('text1','Ich bin der Demotext1');
F3::set('text2','Ich bin der <b>Demotext2</b>. <a href="../">Home</a>');

F3::route(
  'GET /template-demo-02.php',
  function() {
    F3::set('reindamit','in-layout-02');
    echo Template::serve('layout-02.htm');
  }
);
F3::run();
?>

Und die Haupt-Template-Datei layout-02.htm dazu:

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Powered by {{ @VERSION }}</title>
<!-- Classe Web, Funktion Minify(Basisverzeichnis steht in Variable GUI, Dateiname, -->
<style type="text/css">
  {{ Web::minify(@GUI,array('style.css'),FALSE) }}
</style>
</head>
<body>
  <div class="header">
    <h1>Template Datei</h1>
    <h2>Anzeige eine eingebauten Variablen</h2>
    <h3>{{ @VERSION }}</h3>
  </div>
  <div class="content">
    <h2>Eigene Variablen</h2>
    {{@text1}}
  </div>
  <F3:include href="{{@reindamit}}.htm"/>
  <div class="footer">
    {{ @text2}}
  </div>
</body>
</html>

Schließlich noch der Inhalt der Subtemplatedatei in-layout-02.htm:

<h4>Text aus der Datei in-layout-02.htm</h4>

Template Demo 02 anzeigen

Erweiterung mit Kontrollstrukturen

Nun noch eine Erweiterung des Templates mit Kontrollstrukturen. Angenommen, man möchte aus einer bestimmten Anzahl von Elementen, die beispielsweise in einem PHP-Array abgelegt sind, HTML-Code in Form einer Tabelle oder Liste erzeugen, so ist es sinnvoll, dies mit einem schleifenartigen Kontrukt zu erledigen.

Zunächst wird in der PHP-Datei ein Array mit Werten erzeugt:

F3::set('kinder',array('Paula','Klaus ','Peter'));

Um dieses Array Element für Element abzurufen, fügt man in der Templatedatei ein:

<ul>
  <F3:repeat group="{{@kinder}}" value="{{@kind}}">
    <li>{{@kind}}</li>
  </F3:repeat>
</ul>

Dieses Konstrukt durchläuft kinder und weist jeweils der Variablen kind den aktuellen Wert zu, der dann ausgegeben wird. Dies geschieht sinnvollerweise in einer <ul><li>-Liste.

Jetzt noch ein etwas komplexeres Beispiel. Zunächst wird eine Array mit 2 Subarrays erzeugt:

F3::set('tabelle',
array(
  'coffee'=>array('arabica','barako'),
  'tea'=>array('darjeeling','pekoe')
  )
);

Dieses Array wird im Template in eine Tabellenstruktur geschrieben. Das Array tabelle wird durchlaufen, wobei jeder Schlüsselwert in ikey geschrieben wird und das dazugehörige Unterarray in zeile. ikey wird ausgegeben und in einer weiteren Schleife wird das dazugehörige Unterarray durchlaufen, dessen Werte wiederum ausgegeben werden.

<table>
  <tr>
    <th>Produktgruppe</th>
    <th>Sorte 1</th>
    <th>Sorte 2</th>
  </tr>
  <F3:repeat group="{{@tabelle}}" key="{{@ikey}}" value="{{@zeile}}">
    <tr>
      <td>{{@ikey}}</td>
      <F3:repeat group="{{@zeile}}" value="{{@zelle}}">
        <td>{{@zelle}}</td>
      </F3:repeat>
    </tr>
  </F3:repeat> 
</table>

 

Template Demo 03 anzeigen