Artikelformat

xsl als Templatesystem

Obwohl PHP als Template-Sprache entworfen wurde, gibt es inzwischen viele Templatesysteme, die in PHP geschrieben sind. Diese stellen Daten bspw. als HTML-Code dar. Dieser Beitrag befasst sich nun mit dem Two Step View Design Pattern, das in PHP umgesetzt werden kann und dabei fast kein PHP nutzt. Dieser Widerspruch wird nun aufgeklärt.

Das Pattern beschreibt eine 2 stufige Transformation von Daten zu einer fertigen Ausgabe. Zuerst werden die Daten aus der Datenbank gelesen und in der Business Logik errechnet. Es besteht die Möglichkeit verschiedene Datenquellen anzuzapfen. Wichtig ist nur, dass die aggregierten Daten in einer domänspezifischen XML Repräsentation existieren. Diese Daten werden nun in einem ersten Schritt aufbereitet, wodurch ein neues XML-Dokument entsteht. Beispielsweise für eine Ausgabe auf dem Bildschirm. Diese Zwischenstufe ist noch kein fertiges HTML. Erst im zweiten Schritt wird dieses Zwischendokument in HTML transformiert.
Der Vorteil dieser Vorgehensweise liegt darin, dass man so nur das Template definieren muss dabei eigene Tags zur Verfügung hat. Damit können komplexe Strukturen durch ein simples Tag ausgedrückt werden. Auch kann man die vorhandenen HTML Tags um eigene erweitern. Bspw ein Kalendar-Input Feld o.ä. Durch die Benutzung vorgegebener Komponenten kann man auch ein Design definieren, dass die gesamte Webapplikation oder Webseite nutzt. Es entsteht also ein einheitliches Design und Layout.
Ein weiterer Vorteil ist die mehrfache Nutzung der domänspezifischen Daten. Mit Hilfe alternativer Layout-Informationen lässt sich eine andere Art der Ausgabe generieren. PDF- oder Excel-Dateien sind theoretisch möglich.

Soviel zur Theorie. Im folgenden gibt es eine simple Beispielimplementierung.

Zuerst gibt es die Daten. Diese sind in diesem Fall als XML-Datei abgelegt. In einem echten System würde man DOMDocument, XMLWriter oder SimpleXML nutzen, um die Daten aus der Businesslogik in XML-darzustellen. Im Beispiel heißt der Root-Knoten array. Darin gibt es row– und cell-Tags. So kann ein 2-dimensionales Array dargestellt werden.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="UTF-8"?> 
<array>
    <row> 
        <cell>14</cell>
        <cell>17</cell>
        <cell>13</cell>
        <cell>12</cell>
        <cell>11</cell>
        <cell>16</cell>
        <cell>14</cell>
        <cell>11</cell>
    </row> 
    <row> 
        <cell>24</cell>
        <cell>27</cell>
        <cell>23</cell>
        <cell>22</cell>
        <cell>21</cell>
        <cell>26</cell>
        <cell>24</cell>
        <cell>21</cell>
    </row>
    <row> 
        <cell>34</cell>
        <cell>37</cell>
        <cell>33</cell>
        <cell>32</cell>
        <cell>31</cell>
        <cell>36</cell>
        <cell>34</cell>
        <cell>31</cell>
    </row>
</array>

Die definierten Daten werden durch ein xsl-Template transformiert und es entsteht die abstrakte Beschreibung eines Layouts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8"/> 
    <xsl:template match="/array">
        <layout> 
            <simplelist>
                <xsl:for-each select="row"> 
                    <block>
                        <xsl:for-each select="cell"> 
                            <data>
                                <xsl:value-of select="."/> 
                            </data>
                        </xsl:for-each> 
                    </block>
                </xsl:for-each> 
            </simplelist>
        </layout> 
    </xsl:template>
</xsl:stylesheet>

Die nun vorhandene Beschreibung wird im zweiten Schritt in HTML-Code umgewandelt. Man erhält eine HTML-Datei mit Header, Body und einer Tabelle mit den eingangs gezeigten Daten.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="UTF-8" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" />
    <xsl:template match="/layout"> 
        <html>
            <head> 
                <title>XSL Test</title>
            </head> 
            <body>
                <xsl:apply-templates/> 
            </body>
        </html> 
    </xsl:template>
    <xsl:template match="simplelist"> 
        <table border="1">
            <xsl:apply-templates/> 
        </table>
    </xsl:template>
    <xsl:template match="block"> 
        <tr>
            <xsl:apply-templates/> 
        </tr>
    </xsl:template>
    <xsl:template match="data"> 
        <td>
            <xsl:apply-templates/> 
        </td>
    </xsl:template> 
</xsl:stylesheet>

PHP bietet mit der XSLTProcessor-Klasse einen guten Zugang zu den XSL-Transformationen. Eine einfache Two-Step-View Implementierung ist der folgende HTMLGenerator.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class HTMLGenerator {
 
    /**
     * Führt die Template, Layout und Daten zusammen und generiert einen Ausgabe-String
     *
     * @param DOMDocument $data
     * @param DOMDocument $data2layout
     * @param DOMDocument $layout2html
     * @return String  
     */
    public static function execute(DOMDocument $data, DOMDocument $data2layout, DOMDocument $layout2html) {
 
        // Daten nach Layout - Prozessor erzeugen
        $data2layout_proc = new XSLTProcessor;
        // Spezifisches Stylesheet einlesen 
        $data2layout_proc->importStyleSheet($data2layout);
        // Erste Transformation durchführen 
        $layout = $data2layout_proc->transformToXML($data);
        // Layout nach Präsentation - Prozessor erzeugen
        $layout2html_proc = new XSLTProcessor;
        // Allgemeines Layout Stylesheet einlesen 
        $layout2html_proc->importStyleSheet($layout2html);
        // Zweite Transformation durchführen 
        $pres = $layout2html_proc->transformToXML(DOMDocument::loadXML($layout));
        // Rückgabe des fertigen Präsentationscodes
        return $pres;
    }
 
}

Der Vorteil von XSL ist, dass man dieses Verfahren mit jeder Programmiersprache einsetzen kann, die einen XSLTProzessor mitbringt. Und dabei können Template- und Layout-Dateien ohne Aufwand migriert werden. Man benötigt nur eine ähnliche Implementierung wie der HTMLGenerator und Logik, die die XML-Daten generiert.

Das Beispiel ist (inkl. index.php) wie gewöhnlich im SVN-Repository zu finden.

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close