Q)

Die QWeb Template Engine

Im vorigen Abschnitt haben wir unseren Widgets Inhalte hinzugefügt, indem wir ihr DOM direkt manipuliert (und hinzugefügt) haben:Dies ermöglicht die Generierung und Anzeige jeder Art von Inhalt, wird aber unhandlich, wenn große Mengen an DOM generiert werden (viele Duplikationen, Zitierprobleme, ...). Wie in vielen anderen Umgebungen ist die Lösung von Odoo die Verwendung einer Template Engine. Die Template-Engine von Odoo heißt QWeb. QWeb ist eine XML-basierte Template-Sprache, ähnlich wie Genshi, Thymeleaf oder Facelets. Die meisten Javascript-Template-Engines sind textbasiert, was eine einfache strukturelle Erweiterbarkeit ausschließt, bei der eine XML-basierte Template-Engine generisch geändert werden kann, z.B. mit Hilfe von XPath oder CSS und einer Baumänderungs-DSL (oder auch nur XSLT). Diese Flexibilität und Erweiterbarkeit ist ein Kernmerkmal von Odoo, und der Verlust dieser Flexibilität und Erweiterbarkeit wurde als inakzeptabel erachtet. 

QWebFirst

Mit QWebFirst definieren wir eine einfache QWeb-Vorlage in der fast leeren Datei oepetstore/static/src/xml/petstore.xml: Jetzt können wir diese Vorlage innerhalb des HomePage-Widgets verwenden. Mit Hilfe der oben auf der Seite definierten QWeb-Lader-Variable können wir die in der XML-Datei definierte Vorlage aufrufen: QWeb.render() sucht nach der angegebenen Vorlage, rendert sie in eine Zeichenfolge und gibt das Ergebnis zurück. Da Widget() jedoch über eine spezielle Integration für QWeb verfügt, kann die Schablone über ihr Schablonenattribut direkt auf dem Widget gesetzt werden:Obwohl das Ergebnis ähnlich aussieht, gibt es zwei Unterschiede zwischen diesen Verwendungen:Bei der zweiten Version wird die Schablone direkt vor dem Aufruf von start() gerendert:In der ersten Version wird der Inhalt der Schablone zum Wurzelelement des Widgets hinzugefügt, während in der zweiten Version das Wurzelelement der Schablone direkt als Wurzelelement des Widgets gesetzt wird. Aus diesem Grund erhält auch das Unter-Widget "greetings" einen roten Hintergrund. Vorlagen sollten ein einzelnes Nicht-Root-Element haben, insbesondere wenn sie als Vorlage eines Widgets festgelegt sind. Wenn es mehrere "Wurzelelemente" gibt, sind die Ergebnisse undefiniert (normalerweise wird nur das erste Wurzelelement verwendet und die anderen werden ignoriert).

QWeb Context

Bei expliziten Aufrufen von QWeb.render() werden die Schablonendaten als zweiter Parameter übergeben: Bei Verwendung der Integration von Widget() ist es nicht möglich, der Schablone zusätzliche Daten zur Verfügung zu stellen. Die Schablone erhält eine einzelne Widget-Kontextvariable, die auf das gerade gerenderte Widget verweist, kurz bevor start() aufgerufen wird (der Zustand des Widgets entspricht im Wesentlichen dem von init() eingerichteten Zustand).

Vorlagendeklaration

Wir haben gesehen, wie QWeb-Vorlagen gerendert werden, sehen wir uns nun die Syntax der Vorlagen selbst an. Eine QWeb-Vorlage besteht aus regulärem XML gemischt mit QWeb-Direktiven. Eine QWeb-Direktive wird mit XML-Attributen deklariert, die mit t-.t-name beginnen, nimmt den Namen der zu definierenden Vorlage an und deklariert, dass sie mit QWeb.render() aufgerufen werden kann. Sie kann nur auf der obersten Ebene einer Schablonendatei verwendet werden. escapingIt nimmt einen Javascript-Ausdruck, der ausgewertet wird, das Ergebnis des Ausdrucks wird dann HTML-escaped und in das Dokument eingefügt. Da es sich um einen Ausdruck handelt, ist es möglich, nur einen Variablennamen wie oben anzugeben, oder einen komplexeren Ausdruck wie eine Berechnung:Outputing HTMLUm HTML in die gerenderte Seite einzufügen, verwenden Sie t-out. Wie t-esc nimmt es einen beliebigen Javascript-Ausdruck als Parameter, führt aber keinen HTML-escape-Schritt aus.<div><t t-out="name.link(user_account)"/></div>

t-out darf nicht für Daten verwendet werden, die vom Benutzer zur Verfügung gestellte Inhalte enthalten, da dies zu Cross-Site-Scripting-Schwachstellen führt

Conditionals

QWeb kann mit t-if bedingte Blöcke haben. Die Direktive nimmt einen beliebigen Ausdruck, wenn der Ausdruck falsch ist (falsch, null, 0 oder eine leere Zeichenkette), wird der gesamte Block unterdrückt, andernfalls wird er angezeigt.QWeb hat keine "else"-Struktur, verwenden Sie ein zweites t-if mit der ursprünglichen Bedingung invertiert. Möglicherweise möchten Sie die Bedingung in einer lokalen Variablen speichern, wenn es sich um einen komplexen oder teuren Ausdruck handelt.

t-Iteration

Um auf einer Liste zu iterieren, verwenden Sie t-foreach und t-as. t-foreach nimmt einen Ausdruck, der eine Liste zurückgibt, und iteriert auf t-as nimmt einen Variablennamen, der während der Iteration an jedes Element gebunden wird.

Definieren von Attributen

QWeb bietet zwei verwandte Direktiven zur Definition berechneter Attribute: t-att-name und t-attf-name. In beiden Fällen ist name der Name des zu erstellenden Attributs (z.B. definiert t-att-id das Attribut id nach dem Rendern). 

Aufrufen anderer Vorlagen

Vorlagen können in Unter-Vorlagen aufgeteilt werden (aus Gründen der Einfachheit, Wartbarkeit, Wiederverwendbarkeit oder zur Vermeidung übermäßiger Verschachtelung von Markups). Sub-Templates erben den Rendering-Kontext ihres Aufrufers.

Verwendung von QWeb in Widgets

Erstellen Sie ein Widget, dessen Konstruktor zwei Parameter außer dem übergeordneten Parameter: product_names und color.product_names sollte ein Array von Zeichenketten sein, wobei jede der Name einer Produktfarbe eine Zeichenkette ist, die eine Farbe im CSS-Farbformat enthält (d.h.: #00000000 für Schwarz).Das Widget sollte die angegebenen Produktnamen untereinander anzeigen, jede in einer separaten Box mit einer Hintergrundfarbe mit dem Wert von color und einem Rahmen. Zum Rendern des HTML sollten Sie QWeb verwenden. Alle erforderlichen CSS sollten sich in oepetstore/static/src/css/petstore.css befinden.