Website Redesign

Posted by janto on Wednesday, June 5, 2019

Vielleicht habt ihr es schon mit bekommen: Wir haben vor kurzem unsere Website neugestaltet. ✨ Mit diesem Artikel möchten wir euch einen kleinen Einblick geben, was uns dabei wichtig war und wie wir das eine oder andere gelöst haben.

Wo wollen wir hin

Unsere Ziele für das Redesign waren:

  • Wir brauchen ein responsives Layout.
  • Wir wollen mehrere Sprachen unterstützen.
  • Die Seite soll statisch sein, also ohne serverseitigen Code auskommen.

Darüber hinaus war uns folgendes wichtig:

  • Es soll für jede im Team “möglichst einfach” sein, Änderungen an der Seite vorzunehmen, z.B. per Merge Request und am besten auch direkt im Browser.
  • Das Editieren selbst sollte ebenfalls relativ simpel sein: Gerne nur Markdown für Content (und YAML o.ä. für die Konfiguration, an der bestenfalls nur selten geschraubt werden muss).
  • D.h. kein HTML – auch nicht mit Preprocessors (obwohl Pug kurz im Gespräch war). Kein CMS zur Verwaltung und kein Framework für das Layout (ein bisschen haben wir hier getrickst und Shortcodes benutzt, aber dazu später mehr).
  • Das Deployment soll möglichst automatisiert ablaufen, ohne dass detailliertes Wissen über Interna / Infrastruktur nötig ist.
  • Und, na klar, soll das alles brauchbar dokumentiert sein.

Zudem stellten sich uns ein paar grundsätzliche Fragen: Wie gehen wir mit den anfallenden Daten um? Denn Statistiken darüber, wie unsere Seite genutzt wird, sind uns wichtig. Andererseits möchten wir eure verdiente Privatsphäre respektieren, auch wenn es um Social Media geht. An dieser Stelle aber nur ganz kurz dazu: Um eure Daten nicht über Dritte laufen zu lassen, haben wir uns in diesen Bereichen für Matomo und Embetty entschieden.

Soweit skizziert das schon ganz gut die Richtung, in die wir wollten. Gelandet sind wir letztendlich bei Hugo, einem Invoke Makefile, ein paar Docker Images und einer CI Pipeline.

Hugo mag vielleicht verwundern, wo wir Sphinx doch z.B. schon für Manual und Uberlab benutzen und generell recht Python-affin sind. Nun, auch wenn z.B. die Funktions-Syntax oder Templates für Pythonistas eher ungewohnt sein mögen, liefen erste Versuche richtig gut. Vieles — wahrscheinlich alles — wäre sicher auch mit Sphinx möglich gewesen; aber Aufbau, Modularität und Workflow haben einfach gleich ziemlich gut gepasst.

Von PoC zu MVP

Am Anfang stand bei uns ein kleines proof of concept (PoC), um unsere Entwicklungs­umgebung und Infrastruktur auszuloten. Die Idee dabei: Als Entwicklerin brauchst du nur git und docker auf deinem System, um loszulegen. Von da aus machten wir uns auf den Weg zu einem minimum viable product (MVP) welches die eingangs skizzierten Ziele erfüllt.

Das Repo besteht somit auch nur aus Content, Konfiguration und Dokumentation (wie zum Beispiel “wie arbeitest du mit Texten?”, “wie läuft das Deployment?” usw.). Das Hugo Binary kommt aus einem externen Docker Image. Die generieten HTML-Dateien und deren Assets schnappt sich ein weiteres Image und serviert sie letztenendes per Nginx.

Asset Pipeline

Das Theme (also CSS, Javascript, Komponenten, usw.) wurde als Git-Submodul in ein zweites Repo ausgelagert - für ein Hugo Setup ist das nicht ungewöhnlich und es erlaubt uns, das ganze Frontend-Geraffel wegzukapseln.

Wir haben uns mehrere Kandidaten aus der schnelllebigen Tooling-Landschaft angeschaut und uns für eine minimalistische Lösung mit Rollup und PostCSS entschieden. Auf einen Task-Runner haben wir verzichtet und nutzen stattdessen ein paar Einträge für yarn run… in der scripts Sektion unserer package.json Datei; lint, test, build, sowas halt …

