Willkommen zurück! Heute möchte ich euch mein neuestes Projekt vorstellen, die Coding Community. Wer zuerst einen Blick auf die fertige Seite werfen möchte, kann das hier machen. Ich habe das Ganze heute veröffentlicht, ihr könnt also unter den ersten sein, die sich registrieren! Im nun folgenden Beitrag möchte ich ein wenig auf die Entstehungsgeschichte und die umgesetzten Funktionen eingehen. Natürlich werde ich wie immer auch die Komponenten näher vorstellen, die ich für die Umsetzung aber auch das Deployment, also die Veröffentlichung der Seite, verwendet habe.
Als Bonus ist der Quellcode für dieses Projekt komplett Open Source unter der MIT Lizenz auf GitHub veröffentlicht. Den Link dazu findet ihr im Fußbereich der Coding Community.
Brainstorming
Am Anfang jedes Projekts steht natürlich die Ideenfindung. Auch in meinem Fall war das nicht anders. Wie ich in einigen Beiträgen hier bereits des Öfteren erwähnt habe, bilde ich mit seit über zwei Jahren auf Udemy fort. Das ist eine Plattform auf der jeder eigene Kurse veröffentlichen kann. Ich bin dort aber mit dem Ziel unterwegs, möglichst viel aktuelles Wissen über die moderne Webentwicklung aufzusaugen.
Natürlich mache ich mir zu jedem Kurs und damit jeder neu gelernten Technologie oder Programmiersprache meine Gedanken. Welches Projekt könnte ich damit umsetzen?
Über die Jahre hatte ich dabei viele verschiedene Ideen, die es aber nie wirklich in die finale Phase geschafft haben. Oft liegt es einfach daran, dass ich alles möglichst gleich beim ersten Versuch nahezu perfekt machen will. Sehr häufig habe ich mich dabei in der vorbereitenden Projektplanung verloren und es kam nie zum Start der Umsetzung.
Das war in dem hier vorgestellten Fall zum Glück anders, denn es hat mir sehr viel Spaß gemacht, das Ganze über meinen Weihnachtsurlaub in Angriff zu nehmen. Ich habe jede Menge während der Umsetzung gelernt.
Wie ich zu genau dieser Idee gekommen bin
Es war einer dieser Tage, an denen es draußen geregnet hat, und ich mich deswegen mal wieder einigen Stunden Videokursen gewidmet habe. In mehreren dieser Kurse priesen die Ersteller der Kurse ihre Communities an, die sie für die Kurse erstellt haben. Oft werden diese auf Basis von Discord umgesetzt.
Ich habe mir dann den Spaß gemacht, und mich dort angemeldet. Anfangs war ich voller Elan und wollte so vielen anderen Teilnehmern wie möglich bei ihren Problemen helfen. Leider ist dieser Elan schnell verflogen, nachdem sich herausgestellt hat, die Plattform Discord ist für die angedachte Art der Kommunikation einfach nicht geeignet.
Hier einige Gründe wieso ich zu diesem Schluss gekommen bin:
- Channels zu den einzelnen Themen/Kursen/Sprachen werden sehr schnell unübersichtlich
- Es gibt keine Möglichkeit sich auf eine vorhergehende Frage zu beziehen, somit musste ich immer über die Erwähnung des Benutzers gehen
- Es gibt keinen Code Editor, was für eine Community rund um verschiedenste Entwicklungsthemen für mich das größte Problem darstellte
Kurz danach fasste ich den Entschluss, aus persönlichem Interesse, eine Plattform zu schaffen, die für die genannten Probleme eine Abhilfe schaffen kann.
Eingesetzte Software/Frameworks
Bevor ich mit der eigentlichen Umsetzung der Seite begonnen habe, stand zunächst die Auswahl eines geeigneten Editors an. Bei dem was ich vorhatte, eines der wichtigsten Werkzeuge. Da ich beruflich bereits Erfahrung mit dem CKEditor hatte, war dieser in der engeren Auswahl. Mit Version 5 hat es einen großen Sprung gegeben. Deshalb wären mit Sicherheit alle Funktionen umzusetzen gewesen. Probleme bereitete mir allerdings die Lizenz GPL2, da ich meine Seite von Beginn an unter der MIT Lizenz veröffentlichen wollte.
Daher habe ich mich nach Alternativen umgesehen und bin relativ schnell bei Editor.js gelandet. Dieser bietet einen relativ neuen Ansatz im Gegensatz zu den alteingesessenen WYSIWYG-Editoren. Inhalte werden dabei nicht in ein einzelnes Feld eingegeben, sondern jede Art von Inhaltselement bekommt einen eigenen Block. Ein ähnliches Vorgehen bieten zum Beispiel auch die Editoren von Confluence oder auch diverser Newsletter Anbieter.
Im Standard gab es bereits Blockarten für Überschriften, Listen, Absätze, Bilder und sogar Tabellen. Im Fall von Editor.js lassen sich auch sehr einfach neue Arten von Inhaltselementen erstellen. Dies war in meinem Fall notwendig, da ich mit dem relativ einfach gehaltenen Code Block nicht zufrieden war.
Als nächstes beschäftigte mich also die Auswahl eines passenden Code Editors. Hier fiel meine Wahl nach kurzer Recherche auf Ace. Dieser wurde ursprünglich für Cloud9 entwickelt, einer Cloud IDE. Dieses Projekt wurde mittlerweile von Amazon AWS übernommen und in die eigenen Produkte integriert. Eine gute Basis also, um es in meiner Seite zu verwenden. Es werden sehr viele Programmiersprachen unterstützt und auch eine passable Auswahl an Themes für das Syntaxhighlighting ist vorhanden. Mithilfe der Dokumentation von Editor.js war es relativ einfach, diesen Codeeditor als eigenen Blocktyp hinzuzufügen. Er hat mir letztendlich so gut gefallen, dass er auch für die Darstellung des Codes auf der jeweiligen Inhaltsseite zum Einsatz kommt. Dabei verwende ich die umfassenden Konfigurationsparameter, um den Inhalt nur lesend anzuzeigen, und alle eingaberelevanten Bestandteile, wie Zeilenhervorhebung oder den Cursor, auszublenden.
Eine weitere, sehr interessante Funktion von Editor.js kommt beim Speichern der Inhalte zum tragen. Es wird nicht ein riesiges HTML-Konstrukt erzeugt, sondern die komplette Blockstruktur wird als JSON-Objekt zurückgegeben. Auf diese Weise, lassen sich sehr einfach nötige Filterungen auf bösartige Eingaben durchführen, und bei der Anzeige der einzelnen Blöcke hatte ich völlige Freiheit.
Das Backend
Da ich häufig in der Planungsphase früherer Projekte beim Backend hängen geblieben bin, dachte ich mir, bei diesem Projekt setze ich auf bereits bestehende Software. Wer den ersten Beitrag meines Blogs gelesen hat (“Willkommen auf Next Direction”, unten verlinkt), der weiß, dass der Teil “Direction” des Seitennamens, von Directus abgeleitet ist. Directus ist ein headless CMS System, mit dem ihr sehr schnell und einfach das komplette Backend konfigurieren könnt. Dazu zählen die verfügbaren Entitäten einer Seite, die Abhängigkeiten zwischen diesen und auch die Berechtigungen darauf. Am Ende bekommt ihr eine moderne REST API, die nahezu einen kompletten Funktionsumfang bietet. Was nicht im Standard möglich ist, lässt sich sehr einfach über sog. Hooks realisieren. Damit könnt ihr euch in die Abläufe des Backends einhängen und bestimmte Funktionalitäten ergänzen. Auch eigene Endpunkte wären möglich, diese habe ich bisher aber noch nicht benötigt.
Ich habe für meine Seite folgende Hooks implementiert, um teilweise fehlende Funktionen nachzurüsten:
- Während der Registrierung wird dem neuen Benutzer die Standardrolle “User” zugewiesen, und mir eine E-Mail für die Freischaltung des Kontos geschickt. Leider funktioniert die Zusendung eines Aktivierungslinks nicht, da bei der Annahme eine Fehlermeldung zu fehlenden Rechten erscheint. Es gibt aber bereits Pläne auf Seiten von Directus, öffentliche Registrierungen zu erlauben.
- Wenn ein neues Thema oder eine Antwort darauf erstellt wird, dann werden die Inhalte anhand einer Whitelist gefiltert. Dabei verwende ich das relativ junge Projekt html-sanitizer. Auch das musste ich um ein Plugin erweitern, da standardmäßig das
<mark>
Tag nicht erlaubt war, was von Editor.js aber für das Markieren von Text verwendet wird. - Aufgrund der sehr komplexen und damit fehlenden Konfigurationsmöglichkeit benötigte ich außerdem noch zwei Hooks für die Benutzer. Der Erste stellt sicher, dass über die öffentliche Abfrage der Benutzer lediglich deren ID und Benutzername geliefert werden. Der Zweite sorgt dafür, dass sich ein Benutzer nicht selbstständig eine andere Rolle zuweisen kann. Zweiteres sollte eigentlich über Directus möglich sein, die von mir gemachten Einstellungen haben aber nicht so gegriffen, wie ich mir das vorgestellt habe.
Wer mehr zu den Hooks wissen will, der kann sich den Fork von Directus im GitHub Account von Next Direction anschauen. Den Link dazu findet ihr im Fußbereich dieser Seite. Dort findet ihr diese im Verzeichnis public/extensions/custom/hooks
.
Während der Konfiguration der Entitäten, dem Einstellen der Rechte und der Entwicklung der Hooks, sind mir kleinere Fehler in Directus aufgefallen, die ich bereits per GitHub gemeldet habe. Für die ersten gibt es bereits auch Merge Requests, um die Probleme zu beheben. Ich bin während der Umsetzung meiner eigenen Seite ein großer Fan von Directus geworden. Es stehen dort auch viele spannende Entwicklungen an, wovon ich sicher das ein oder andere auch bei mir verwenden kann, um noch mehr Funktionsumfang anbieten zu können.
Das Frontend
Für das Frontend, worauf ich in diesem Projekt auch mein Hauptaugenmerk gelegt habe, ist Nuxt.js im Einsatz. Auch zu diesem, auf Vue.js basierenden Framework, habe ich bereits einen eigenen Beitrag geschrieben. Ich habe ihn auch am Ende dieses Beitrags entsprechend verlinkt.
Beide Frameworks wollte ich schon sehr lange in einem eigenen Projekt verwenden. Ich freue mich sehr, dass es nun endlich geklappt hat.
Durch die Verwendung von Nuxt, wird Vue nochmal auf eine andere Stufe gehoben. Die Verwendung von Funktionen wie Routing oder dem Store, sind damit nochmal um ein vielfaches einfacher, wodurch ich mich auf die wesentliche Entwicklung des Frontends konzentrieren konnte. Auch die serverseitige Erzeugung der Seiten wird bereits automatisch von Nuxt übernommen. Das wird später wichtig, wenn ich mich um die Optimierung für Suchmaschinen kümmere.
Während der Entwicklung habe ich viel neues dazugelernt, was häufig auch im Refactoring kompletter Seiten endete, nachdem die Funktionalität jeweils abgeschlossen war.
Hier ein paar Kennzahlen zum Frontend:
- Aktuell gibt es neun, per Routen erreichbare Seiten, wobei drei davon für die rechtlich notwendigen Informationen zuständig sind
- Es gibt einen zentralen Store für Informationen wie den eingeloggten Benutzer, oder die verfügbaren Kategorien
- Für die Darstellung und die Bearbeitung eines Beitrags inklusive dessen Antworten gibt es ein separates Store Modul
- Vier Plugins und eine Middleware reichten aus um die gewünschten Funktionen umzusetzen
- 36 weitere Vue Komponenten wurden entwickelt, aufgeteilt in Inhalt, funktional, Layout und UI-Elemente
Während der kompletten Umsetzung waren die Dokumentationen von Vue und Nuxt meine stetig zuverlässigen Begleiter. Mit zunehmender Dauer des Projekts, wurde ein Blick hinein aber immer weniger notwendig.
Funktionen
Kommen wir als nächstes zu den Funktionen, die in der ersten Umsetzungsphase enthalten sind:
- Neue Benutzer können sich registrieren und nach Freischaltung per JSON Web Token (JWT) anmelden
- Da ein Token nur 15 Minuten gültig ist, wird es während der aktiven Sitzung regelmäßig vor Ablauf automatisch im Hintergrund erneuert
- Ein Benutzer kann sein Profil einsehen und dort das Benutzerbild oder das Passwort ändern
- Über das Profil ist es ebenso möglich, seine letzten Beiträge oder Antworten einzusehen
- Angemeldete Benutzer können neue Beiträge erstellen oder auf bereits bestehende antworten
- Beiträge werden in vorgegebenen Kategorien erstellt, bekommen einen Titel und Inhalt, und können mit Tags versehen werden
- Antworten zu bestehenden Beiträgen können verfasst werden
- Sowohl Beiträge als auch Antworten können jeweils positiv bzw. negativ bewertet werden, wobei die Meinung auch nachträglich geändert werden kann
- Fragen und Antworten können außerdem vom Ersteller beliebig lange bearbeitet werden
- Antworten, die den fragenden Benutzer zufriedenstellen, können als “akzeptiert” markiert werden, wobei nur eine Antwort so gekennzeichnet werden kann
- Eine einfache Suche nach Stichwörtern oder nach existierenden Tags hilft bei der Findung benötigter Informationen
- Alle Beiträge werden übersichtlich entweder auf der Startseite oder innerhalb der einzelnen Kategorieseiten angezeigt
- Auf der Startseite werden alle Beiträge absteigend nach Erstelldatum angezeigt, während innerhalb der Kategorien Ankündigungen immer ganz oben zu finden sind
Wem das noch nicht ausreicht, der sollte direkt weiter lesen, denn im letzten Abschnitt dieses Beitrags, werde ich auf einige noch geplante Funktionen zu sprechen kommen.
Deployment
Der letzte Schritt auf dem Weg zur Coding Community war das Deployment der Anwendungen. Directus habe ich dabei auf meinem bestehenden Server mit Nginx und MySQL installiert. Die Anleitung zur Installation ist sehr kurz gehalten, reicht aber aus, um die nötigen Schritte durchführen zu können:
- Klonen des Repositories
- Anlegen der Datenbank und Importieren des mitgelieferten Dumps
- Anlegen der Projektkonfiguration
Mit einer Installation lassen sich auch mehrere Projekte verwalten. Das Ganze habe ich bereits erfolgreich in einer lokalen Installation getestet. Bei Bedarf können die Projekte auch als “privat” erstellt werden, dann werden sie nicht über den allgemeinen Endpunkt aufgelistet.
Für das Frontend auf Nuxt.js Basis habe ich meinen Dokku Server verwendet. Dabei handelt es sich um eine Open Source Alternative zu Heroku. Hier die Schritte, die damit notwendig sind, um eine Nuxt.js Anwendung zu veröffentlichen:
- Neue App in Dokku anlegen
- Umgebungsvariablen und Konfigurationsparameter setzen
- Dokku als zusätzlichen Remote im Git Repository hinzufügen
- Pushen des gewünschten Branches an Dokku
- Nach erfolgreicher Veröffentlichung kann per Letsencrypt noch SSL eingerichtet werden
- Optional können auch weitere Domains eingerichtet werden, unter denen die Seite erreichbar ist
Das war es auch schon. Beide Dienste laufen damit. Wenn ihr mehr über das Deployment wissen wollt, könnt ihr mich jederzeit kontaktieren.
Zusammenfassung und Zukunft
Ich hoffe, ich konnte euch mit diesem Beitrag einen kleinen Einblick in die spannende Entstehungsgeschichte der Coding Community von Next Direction geben. Obwohl ich dieses Projekt zum Lernen und auch zum Spaß erstellt habe, würde ich mich natürlich über eine rege Beteiligung freuen. Zu Beginn stehen erst einmal nur Kategorien zur Webentwicklung zur Verfügung, da ich hier die meiste Erfahrung anbieten kann. Es wäre wohl sehr frustrierend, wenn ihr eure Fragen stellt, und zu Beginn niemand da ist, der sie beantworten kann. Es ist aber nicht ausgeschlossen, sollten sich genügend Wissende finden, dass auch weitere Kategorien angeboten werden.
Zum Abschluss möchte ich noch ein paar Funktionen nennen, die bereits auf der Agenda für die Weiterentwicklung des Projekts zu finden sind. Einige davon auf meiner eigenen Liste, andere auch bereits als Issue auf GitHub.
- Kommentare zu Fragen und Antworten
- Erstellung von Ankündigungen über die Seite selbst, aktuell ist dies nur per nachträglicher Kennzeichnung im Backend möglich
- Entwürfe für jedermann, leider aktuell aufgrund eines Berechtigungsproblems auf Seiten von Directus noch nicht möglich, wodurch jeder angemeldete Benutzer alle Entwürfe sehen würde
- Im Hinblick auf Suchmaschinenoptimierung werden die URLs noch auf eine lesbare Form gebracht, anstatt IDs zu verwenden
- Permalinks zu einzelnen Antworten
- Während auf der Startseite aktuell maximal 200 Beiträge angezeigt werden, ist dieses Limit für Kategorieseiten nicht ausreichend, deshalb wird noch eine Seitennavigation integriert
Sollten euch weitere Funktionen einfallen, oder ihr Probleme bei der Benutzung bereits bestehender Möglichkeiten haben, könnt ihr mich jederzeit auf allen zur Verfügung stehenden Kanälen erreichen. Dazu zählen E-Mail, Slack, die Coding Community oder auch GitHub. Ich werde mich wie immer bemühen, so schnell es mir möglich ist, zu reagieren.
Nun will ich euch aber nicht länger aufhalten, und wünsche euch einen guten Start in das Jahr 2020!