Contao-News

Wir informieren Dich hier regelmäßig zu Updates, stellen Best-Practice-Arbeiten vor und berichten über Aktuelles aus dem Contaoversum.

Rückblick auf das zweite Core-Entwicklertreffen 2018

von Yanick Witschi – Aktuelles

Jedes Jahr trifft sich das Contao Core-Entwicklerteam zwei Mal für einen kurzen Code-Sprint von drei Tagen. Da im Moment vier Entwickler aus der Schweiz kommen, findet das Treffen jeweils ein bisschen ausserhalb von Zürich statt. Die Treffen werden von der Contao Association getragen und sind für uns sehr wichtig. Mitglied werden und uns somit unterstützen kann man hier.

Ich habe mir vorgenommen, jeweils nach einem solchen Treffen die wichtigsten Informationen zusammenzutragen und so mit der gesamten Community zu teilen. Dieses Mal haben uns folgende Themen beschäftigt:

Ökosystem

Zu Contao 3.5-Zeiten bestand Contao primär nur aus der Software Contao. Mittlerweile müssen wir uns aber nicht mehr nur um Contao selbst kümmern, sondern auch um dessen Ökosystem. Wir haben einen separaten Contao Manager, dessen Suchindex, die Composer Cloud und einige Bots, die uns Arbeit abnehmen, wie z.B. wiederkehrende Aufgaben bei einem neuen Contao-Release. Von Zeit zu Zeit ist es deshalb auch wichtig, dass wir an diesen Tools arbeiten.

Monorepository

Ein Problem, das wir seit Contao 4 haben, sind die verschiedenen Bundles in den verschiedenen Repositories. Für Nutzer scheint es oftmals schwierig, das korrekte Repository für Fehlermeldungen bzw. Feature-Wünsche zu finden.

Für Entwickler ist es noch schwieriger, weil Änderungen an mehreren Bundles (z.B. Core und News) das Arbeiten über mehrere Repositories erfordern. Und der Maintainer, also Leo, muss für neue Releases alle Repositories synchron halten. Wir planen deshalb über kurz oder lang den Umstieg auf ein sogenanntes Monorepository.

Ein Monorepository (kurz Monorepo) hätte den grossen Vorteil, dass wir alle unsere Bundles in einem Repository pflegen könnten. Die Issues wären zentral und Code-Änderungen können problemlos über mehrere Bundles stattfinden. Releases werden ebenfalls einfacher, weil sie nur noch in dem Monorepo stattfinden würden.

Das hat alles keinen Einfluss darauf, wie die Bundles dann installierbar sind. Durch sogenannte Subtree-Splits würde das Monorepo automatisiert wieder auf die jetzt vorhandenen Bundles (core-bundle, news-bundle etc.) aufgeteilt werden.

Es gibt jede Menge Informationen zu Monorepos im Netz und etliche Erfolgsgeschichten. Auch Symfony selbst nutzt übrigens ein Monorepo und es funktioniert hervorragend.

Martin hat sich intensiv damit beschäftigt wie Git funktioniert und wie wir unsere – jetzt noch standalone Pakete – zuerst in ein Monorepo mergen und anschließend wieder splitten können, ohne dabei die History zu verlieren. Das ist ziemlich schwierig aber es scheint auch möglich. Also falls ihr mal für ein Projekt einen Git-Experten braucht – wir haben jetzt einen!

Package Indexer

Zu unserem Ökosystem gehört natürlich auch der Contao Manager und seit der vergangenen Konferenz auch die Composer Cloud und der sog. "Package Indexer". Der Package Indexer ist dafür verantwortlich, die Contao Bundles und alten 3.5 Module auf Packagist zu suchen, sie mit unseren Übersetungen und Logos anzureichern und im Suchindex des Contao Managers abzulegen.

In der jüngsten Vergangenheit hat der Package Indexer für einige Probleme gesorgt, so dass es höchste Zeit war, diesen komplett neu zu entwickeln. Das war eine meiner Aufgaben. Die neue Version sollte nun deutlich stabiler laufen und indexiert neu auch Pakete vom Typ "contao-component". Im Hinblick auf Contao 4.6 ein wichtiger Schritt, weil dadurch wird es z.B. möglich zwischen verschiedenen jQuery-Versionen zu wechseln, indem jeweils die gewünschte Version des Pakets "contao-components/jquery" installiert wird.

