Template-Engines für C++

Standard

Ich habe in den letzten Tage nach einer Alternative für NL::Template gesucht, weil der Support für C++98 in NL::Template nicht optimal zu sein scheint. Es gibt zwar ein speziellen Branch für C++98, wenn ich diesen verwende, bekomme ich jedoch einen Speicherzugriffsfehler.

Im englischsprachigen Wikipedia gibt es eine tabellarische Auflistung von Template-Engines, ebenso wie für C++: http://en.wikipedia.org/wiki/Comparison_of_web_template_engines

Google ctemplate scheint von Google fallen gelassen worden zu sein und wird noch von einer Person auf GitHub weiter gepflegt. Es gib noch zwei Frameworks, die zum Großteil nur auf Russisch dokumentiert sind (auch in den Sourcen). Aber irgendwie habe ich nichts wirklich Überzeugendes gefunden.

Ich habe auch ein Wenig zu den (relativ) neuen Programmiersprachen Go und Rust quer gelesen. Beide möchten eine Alternative zu C++ sein und wollen es besser machen, als C/C++. Ich war sehr erstaunt zu sehen, dass es für beide Programmiersprachen schon mehrere ausgereift wirkende Web Frameworks gibt.

Mein Eindruck ist: C++ kann sich im Web-Umfeld warm anziehen. Der einzige Vorteil, den ich noch bei C++ sehe, ist dass es mehr Compiler zur Auswahl gibt und dass diese für mehr Plattformen zur Verfügung stehen, als für Rust und Go ist. Im Gegensatz zu node.js, gibt es in Rust und Go echte Nebenläufigkeit (zu dem noch auch einen interessanten Ansatz). Ich denke, das wird die nächsten Jahren noch recht spannend werden.

Kurztipp: Modularer Seiten mit dem Tntnet Template-System ecpp

Standard

In aller Regel hat man auf einer Seite immer wiederkehrende Elemente, wie den Kopfbanner, ein Navigation oder eine Fußzeile. Um die DRY-Regel „Don’t repeat yourself“ zu befolgen, müssen wir also ein Weg finden, wie wir diese immer wiederkehrenden Elente auslagern und in die betreffenden Seiten als externe Elemente wieder einbetten. In Tntnet gibt es verschiedenen Möglichkeiten dieses zu tun. Diese beruhen auf zwei grundlegenden Technologien, die ich hier kurz vorstellen möchte.

Einbetten von Code

Die erste Variante ist die, den Code, der sich immer wiederholt, in eine externe ecpp-Datei auszulagern, und den Code per include an die betreffenden Stellen der ecpp-Views einzubetten. Dieses geschieht über:

<%include>src/view/part/head.ecpp</%include>

Hier wird der Code der Datei „src/view/part/head.ecpp“ eingefügt. Beim Übersetzen der ecpp-Datein wird der Code 1:1 an die betreffende Stelle kopiert. Das Verfahren ist sehr simpel.

Der Vorteil ist, dass schon bei dem Übersetzen des Codes fehlende Abhängigkeiten erkannt werden, z.B. wenn die Datei mit dem zu includierenden Code nicht vorhanden ist.

Der Nachteil ist, dass die Komponenten/Dateien keine eigenen Namensräume haben. Das kann dazu führen, dass es zu unerwünschten Nebeneffekten kommt, z.B. wenn zufällig die gleichen variablen Namen verwendet werden. Ein weitere Nachteil ist, dass das Build-System (GNU Make z.B.) nichts von dem Code-Include weiß. Wenn der Code, der includiert wird, von dem Entwickler geändert wird, weiß das Build-System nicht, dass es alle ecpp-Dateien neu übersetzen muss, in denen der Code includiert wurde.  Also muss man händisch ein „make clean“ ausführen, das wiederum für längere Übersetzungszeiten sorgt. Alternativ kann man versuchen, diese Abhängigkeiten mit Tools wie Autotools abzubilden. Das setzt jedoch ein gesteigertes Wissen über das Build-System voraus.

Einbetten von Komponentenausgaben

Ein anderer Weg ist, die Elemente, die man immer auf verschiedenen Seiten einbetten will, als eigenständige Komponenten umzusetzen. Dazu werden die diese Elemente (Menüs, Banner, Fußzeile, etc.) als eigenständige Komponenten übersetzt. Diese werden dann wiederum zur Laufzeit in der Seite aufgerufen und deren Rückgaben werden dann in die (Gesamt-)Ausgabe eingebettet. Das geschieht über diesen Tag:

 <& core_part_head qparam >

„core_part_head“ ist die Komponente die aufgerufen wird. „qparam“ sind die Request-Parameter des Ausrufs, die an die (Teil-)Komponente weitergereicht wird.

Der Vorteil dieses Verfahren ist, dass das Build-System nicht die Abhängigkeiten kennen muss. Ein weitere Vorteil ist, dass die Komponenten völlig autonom sind und sich untereinander nicht in die Quere kommen können.

Ein Nachteil ist, dass bei dem Aufruf der Teil-Komponente die Aufruf-Parameter weitergereicht werden müssen. Ein weiterer Nachteil ist, dass die Verknüpfung nur sehr locker ist, und nicht zur Übersetzungszeit geprüft wird. Das bedeutet, dass bei einem Schreibfehler des Komponentennamen, dies leider erst zur Laufzeit zu einem Fehler führt.

Ein weiteres Merkmal dieser Variante kann man als Vor- und als Nachteil sehen: Die Teil-Komponenten, also Menüs, Banner, Fußzeilen usw. lassen sich direkt aufrufen, wenn man die URL der Teil-Komponente kennt. Im obigen Beispiel „http://domainname.de/core_part_head„. Zu sehen bekommt man dann das Menü oder die Fußzeile oder was auch immer die Teilkomponente ist.

Das ist kein Drama und lässt sich durch rewrite rules abfangen, nur man muss halt daran denken. Etwas fataler könnte es sein, wenn man seine ACLs (Access Control List) URL-Basiert realisiert. Dann könnte es sein, dass sich ein User quasi „unter dem Radar“ Zugang zu Funktionen verschaffen kann, die für ihn nicht gedacht sind.

Weiterführendes: ecpp manpage: http://www.tntnet.org/man7/ecpp.7.html


Creative Commons Lizenzvertrag