Odoo und OWL

Ein Praxisbeispiel für die Nutzung von Odoo OWL
October 3, 2024 by
Odoo und OWL
manaTec GmbH, Denis Orechov
 

Mit jeder neuen Version von Odoo wird auch das hauseigene JavaScript-Framework OWL (Odoo Web Library) weiterentwickelt und verbessert. OWL ist ein modernes, komponentenbasiertes Framework, das Odoo dabei unterstützt, dynamische und effiziente Webanwendungen zu erstellen. Es basiert auf einem reaktiven Ansatz, der eine einfachere und flexiblere Entwicklung von Benutzeroberflächen ermöglicht. Die kontinuierliche Weiterentwicklung von OWL hat direkten Einfluss auf die Leistungsfähigkeit und Flexibilität von Odoo-basierten Systemen.

Das Ignorieren dieses wichtigen Teils von Odoo könnte dazu führen, dass Optimierungen und Verbesserungen Ihrer Kundensysteme nur ineffizient oder gar nicht umgesetzt werden können. Entscheiden Sie sich jedoch dafür, in OWL einzusteigen, werden Sie schnell feststellen, dass es einige Herausforderungen gibt, die Sie eigenständig bewältigen müssen. Zwar finden sich Dokumentationen, Beispiele und weiterführende Ressourcen auf dem offiziellen GitHub-Repository von OWL, allerdings sind viele dieser Materialien entweder nicht detailliert genug oder behandeln Beispiele, die nicht direkt auf Odoo zugeschnitten sind. Eine weitere Möglichkeit, sich in OWL einzuarbeiten, besteht darin, den Quellcode zu durchforsten und durch Experimentieren zu lernen – doch dies garantiert nicht immer ein tiefes Verständnis des Frameworks.

Mit der Einführung von Odoo 16 wurde OWL 2 veröffentlicht, das sich deutlich von OWL 1 abgrenzt. Ab Odoo 17 empfehlen wir dringend, mit OWL zu arbeiten, da der offizielle Quellcode ab dieser Version ausgereifter ist und viele grundlegende Funktionsweisen verbessert wurden. Zudem gilt OWL 1 allmählich als veraltet. Mehr über die Entwicklungsgeschichte von OWL erfahren Sie in einem begleitenden Podcast.

In diesem Blogbeitrag möchten wir dir einen ersten Einblick in die Entwicklung mit OWL in Odoo 17 geben und dir anschließend in einem praktischen Beispiel zeigen wie du deine eigenen OWL-Entwicklungsprojekte effizient und eigenständig umsetzen kannst.

Anatomie eines OWL Moduls

Damit Odoo das eigene Modul als OWL relevant betrachtet, müssen mindestens die folgenden drei Bedingungen erfüllt sein.

1. Die Ordnerstruktur muss so sein, wie OWL sie erwartet

2. OWL Dateien müssen im Manifest im korrekten Bundle verwiesen werden

3. OWL Dateien muss syntaktisch und Inhaltlich korrekt geschrieben sein

Die Komplexität und Struktur des am Ende resultierenden Moduls variiert je nachdem, wo und was umgesetzt werden soll. An welcher Stelle und auf welcher Ebene findet die Anpassung statt? Soll der relevante Bereich in seiner Darstellung angepasst, um einen neuen Teil erweitert, oder sogar ein Teil existierender OWL Funktionsweise geändert werden?

Diese Fragen helfen angehenden OWL Entwicklern bei der Konzeptionsphase ihrer Entwicklung.

Anstatt eine Menge an Beispielen zu zeigen, wollen wir dir eine Heuristik mitgeben, damit du schneller eigenständig Erfahrungen sammeln kannst. Kurz gesagt hilft es, Fehler bei der Modulstruktur vorzubeugen, indem nach dem Prinzip “Gleiches mit Gleichem” gearbeitet wird. Das heißt, dass im Quellcode ein Beispiel gefunden wird und nicht nur der Code kopiert werden soll, sondern der Pfad zur Datei und deren Einbindung in das Modul-Manifest ebenso wichtig sind.

Praxisbeispiel Odoo OWL: Passwort-Qualität

Ein gutes Beispiel ist das Modul “Password Policy” (technischer Name: auth_password_policy) und “Password Policy support for Signup” (technischer Name: auth_password_policy_signup und auth_password_policy_portal).

Das Modul “Password Policy” führt eine Erweiterung ein, welche die Komplexität einer Eingabe ermittelt und bewertet, wie sicher ein Passwort ist. Die Passwort-Qualität wird als Balken dargestellt und im Backend beim Wechseln des Passworts verwendet.