Code-Qualität

Wir haben im Moment alleine beim Core-Bundle eine Test-Coverage von 97% und über 1300 automatisierte Tests, die bei jedem Commit durchlaufen.

Wir testen unseren Code gegen die jeweils neusten Versionen sowie die jeweils ältesten Versionen aller abhängigen Pakete und das für alle unterstützten PHP-Versionen plus sogar den Nightly-Build (also das was in absehbarer Zeit PHP 7.3 werden wird). Vor knapp einem Monat haben wir dadurch z.B. einen Bug in eben diesem Nightly-Build gefunden und konnten so dazu beitragen, dass ein Fehler in PHP 7.3 behoben wurde, bevor er jemals einen unserer User betroffen hätte.

Seit kurzer Zeit lassen wir unseren Code zusätzlich noch durch PHPStan analysieren. PHPStan führt eine statische Code-Analyse (also eine Reihe an formalen Checks am Code noch bevor dieser ausgeführt wird) durch und macht uns so auf Probleme aufmerksam. David hat uns von Level 1 erst auf Level 2 und dann sogar Level 3 gebracht und so einige unscheinbare Fehler in unserem Code beheben können.

Die Code-Qualität von Contao 4 ist grossartig und sie wird stetig besser. Das soll kein Selbstlob sein, es ist einfach eine Tasache und darauf dürfen wir stolz sein!

OAuth

Die Umstellung auf Symfony Security in Contao 4.5 war einer der grössten Pull Requests in der Geschichte von Contao. In Contao 4.6 konnten wir dadurch Zweifaktor-Authentifizierung (vorerst nur für die Backend-User) realisieren und natürlich eröffnet uns das jede Menge neuer Möglichkeiten.

Jim hat sich mit der OAuth-Integration beschäftigt. Es würde uns ermöglichen, Logins via Facebook, GitHub, Twitter, Google etc. zu erlauben. Aber wie immer bei Authentifizierung (und Authorisierung) klingt die technische Implementierung einfacher als es ist. Es soll auf jeden Fall so sein, dass es sowohl für das Backend als auch das Frontend funktioniert. Wir werden sehen wohin uns das bringt.

Routing

Das Routing beschreibt den Prozess wie ein Request auf den passenden Inhalt gemappt wird. In Contao also wie eine URL auf die korrekte Seite im Seitenbaum zeigt (und umgekehrt, also wie man auf Basis eines Seitenobjekts die dazugehörige URL erhält). Ein solches "Mapping" bezeichnen wir als "Route". Das Problem beim Routing ist, dass wir sowohl dynamische Routen aus der Datenbank (also das was ihr im Backend im Seitenbaum anlegt) als auch statische Routen ("/contao", "/contao/login" etc.) haben.

Im Moment laufen die statischen Routen über den Symfony Router (der ist übrigens der schnellste in der PHP-Welt) und alles was in der Datenbank steht wird immer noch wie eh und je gehandhabt. Unser aktuelles Routing funktioniert natürlich, ist aber halt über die Zeit gewachsen, nicht wirklich optimiert und nicht automatisiert testbar. Ausserdem – und das ist ziemlich wichtig – findet es zurzeit zu spät im Prozessablauf statt, um weitere Optimierungen anbringen zu können. Eine solche wäre z.B. die Session-Cookies auf "secure" zu stellen (womit sie nur über https aber niemals über http gültig wären). Das ist derzeit nicht möglich, weil wir zum Zeitpunkt zu dem die Session gestartet wird, noch nicht wissen ob wir uns innerhalb eines Webseite-Roots von Contao befinden, für den der Administrator das Häkchen bei "HTTPS" gesetzt hat.

Natürlich ist das nur ein Beispiel von einigen Optimierungen, die durch die Umstellung auf Symfony Routing möglich würden. Nur ist das Problem, dass Symfony gar keine dynamische Routen unterstützt. Symfony ist ein Framework für PHP-Applikationen und verfügt über keine CMS-spezifischen Features, wie es eben dynamische Routen aus einer Datenbank sind.

