zurückInhaltvorwärts Perl Einführung: Das HTML::Template Modul

12.7 Das HTML::Template Modul

Im letzten Kapitel zum CGI Modul, hatten die von unseren Beispielskripten generierten Seiten ein eher einfaches Layout (falls man das überhaupt so nennen möchte). Möchte man ein umfangreicheres Layout erzeugen, werden die meisten schnell davon absehen dieses über die Methodenaufrufe in CGI.pm zu lösen.

Aber auch eine in den Perl-Code als "Here-Dokument" eingebettete HTML-Seite kann man nicht als Ideallösung bezeichnen. Spätestens wenn man die Vorlage für die Ausgabeseite nicht selber gestaltet, und bei jeder kleinen Änderung am Seitenlayout den ganzen HTML-Kram per Cut and Paste in das Skript kopieren muß, wird man sich schnell nach einer anderen Lösung umschauen.
Bevor man sich jetzt eine Lösung selbst zusammenbastelt, bei der man eine Vorlagendatei einliest und einige bestimmte Schlüsselwörter per Substitutionsoperator durch die Ergebnisse des Perl-Skripts ersetzt, sollte man sich einmal anschauen, welche Lösungsmöglichkeiten es sonst noch so gibt.

Eine einfache Lösung hierfür findet man mit dem HTML::Template Modul, dies findet man wie gewohnt im CPAN oder auch als ppm Paket auf der Activestate Seite. Dieses Modul vereinfacht den Umgang mit HTML-Vorlagen in es einfach eine kleine Zahl neuer HTML-Tags einführt.

Besonderheiten:

Auch wenn die Tags des HTML::Template Moduls auf den ersten Blick sehr nach HTML aussehen, muß man einige Besonderheiten beachten.

  1. Ein Tag muß komplett in einer Zeile stehen
  2. Es sind Konstruktionen möglich, die in 'reinem' HTML nicht erlaubt sind

Während man den 2.Punkt leicht umgehen kann (wie zeigen wir später), kann der 1. Punkt schnell zur Falle werden. Z. B. wenn irgendein möchtegern WYSIWYG HTML-Editor die Tags gnadenlos auseinander reisst. Aber auch die Freunde von Handgestricktem HTML können sich leicht selbst austricksen, indem sie ein (wirklich praktisches) Tool wie Tidy-HTML verwenden und dabei die Zeilen des HTML-Codes auf eine handliche Länge umbrechen lassen...

Wie sieht nun also so eine HTML-Vorlage aus? Im Prinzip ist das, wie bereits erwähnt, eine ganz normale HTML Seite, wo lediglich ein paar spezielle Tags eingestreut werden:

<html>
  <head>
    <title>Ein kleiner Test<title>
  </head>
  <body>
    Browser-Typ: <TMPL_VAR NAME="user_agent">
    Remote-Host: <TMPL_VAR NAME="host">
  </body>
</html>

In diesem kleinen Beispiel soll einfach Ausgegeben werden, welcher Browser der aufrufende Benutzer verwendet und welche IP-Adresse der PC hat. Wer sich mit HTML ein wenig auskennt, wird auch schon einen der HTML::Template Tags erblickt haben, mit TMPL_VAR wird einfach ein Platzhalter für eine Variable in den HTML-Code eingefügt.

Die im Template verwendeten Variablen müssen natürlich im CGI-Skript entsprechend gesetzt werden, deshalb sehen wir uns zunächst das dazugehörige Skript an:

#!/usr/bin/perl

use CGI;
use HTML::Template;

$cgi = new CGI;
$template = HTML::Template-&gtnew(filename => "c:\\inetpub\\wwwroot\\template.html");

print $cgi->header();

$template->param(
      user_agent => $cgi-&gtuser_agent(),
      host => $cgi->remote_host(),
);

print $template-&gtoutput();

Wie es sich für ein ordentliches Perl-Modul gehört, müssen wir zunächst ein HTML::Template Objekt erzeugen. Die einfachste Methode solch ein Objekt zu erzeugen, ist es die New Methode mit dem Name/Wert Paar Filename=>"Pfad" als Parameter aufzurufen. Ein Template Objekt kann nur eine HTML-Seite beeinhalten.