Um unser Javascript kümmert sich Buble. Bei CSS haben wir uns auf custom properties und BEM Notation beschränkt, anstatt auf Sass oder Stylus Features wie Variablen und Mixins zurückzugreifen. Ein paar CSS Feature Previews nutzen wir jedoch per PostCSS - vor allem für media queries und custom selectors.

Docs or it didn’t happen

Alle nötigen Vorgänge sind dokumentiert und mit der Reduzierung auf standard­konformes JavaScript und CSS, sowie den Verzicht auf Frameworks und komplexes Tooling konnten wir recht zugänglich und flexibel bleiben.

Dennoch sind bereits einige Befehle für den Dev-Workflow zusammen gekommen. Um das Ganze gut automatisier- und reproduzierbar zu halten, haben wir eine Invoke-Makefile dazu gepackt. Diese liefert einen Überblick über die verfügbaren Tasks und die entsprechenden Hilfe-Texte. Zu Wahl stehen u.a. Theme Update, Dev-Server starten und natürlich die automatisierten Tests. Diese Tasks sind allerdings meist nur kleine Wrapper: Nimm Docker Image X und lass es mit diesen Parametern, Volume(s) und Environment-Variablen laufen.

So sind wir bei einem recht komfortablen Workflow von git clone, pipenv sync und pipenv run invoke task-x angekommen.

Designprozess

Nun, da unsere Entwicklungs­umgebung stand, war es Zeit, auf das Design zu schauen: Also Sketch und Zepplin anwerfen. Spannend war dabei, dass wir uns ja selbst darauf beschränkt haben, als Content-Input nur Markdown (ohne HTML) zu nehmen — unsere Designentwürfe für die verschiedenen Seiten sahen zum Teil aber schon recht unterschiedlich aus – und wir wollten möglichst wenig in den Templates feststampfen und auch keine strikte Seitenstruktur vorgeben. Daher einigten wir uns auf einige wenige, möglichst flexible Bausteine, die wir als Hugo Shortcodes umsetzten.

Responsiveness

Für Leute die Content schreiben sind vor allem zwei dieser Shortcodes wichtig: section und content. Beiden können auch (CSS-)Klassennamen mitgegeben werden. Der so gruppierte Markdown Content kann von unserem CSS recht flexibel an den jeweiligen Viewport angepasst werden.

Nur unter Schmerzen erinnere ich mich an Tabellen-Layouts mit zerstückelten Bilddateien und Float-Verrenkungen zurück. 😉 Heutzutage müssen wir in vielen Fällen nur per Media Query von display: flex auf display: grid umschalten oder ein paar Custom Properties für Abstände oder Grid-Areas anpassen. 😍

Mehr Automation wagen

Okay, wir sind fast am Ziel. Das Arbeiten an und mit der Seite erfordert allerdings noch immer eine lokale Entwicklungs­umgebung. Die Tools sind zwar alle in Docker Images verpackt und mit dem Invoke File “gewrapped” aber um mal schnell ein Komma zu setzen oder eine Übersetzung beizusteuern, ist das schon noch mehr Hussle als nötig.

Bisher fiel aus unser CI Pipeline nach audit, build und testing ein Image. Kurzum Netlify daran geknüpft und schon gibt’s für jeden Merge Request ein Preview. Das kann dann reviewed werden und ein Merge in den stable Branch sorgt dafür, dass auf die Produktionsserver ausgerollt wird — also zumindest ist das der Plan, aktuell rollt noch der master – aber #yolo.

Release Management

Und angekommen. Um auch die weitere Entwicklung nachvollziehbar zu dokumentieren, kommt noch ein weiteres Image dazu: Mit bumpversion zur Versionsverwaltung und reno für das Changelog.

Release

An dieser Stelle ein dickes Dankeschön an die Betatesterinnen und den Usercouncil, die uns auf der Reise begleitet haben. ❤️

Ein wirkliches Ende gibt’s bei solchen Projekten ja eigentlich nicht – und Ideen haben wir noch einige. Zunächst werden wir aber wieder auf eigene Infrastruktur umziehen und uns dann primär der Statusseite und dem neuen Dashboard widmen.