Aber es gibt natürlich viele andere Projekte und so kommt es, dass Andy sich um die Einbindung des Symfony CMF Routers gekümmert hat. Dieser kennt einen "ChainRouter" womit mehrere Router in Reihe geschaltet werden können. So können wir einen Router für statische Routen und einen Router für dynamische Routen kombinieren. Daneben hat sich Andy auch mit der Umstellung unseres eigenen Routingsystems auf den "DynamicRouter" des Symfony CMF beschäftigt, welche uns die genannten Optimierungen erlauben würden.

API

Im Juni hatte Leo in einer News darum gebeten, dass ihr eure API Use Cases in einem GitHub-Ticket dokumentiert. Die API generell hat für viel Diskussionsstoff am Treffen gesorgt. Jeder will eine haben aber keiner weiss, wie sie aussehen soll. Positiv ausgedrückt ist das also Folgendes: eine Herausforderung.

Wie wir eben im Abschnitt zum Routing gelernt haben, kann jeder Entwickler beliebige Routen am System registrieren. Es ist von daher seit Contao 4.0 absolut kein Problem sowas wie eine "/api/gib-mir-alle-news" Route zu registrieren und da dann die News im gewünschten Format zurückzugeben. Aber klar, jeder kocht sein eigenes Süppchen und viele unserer Entwickler sehen Contao nicht nur als CMS sondern auch als Framework und wünschen sich eine Art Grundstein auf dem man aufsetzen kann bzw. ein Raster an das man sich halten kann.

Das Thema ist also ein Elefant und seine Grösse ist undefiniert. Aber wie ihr vielleicht wisst verspeist man einen Elefanten Stück für Stück. Also müssen wir einfach irgendwo mal beginnen und schauen in welche Richtung es sich entwickelt.

Im verlinkten Ticket habe ich ein paar Informationen festgehalten und ich habe bereits ein sehr einfaches Proof-Of-Concept gebaut, das ich sicher weiterverfolgen werde. Es läuft unter dem Codenamen "Capi" für "Contao API". Leo ist noch nicht vom Kürzel überzeugt, was denkt ihr?

Reverse Proxy (aka HttpCache oder Servercache)

Der Servercache beschäftigt uns seit mittlerweile nunmehr vier Contao-Versionen. Manchmal leider mit Bugs aber immer mehr auch mit wahnsinnig tollen Features. Als Entwickler der meisten dieser Features bin ich da bestimmt auch ein bisschen voreingenommen, aber das neue Cache-Tagging-Feature in Contao 4.6 eröffnet uns ganz neue Möglichkeiten.

Sobald Contao 4.6.0 erschienen ist, versucht doch einmal bei den Servercache-Einstellungen der Seite, auf der ihr den News-Reader platziert habt, die Cache-Zeit auf "1 Jahr" einzustellen. Ja richtig, die ganze Seite soll ein Jahr bei uns auf dem Server im Cache liegen, so dass Contao nicht mal hochgefahren werden muss, wenn ein Besucher "https://domain.de/news/super-eintrag.html" aufruft. Keine Datenbankabfragen sondern einfach nur eine superschnelle Antwort des Servers.

Danach editiert ihr diese News, egal ob ein Inhaltselement oder z.B. den Teaser oder die Uhrzeit davon und besucht die Seite erneut. Tadaaa: Der Seiteninhalt ist aktuell! Der Cache-Eintrag wurde automatisch invalidiert. Ihr müsst nicht mehr zuerst in die Systemwartung und den Servercache leeren, das macht jetzt Contao vollautomatisch für euch und zwar nur für die betroffenen Seiten, nicht für den gesamten Cache.

Funktionieren tut das über sogenanntes Cache-Tagging, d.h. wenn die Antwort zum ersten Mal generiert und schliesslich im Cache abgelegt wird, wird dieser Eintrag mit Tags ausgezeichnet. Also unsere Seite "https://domain.de/news/super-eintrag.html", welche unseren News-Eintrag mit ID 42 anzeigt, bekommt z.B. den Tag "contao.db.tl_news.42". Und sie bekommt auch z.B. den Tag "contao.db.tl_content.12", weil das Inhaltselement mit ID 12 benutzt wurde.