Das Modul “Password Policy support for Signup” erweitern die Anpassung aus “Password Policy” und übernehmen sie z.B. im Portal, damit auch Portal-Benutzer sehen, wie sicher das neu eingegebene Passwort ist.

Die Erweiterung des Moduls "Password Policy"​
Die Erweiterung des Moduls "Password Policy"

Anpassung im Styling

Angenommen, du möchtest die Zugänglichkeit verbessern, indem dieser Balken länger sein und unterhalb der Textzeile angezeigt werden soll, anstatt in der Zeile neben dem Passwort. Diese Anpassung kann man mit SCSS umsetzen, worauf wir in diesem Abschnitt eingehen werden.

Wir erstellen zunächst ein neues Modul und passen das Manifest so an, dass es auth_password_policy_portal erweitert. Links ist das neue Modul, rechts ist das Manifest vom Ursprungsmodul, welches wir gesäubert haben. Wichtig sind die Abhängigkeiten (depends) und Assets:

Modulerstellung für die gewünschte Anpassung

Nun fehlt uns noch die zu ladende SCSS-Datei, also erzeugen wir sie nach derselben Ordnerstruktur, wie im Ursprungsmodul, um die Codequalität aufrechtzuerhalten.

Erzeugung der SCSS Datei​
Erzeugung der SCSS-Datei

Nun können wir mit der Anpassung beginnen und in unsere portal_policy.scss Datei folgenden Inhalt schreiben:

meter.o_password_meter {
position: unset;
width: 100%;
}

Fertig! Um das Ergebnis im Portal zu sehen und testen zu können, müssen wir den Server neu starten, die Modulliste aktualisieren und unser Modul installieren.

Der Zwischenstand mit der SCSS Datei aus unserem Modul sieht wie folgt aus:

Der Zwischenstand des Moduls nach Anpassung mit SCSS​
Der Zwischenstand des Moduls nach Anpassung mit SCSS

Anpassung in der Struktur

Neben der zuvor gezeigten Anpassung wollen wir dem Nutzer helfen, ein noch besseres Passwort zu wählen, indem wir einen Text mit Tipps anzeigen. Das kann nicht mit SCSS erledigt werden und eine Anpassung der Logik wäre auch nicht zielführend. In diesem Fall müssen wir mit einer XML-Datei die Ansicht erweitern. Wir haben schon ein Modul erstellt und verwenden es weiter, indem wir die gewünschte Information als Text ergänzen. Dafür müssen wir herausfinden, in welcher Ansicht des Portals der Balken platziert wird. Indem wir die Module nach ihren Dateien untersuchen, finden wir im Modul “auth_password_policy_portal”, unter views/templates.xml wie der in OWL definierte Balken im Portal angezeigt wird:

Anzeige des Balkens für die Passwortstärke in OWL​
Anzeige des Balkens für die Passwortstärke in OWL

Wir kopieren nun den gesamten Pfad samt Ordnerstruktur und XML-Dateinamen, um die Struktur in unserem Modul zu übernehmen. Anschließend vererben wir die Ansicht aus “auth_password_policy_portal”, um unseren Text unterhalb des “owl-component” Elements zu platzieren.

Übernahme der Anzeige in das neu erstellte Modul​
Übernahme der Anzeige in das neu erstellte Modul

Zusätzlich benötigen wir noch eine Übersetzung ins Deutsche, exportieren also die Sprache, fügen eine i18n/de.po Datei hinzu und schreiben eine deutsche Version des Textes. Englisch als Grundsprache zu verwenden ist nicht notwendig, aber empfohlen, um die Codequalität einheitlich und sauber zu halten.

Der letzte Schritt ist, das Manifest unseres Moduls anzupassen, um unsere views/templates.xml Datei für Odoo sichtbar zu machen. Nach der von uns eingeführten Heuristik “Gleiches mit Gleichem” wird deutlich, dass diese Datei über ein “data”-Attribut im Manifest hinterlegt wird, nicht über ein “assets”-Attribut, wie die SCSS Datei. Das Ergebnis sollte den von uns eingepflegten deutschen Text zeigen.

Der Zwischenstand des Moduls nach Anpassung mit XML​
Der Zwischenstand des Moduls nach Anpassung mit XML

Anpassung in JavaScript

Je näher wir uns zur Funktionsweise hinbewegen, desto klarer wird, dass eine Anpassung in JavaScript der einzig sinnvolle Weg ist, denn Nutzer interagieren mit Odoo über den Browser, welcher dank OWL mit Python und anschließend mit der Datenbank kommuniziert. Nicht jede Funktionalität im Browser benötigt eine Reaktion in der Datenbank, viele Interaktionen zwischen Odoo-Nutzern und Odoo finden auf der schon geladenen Seite statt.

