Alle Projekte

Content-Management

pacod-cms

Ein Stack, viele redaktionelle Websites — Artikel, Werbung und Statistiken, mit integrierter KI-Übersetzung.

pacod-cms ist ein Open-Source-Content-Management-System für redaktionelle Websites. Eine Installation hostet viele Sites, jede mit eigener Datenbank, eigenen Dateien und eigenem Cache; die Redaktion arbeitet in einem mehrsprachigen Studio, und die Leserschaft bekommt schnelle, nach Host geroutete öffentliche Sites.

  • Apache-2.0
  • Version 0.0.1
  • Vorschau

Funktionen

  • Redaktioneller Kern

    Artikel, Kategorien, Autoren, Tags und feste Seiten, mit einer gemeinsamen Bildbibliothek für die ganze Website.

  • Multi-Site von Grund auf

    Jede Website hat ihre eigene MongoDB-Datenbank, eigene Dateien und eigenen Cache und antwortet unter den Hosts, die sie beansprucht.

  • Werbung

    Werbebuchungen mit einem HTML5-Banner-Builder, dazu eine Link-in-Bio-Seite für Social-Media-Profile.

  • Statistiken

    Statistiken zu Leserschaft, Werbung und Crawlern, damit die Redaktion sieht, was gelesen und was gecrawlt wird.

  • Mehrsprachig

    Inhalte in vielen Sprachen mit konfigurierbarer Originalsprache; das Studio selbst auf Englisch, Bulgarisch, Deutsch und Russisch.

  • KI-Übersetzung

    Einen Artikel oder eine ganze Website als Job übersetzen; jede Antwort wird verworfen, wenn sie das Markup des Artikels nicht exakt beibehält.

  • Organisationen und Rollen

    Organisationen, Websites und Einladungen, mit Rollen pro Organisation und pro Website, verwaltet in pacod-id.

  • Konfigurierbare PDFs

    Artikel-PDFs als Hintergrund-Job, im Drucklayout der Website oder in einem zweispaltigen wissenschaftlichen Format, mit Abstract und Schlagwörtern aus dem Artikel oder von der KI geschrieben.

  • Zeitschriftenausgaben

    Artikel, zu einer Ausgabe gebündelt, ein PDF pro Sprache mit Titelseite, Editorial, Inhaltsverzeichnis und nummerierten Seiten, veröffentlicht im Archiv der Website.

Einordnung

Diagramm: wie die pacod-Projekte zusammenpassen LLM-Aufrufe Tippe auf ein Projekt, um zu sehen, womit es verbunden ist.

Ein Stack, viele Websites

pacod-cms betreibt viele Websites für viele Organisationen aus einem Stack. Jede Website hat ihre eigene MongoDB-Datenbank, ihren eigenen Dateiordner und ihre eigenen Cache-Einträge und antwortet unter den Hosts, die sie beansprucht. Wer sich registriert, kann eine Organisation anlegen, deren Admin werden, darin Websites erstellen und Personen zur Mitarbeit einladen; ein Plattform-Admin legt die Limits fest.

Das Design geht davon aus, dass der Inhaber einer Website allen anderen auf der Installation feindlich gesinnt sein könnte. Websites führen Skripte aus, die ihre Inhaber geschrieben haben — HTML5-Banner, Tag-Manager, Artikeltexte —, und die Plattform muss diese Skripte und diese Daten dort halten, wo sie hingehören.

Wie die Teile zusammenspielen