Wenn der Pfad zum Template korrekt war, können wir jetzt die eingefügten Platzhalter durch "richtige" Variablen ersetzen. Die Methode hierzu heißt param. Um die Werte im Template zu ersetzen übergeben wir der Methode einen Hash, der die Werte der Variablen enthält. Im Beispiel sind die Werte Rückgabewerte der Methoden des CGI-Moduls, welche den Browsertypen und die IP-Adresse des aufrufenden rechners ermitteln.

In unserem Beispiel sind jetzt alle Platzhalter durch Werte ersetzt worden, wir müssen nur noch die fertige HTML-Seite ausgeben. Die Methode hierzu heißt output() und benötigt keine weiteren Parameter.

Soweit kann man zwar schon ganz gut mit dem Modul arbeiten, was macht man aber, wenn man vorher nicht die genaue Menge der auszugebenden Daten kennt? Z.B. weiß man bei einer Datenbankabfrage ja vorher meist nicht wieviele Ergebnisse man erhält. Aber auch hierfür kennt das HTML::Template Modul eine Lösung: Den TMPL_LOOP Tag. Wir werden in einem kleinen Beispiel eine Multiplikationstabelle ausgeben.

Sehen wir uns zunächst das HTML-Template an:

<html>
  <head>
    <title>Ein kleiner Test</title>
  </head>
  <body>
  <table>
  <TMPL_LOOP NAME=Tabelle>
      <tr>
         <td>2 * <TMPL_VAR NAME=zahl></td>
         <td>=</td>
         <td><TMPL_VAR NAME=ergebnis></td>
      </tr>
  </TMPL_LOOP>
</table>
  </body>
</html>

Im Gegensatz zum TMPL_VAR Tag muß der TMPL_LOOP Tag natürlich am Ende des zu wiederholenden HTML-Codes abgeschlossen werden. Im Beispiel besteht der sich wiederholende Teil aus einer Tabellenzeile, die 2 Platzhalter für Daten, zahl und ergebnis, enthält. Im HTML-Code muß nicht festgelegt werden, wie groß die Tabelle tatsächlich wird.

Das enstprechende CGI-Skript ist etwas komplizierter als unser erstes Beispiel, da hier ausgiebiger Gebrauch von Referenzen gemacht wird. Aber sehen wir uns zunächst mal den Code an:

#!/usr/bin/perl

use CGI;
use HTML::Template;

$cgi = new CGI;
$template = HTML::Template->new(filename => "c:\\inetpub\\wwwroot\\template.html");

print $cgi->header();

for($zahl=1;$zahl<10;$zahl++) {
        my %zeile;
        $ergebnis=2*$zahl;
        $zeile{zahl} = $zahl;
        $zeile{ergebnis} = $ergebnis;
        push (@liste, \%zeile);
}
 $template->param(tabelle => \@liste );
print $template->output();

Die Erzeugung des Template Objekts wurde ja schon weiter oben beschrieben und soll hier nicht wiederholt werden. Interessanter ist die for-schleife. In jedem durchlauf wird ein Hash (%zeile) mit den Elementen "zahl", welches die zu multiplizierende Zahl entält, und "ergebnis", wo das Ergebnis unserer Rechenoperation abgelegt wird, angelegt. Dieses hash entspricht genau einer auszugebenden Zeile im HTML-Template.

Eine Referenz auf dieses Hash wird nun in das array @liste "gepusht". @liste enthält also genau so viele Zeiger auf Hashes, wie es auszugebende Zeilen gibt. Jetzt ist auch schon der schwere Teil geschafft, um im Template die Platzhalter zu ersetzen ist nur ein vergleichsweise simpler Methodenaufruf nötig. Wir übergen einfach eine Referenz auf das Array @liste an die param Methode.

Die Ausgabe erfolgt wieder mit der output() Methode. Im Skript kann man jetzt die Anzahl der auszugebenden Werte beliebig verändern ohne das Template nochmal anfassen zu müssen.

Perl Einführung: Das HTML::Template Modul zurückInhaltvorwärts