Während es bei der Erweiterung von SCSS und XML nur einen sauberen Weg gab, existiert beim JavaScript von OWL eine deutliche Lernkurve. Grund hierfür ist, dass JavaScript in OWL von OWL 1 zu OWL 2 radikal verändert wurde, sodass es mehrdeutige Beispiele im Quellcode gibt. Die Heuristik “Gleiches mit Gleichem” greift hier am schwächsten, da JavaScript komplexer ist, als SCSS und XML Anpassungen zusammengenommen. OWL Entwickler können sich durch einen Patch in eine existierende Funktionalität reinhängen und diese erweitern, ganze Komponenten erstellen, die allein für sich stehen, oder existierende OWL Komponenten vererben.

Um auf unser Beispiel zurückzukommen, richten wir den Blick auf die Komponente “Meter” in der Datei password_meter.js. 

Anpassung des Moduls mit JavaScript​
Anpassung des Moduls mit JavaScript

Die Klasse  “Meter” definiert eine Komponente, welche einen Beschreibungstext ausgibt, wenn der Mauszeiger über den Balken gehalten wird. Zusätzlich wird mit jedem eingegebenen Buchstaben der Sicherheitswert des Passworts berechnet. Diese beiden Eigenschaften werden an die XML-Vorlage (Meter.template) übergeben und dem Nutzer präsentiert.

Unser Beispiel-Ziel für diesen Blog ist es, das Passwort in der Konsole des Browsers auszugeben. Das aktuell eingegebene Passwort ist nämlich nutzerseitig verdeckt, also müssen wir zur Laufzeit in die innere Funktionsweise der Meter-Komponente eingreifen.

Der Schwerpunkt unseres Beispiels liegt nicht nur darin, diese Information auszugeben, sondern zeigt, wie ein Patch in OWL 2 aussieht.

Wir kopieren erneut den Pfad und Namen der Datei, verweisen darauf im Manifest, aber damit Odoo unsere Patch-Funktionalität erkennt, muss die erste Zeile unserer JavaScript Datei mit /** @odoo_module **/ beginnen.

Nun importieren wir die Meter-Komponente und OWLs Patch-Funktionalität. Die dafür verwendete Syntax lässt sich verallgemeinern zu:

 “@ + [Modul-Name] + / + [Dateiname ohne .js-Endung]”

Generell erweitert man den Prototyp einer Klasse, damit alle Instanzen das Verhalten aufweisen. 

Schreibt man also patch(Meter.prototype, {});  statt patch(Meter, {}); umgeht man eine zukünftige Fehlerquelle. Innerhalb der geschweiften Klammern haben wir Zugriff auf sämtliche Methoden der Komponente, ohne eine eigene Komponente erstellt zu haben.

Die fertige JavaScript Datei in unserem Modul sieht folgendermaßen aus:

Die fertige JavaScript Datei​
Die fertige JavaScript-Datei

Für unser Beispiel wissen wir, dass der Getter value() den Wert für die Sicherheit des eingegebenen Passworts berechnet. Wir wissen auch, dass dieser Wert mit jedem eingegebenen Zeichen neu berechnet wird und können darauf schließen, dass in diesem Getter eine gute Stelle ist, um das Passwort in der Konsole auszugeben. Ähnlich zum Erweitern der Methoden innerhalb von Python-Dateien verwendet OWL ebenfalls die Syntax des Aufrufs einer Super-Methode, deren Wert abgefangen, geändert und weitergegeben wird. In Zeile 8 geben wir daher das Passwort in der Browser-Konsole aus und in Zeile 9 geben wir den von der Meter-Komponente berechneten Wert für das Passwort weiter. 

Fazit

In diesem Blog haben wir anhand von Beispielen gelernt, wie ein Modul für OWL Entwicklung strukturiert werden kann, damit so schnell wie möglich ein funktionsfähiges Proof-of-Concept für nötige Anpassungen erstellt werden kann - ganz ohne sich in Ordnerstruktur, korrekte Imports oder Datei-Definitionen zu verlieren. Die von uns gemachte Beispiel-Anpassung in SCSS, XML und JavaScript zielt nicht nur darauf ab, dein Interesse für das OWL Framework zu wecken, sondern auch auf mögliche Fehlerquellen hinzuweisen und zu vermitteln, wie auch du selbstständig Odoo OWL meistern kannst. 

Wenn du zu diesem Thema weitere Fragen hast oder Unterstützung bei der Entwicklung mit OWL benötigst, kontaktier uns gern jederzeit!


 
Odoo 17 Lager
Einfügen