Teil Was es tut
pacod-cms-core Eine Bibliothek: Dokumente, Services, die Mandantenfähigkeit, die Control Plane, Seed-Inhalte, das Designmodell und eine Java-Portierung der Regel-Engine von pacod-id.
pacod-cms-site Die öffentliche Site für alle Websites zugleich: Seiten, schreibgeschütztes JSON unter /web/v1/**, Medien, Zugriffszähler.
pacod-cms-studio Das Studio: das Portal für Organisationen, Websites und Mitglieder, die Bearbeitungsansichten, Hintergrund-Jobs, KI.
Caddy Die Eingangstür, routet nach Host: den Host des Studios zum Studio, den von pacod-id zu pacod-id, jeden anderen Host zur Site.
Gotenberg Erzeugt die PDFs von Artikeln und Zeitschriftenausgaben aus den Druckansichten der Site.

Die beiden Anwendungen rufen einander nie auf. Beide greifen direkt auf MongoDB zu, sodass eine Änderung im Studio die öffentliche Site über die Datenbank erreicht; die Caches der Site laufen nach 60 Sekunden ab, statt geleert zu werden, sodass eine Änderung innerhalb einer Minute live ist.

Vom Host zur Seite

Jede Arbeitseinheit gehört zu genau einer Website, die für ihre Dauer gebunden ist.

  1. Caddy reicht die Anfrage an die Site weiter. In Produktion fordert Caddy das Zertifikat einer Website beim ersten Besuch an, aber erst, nachdem die Site bestätigt hat, dass der Host zu einer aktiven Website gehört.
  2. Die Site schlägt den Host in der Control Plane nach, bevor irgendetwas anderes läuft. Ein Host, den keine aktive Website beansprucht, bekommt ein schlichtes 404, nie eine Standard-Website.
  3. Ist die Website gebunden, geht jede MongoDB-Operation an deren Datenbank. Ist keine gebunden, wirft die Datenbankschicht einen Fehler, statt zu raten.
  4. Das Layout des Seitentyps — Regionen mit geordneten Sektionen — wird gegen das Template-Set der Website aufgelöst, und die Daten jeder Sektion werden vorab geladen. Templates fragen nie selbst ab; eine Sektion, deren Daten fehlschlagen, wird weggelassen und protokolliert, und die Seite wird trotzdem gerendert.

Im Studio ergibt sich die Website aus dem Pfad (/sites/<id>/mgmt/…); Hintergrundarbeit bindet die Website, für die sie läuft.

Wo die Daten liegen

Wo Was
pacod_cms Die Control Plane: Organisationen, Websites, Domains, Plattform-Einstellungen, die Job-Warteschlange.
site_<id> Eine Datenbank pro Website: Artikel, Seiten, Bilder, Banner, Menüs, Einstellungen, Layouts, Theme, Statistiken.
sites/<id>/ Die Dateien der Website: Artikelbilder, Banner-Motive, PDFs. Die PDFs einer Ausgabe im Entwurf liegen in einem privaten Ordner, den nur das Studio ausliefert.
pacod-id Personen, Sitzungen und Rollenzuweisungen. Das CMS speichert keine Konten.

Die Identität einer Website — Name, Logos, Kontaktdaten, Drittanbieter-IDs — steckt in den Daten, nicht im Markup. Eine Drittanbieter-ID wird nur gerendert, wenn sie gesetzt ist und das Format ihres Anbieters hat, sodass eine frische Website überhaupt kein Tracking lädt. Die Originalsprache der Inhalte einer Website ist der letzte Fallback für eine fehlende Übersetzung und der rechtlich maßgebliche Text.

Design ohne Code

Unter Gestaltung im Studio wählt jede Website ein Template-Set — editorial, ein Magazin mit einer Spalte neben dem Inhalt, oder minimal, eine ruhige Spalte — und stellt ein Layout pro Seitentyp zusammen: Startseite, Artikel, Rubrik, Neueste, feste Seite und Suche. Zu den Sektionen gehören Artikellisten (neueste, eine Rubrik oder die meistgelesenen), Rich Text, ein Call-to-Action, ein Suchfeld und die Social-Links. Ein Theme legt Farben mit Nachtmodus-Werten, Schriften und Breiten fest.

Ein Wechsel des Sets zeigt zuerst, was verloren ginge, und nichts wird entfernt: Sektionen, die das neue Set nicht darstellen kann, bleiben erhalten und kehren beim Zurückwechseln wieder. Layouts und Theme bleiben Entwürfe, bis jemand mit Veröffentlichungsrecht sie veröffentlicht. Die Vorschau zeigt Entwürfe unter der eigenen Adresse der Website, in Desktop-, Tablet- oder Telefonbreite, über ein signiertes Token mit 30 Minuten Gültigkeit, und zählt nichts.

Ein neues Template-Set ist Code, den ein Betreiber installiert, kein Upload: Ein Thymeleaf-Template kann alles, was die Site kann.

PDFs und Zeitschriftenausgaben

Langwierige Arbeit läuft im Studio als Job, jeweils für eine Organisation zur Zeit, mit Live-Log und Abbrechen-Knopf. Der PDF-Export ist ein solcher Job: Gotenberg erzeugt aus jedem Artikel ein PDF pro Sprache, in der er geschrieben ist, und der Artikel verlinkt sein PDF, sobald es existiert.

  • Zwei Formate. Standard ist die Druckansicht der Website. Wissenschaftlich ist ein Paper-Layout: ein Kopf über die volle Breite mit Titel, Autoren, Abstract und Schlagwörtern, danach der Text in zwei Spalten.
  • Zwei Arten der Erstellung. Nur Code nimmt Abstract und Schlagwörter aus der Beschreibung und den Tags des Artikels. Mit KI lässt pacod-gw für jeden Artikel und jede Sprache ein Abstract, Schlagwörter und einen kurzen Kolumnentitel schreiben. Der Text des Artikels wird nie verändert.
  • PDF-Einstellungen halten die Vorgaben jeder Website: Format und Art, Papier (A4, Letter oder A5) und Ränder, den Namen der Zeitschrift pro Sprache und ihre ISSN, einen Kolumnentitel und Seitenzahlen. Jeder Lauf kann ein anderes Format und eine andere Art wählen.

Eine Zeitschriftenausgabe bündelt Artikel zu einem PDF pro Sprache. Sie hat einen Jahrgang, eine Nummer und einen Monat, einen Titel und ein Editorial pro Sprache und ein optionales Titelbild; ihre Artikel werden einzeln ausgewählt oder aus ihrem Monat übernommen und dann geordnet. Beim Erzeugen entstehen eine Titelseite, das Editorial, ein Inhaltsverzeichnis mit Seitenzahlen und danach die Artikel, mit einem Lesezeichen pro Artikel und durchgehend nummerierten Seiten. Die PDFs einer Ausgabe im Entwurf werden nur aus dem Studio heruntergeladen. Wird sie veröffentlicht, erscheinen die Ausgabe und ihre PDFs auf der Website unter /issues und in ihrer Sitemap.

Sicherheitsmodell

Wer was darf

pacod-id besitzt Konten und Rollen. Tokens tragen keine Rollen: Das Studio folgt dem Feed der Rollenzuweisungen von pacod-id und entscheidet jede Berechtigung selbst anhand des Manifests des CMS (authz/cms.yaml). Die Rollen sind Plattform-Admin, Provisioner, Organisations-Admin, Website-Admin, Designer, Redakteur, Autor und Analyst, vergeben auf der Plattform, in einer Organisation oder auf einer Website. Ein Autor schreibt; ein Redakteur veröffentlicht auch.

  • Jeder Handler im Studio deklariert die Berechtigung, die er braucht; einer, der keine deklariert, wird abgewiesen. Keine Rolle ist implizit.
  • Hat der Feed von pacod-id eine Minute lang nicht geantwortet, antwortet das Studio mit 503, statt mit Rollen zu entscheiden, die womöglich entzogen wurden. Die öffentlichen Websites sind davon nicht betroffen.

Websites bleiben getrennt

  • Das Studio liegt auf einer anderen registrierbaren Domain als die Websites, sonst startet es nicht. Andernfalls könnte das Skript einer Website Cookies für das Studio setzen und dessen CSRF-Schutz aushebeln.
  • Das Studio liefert nie HTML oder Skripte einer Website aus. Entwurfs- und HTML5-Banner-Vorschauen werden vom eigenen Origin der Website eingebettet.
  • Gotenberg ist abgeschottet: Es erreicht nur die interne Adresse der Site und führt kein JavaScript aus.
  • Nur veröffentlichte Artikel erreichen Leser, auf jeder Route, in jeder Liste, jedem Feed, jeder Sitemap und jedem PDF. Eine Zeitschriftenausgabe im Entwurf ist nie öffentlich.

KI, die deine Schlüssel nicht anrührt

Jeder KI-Aufruf läuft über pacod-gw; das Studio hält nie den Schlüssel eines Anbieters. KI ist für neue Organisationen standardmäßig aus: Ein Plattform-Admin schaltet sie pro Organisation ein, und der Admin einer Website kann sie für die eigene Website abschalten.

  • Artikelübersetzung läuft als Job. Ein übersetzter Text muss das Markup seiner Quelle exakt beibehalten — nur alt, title, aria-label und placeholder dürfen sich ändern —, sonst wird er abgewiesen.
  • Website-Übersetzung umfasst feste Seiten, Rubriknamen, Menüs, die Link-Seite und, falls ausgewählt, Tags, ohne Änderungen zu überschreiben, die währenddessen gemacht wurden; höchstens 2.000 Aufrufe pro Lauf.
  • Schreibhilfe formuliert eine Auswahl auf sechs Arten um und schlägt eine Zusammenfassung und Tags vor.
  • Alt-Text pro Sprache schlägt ein Vision-Modell anhand des Bildes selbst vor.
  • Design-Assistent entwirft ein Theme oder ein Layout aus wenigen Worten und schreibt es nur in den Entwurf.
  • PDF-Vorspann: Für PDFs, die mit KI erstellt werden, ein Abstract, Schlagwörter und ein Kolumnentitel pro Artikel und Sprache, als reiner Text geprüft. Sie werden wiederverwendet, bis der Artikel bearbeitet wird.

Das Gateway sieht nur opake IDs, nie Namen oder E-Mail-Adressen.

Drei Umgebungen, ein Makefile

dev stage prod
Eingangstür HTTP, dazu HTTPS von Caddys lokaler CA HTTPS (Let's Encrypt) HTTPS (Let's Encrypt)
Mails von pacod-id von mailpit abgefangen von mailpit abgefangen dein Relay
KI Mock-Gateway Mock-Gateway dein pacod-gw, oder aus
Demo-Websites ja ja keine

Stage ist die Konfiguration der Produktion, mit abgefangenen Mails und gemockter KI. make check verweigert den Start, solange ein Secret fehlt oder die Konfiguration unsicher ist. Sichere .env, die MongoDB-Datenbanken, die Dateien der Websites und das PostgreSQL von pacod-id. /mgmt-health des Studios prüft nur, ob es läuft: Ein Studio, das pacod-id nicht erreicht, bleibt gesund, während seine Ansichten mit 503 antworten, und meldet das in seinem Log.

Jede Umgebung läuft im Docker-Netzwerk pacod-net, das sich alle pacod-Projekte teilen. Die eigenen Dienste des CMS — Site, Studio, MongoDB und Gotenberg — stehen in einer Compose-Datei; seine eigenen Kopien der gemeinsamen Teile — Caddy, pacod-id mit seinem PostgreSQL, das Entwicklungs-Gateway und der Mail-Catcher — in einer zweiten, die das Makefile mitlädt. Pro Rechner passt nur ein Stack, der die gemeinsamen Teile betreibt. pacod-demo lädt nur die erste Datei und betreibt das CMS zusammen mit den anderen Projekten hinter einem Caddy, einem pacod-id, einem PostgreSQL und einem Gateway; online ist es unter demo.pacod.io.

Grenzen und weiterführende Lektüre

Bekannte Einschränkungen in v1:

  • Die Identität einer Website (siteSettings) hat noch keine Ansicht im Studio; sie wird in der Datenbank bearbeitet.
  • Die Demo-Inhalte gibt es nur auf Englisch.
  • Die Mitgliederliste zeigt keine plattformweiten Rollen.

Die Roadmap nennt, was v1 zurückstellt, darunter eine Schreib-API, einen Gateway-Schlüssel und ein KI-Budget pro Organisation, einen separaten Worker, S3-Speicher und Importer für Inhalte.

Im Repository:

Screenshots

Tech-Stack

Geschrieben in
  • Java
Tech-Stack
  • Java 25
  • Spring Boot 4.1
  • Thymeleaf
  • MongoDB
  • Maven
  • Caddy
  • Gotenberg
  • Docker

Schnellstart

Ein Entwicklerrechner
make initmake upopen http://studio.localhost:8000/
Eine weitere Website über die Kommandozeile
make site-create SLUG=acme NAME="Acme News" HOSTS=acme.localhost DEMO=1

Funktioniert mit

  • pacod-id

    Das Studio meldet Personen über pacod-id an, das auch ihre Rollen pro Organisation und pro Website verwaltet.

  • pacod-gw

    KI-Funktionen laufen über das Gateway — das Studio hält nie den Schlüssel eines Anbieters.

Lizenz

Apache-2.0

Der eigene Code des Projekts steht unter Apache-2.0. Das Studio bündelt den TinyMCE-Editor (GPL-2.0-or-later), daher wird das gebaute Studio als Ganzes unter den Bedingungen der GPL-3.0 weitergegeben. Die öffentliche Site enthält ihn nicht.