Editiert ihr nun z.B. das Inhaltselement ID 12, werden alle Cache-Einträge mit "contao.db.tl_content.12" invalidiert. Folglich auch der Cache-Eintrag für "https://domain.de/news/super-eintrag.html".

Für dieses Feature mussten wir noch einige Dinge (hier, hier und hier) fixen bzw. nachrüsten.

Diverses

Natürlich gibt es neben den grösseren Dingen, die ich hier einzeln aufgeführt habe, auch immer noch kleinere aber nicht weniger wichtige Verbesserungen. Hier ein Auszug davon:

  • Wir haben dank Martin eine verbesserte Suche. Sie versteht jetzt auch Sprachen bei denen Wörter nicht durch das bei uns übliche Leerzeichen getrennt sind (wie bspw. Katakana, die Silbenschrift der japanischen Sprache).

  • Ebenfalls hat Martin einen Pull Request bei Imagine gemacht (der Bibliothek die wir zur Generierung von Vorschaubildern nutzen), um JPEG-Samplingfaktoren konfigurieren zu können. Sollte das akzeptiert werden, könnten wir vielleicht schon bald noch kleinere (bezogen auf die Datenmenge) JPEG-Vorschaubilder generieren lassen.

  • Jim hat ein Symfony Flex "Recipe" für Contao erstellt, das die Installation von Contao ohne Managed Edition vereinfachen wird. Ausserdem hat er die Dokumentation des Core-Bundles dafür aktualisiert.

  • Meine Wenigkeit (mit CSS-Hilfe von Martin, weil ich kann's einfach nicht) hat unserer Frontend-Vorschau ein Upgrade verpasst, so dass man in Zukunft sieht, auf welcher Seite man sich eigentlich befindet.

So, viel ausführlicher kann ich drei Tage nicht zusammenfassen. Jetzt brauche ich auf jeden Fall mal eine runde Schlaf.

Ich finde, das Treffen war wieder sehr erfolgreich und mir hat's auf jeden Fall viel Spass gemacht. Das nächste findet voraussichtlich im Februar 2019 statt.

Aber vorher sehen wir uns alle auf dem Contao Camp am 3. und 4. November in Leipzig!

– Yanick

Alle News anzeigen

Kommentare

Kommentar von chris |

Vielen Dank für die Zusammenfassung! Sicherlich sehr viel Arbeit aber auch sehr spannend zu lesen. Bitte wiederholen! :)

Kommentar von werner |

1.000 Dank für die Infos, und natürlich auch für Deinen/euren Einsatz!!!

Kommentar von Thorsten Neuhaus |

Herzlichen Dank für euren Einsatz und die Dokumentation von dem Treffen. Sehr informativ und verständlich beschrieben!

Kommentar von David Bopp |

Vielen Dank für den ausführlichen Bericht und die viele gute Arbeit!

Als Name für die API schlage ich API-C vor (ausgesprochen: "epic").

Kommentar von Alexander von Bressensdorf |

Auch von mir ein dickes Danke für Eure ganze tolle Arbeit

Kommentar von Glen Langer |

Das waren ja recht effizente und erfolgreiche Tage, Wow!
CAPI: Erinnert mich an "Common ISDN Application Programming Interface". Daher wäre ein andere Name/Kürzel bestimmt sinnvoller.

Kommentar von zonky |

Super Arbeit! & herzlichen Dank für die ausführliche Beschreibung der Arbeiten!

Kommentar von Ralph Leyendecker |

Top Arbeit! Vielen vielen Dank für Euren Einsatz!

Kommentar von Christian |

Vielen Dank für den ausführlichen Bericht und eure Arbeit.
CAPI finde ich wie Glen bemerkt hat ebenfalls nicht gut. Das führt sicher später bei der Google-Suche zu uneindeutigen Treffern. CTOAPI oder Contao-API ausgeschrieben?

Kommentar von Kim |

Vielen lieben Dank für euren Einsatz, da habt ihr's krachen lassen :)

Einen Kommentar schreiben

Bitte rechnen Sie 3 plus 5.