Zwanzig Kundensites brauchen alle einen Blog-Post, einen Termin und eine Person. Entweder du kopierst die Schemas zwanzigmal und pflegst sie zwanzigmal, oder du legst sie einmal in ein Paket und abonnierst es pro Site. RustyCMS macht Letzteres — und lässt jede Site trotzdem abweichen, wo sie muss.
Drei Schichten
1. Repo-Defaults ./types/
2. Schema-Pakete (in Abo-Reihenfolge) <content>/_types/<paket>/
3. Site-Override (höchste Priorität) <content>/<site>/types/
Jede Site sieht die Summe aller drei. Ein Paket wird einmal gepflegt, jede abonnierende Site bekommt die Änderung sofort — kein Kopieren, kein Deploy.
// <content>/site-a/.rustycms.json5
{
locales: ["de", "en"],
types: ["core", "press", "events"],
}
Gemergt pro Feld, nicht ersetzt
Das ist der Punkt, an dem die meisten Vererbungsmodelle scheitern: Ein Override, der ein Feld ändern will, muss sonst das ganze Schema kopieren — und friert damit alles andere ein. RustyCMS merged pro Feld. Ein Site-Override nennt nur, was abweicht: ein zusätzliches Feld, ein anderes Label, ein strengeres Pattern. Alles andere kommt weiter aus dem Paket, und ein neues Paket-Feld taucht auch in Sites auf, deren Override es nicht kennt.
Bool-Flags werden mit ODER gemerged — ein Override kann required anschalten, aber nie still ausschalten. Feldreihenfolge bleibt erhalten, fehlende Einträge werden angehängt.
Verwalten ohne Dateizugriff
Pakete und Abos gehen über die API und die Admin-UI: Paket anlegen, Schema hineinlegen, Site abonnieren, Reihenfolge ändern. Jeder Schreibvorgang baut die Cascade für alle Sites neu und invalidiert den Cache. Wer lieber Dateien editiert: Der Watcher beobachtet auch _types/, ein direkter Edit wirkt genauso.
curl -X PUT /api/environments/site-a/type-packs \
-H "X-API-Key: $KEY" -d '{"packs":["core","press"]}'
# Aufgelöstes Schema prüfen — so wie die Site es sieht
curl /api/collections/press_release?_environment=site-a
Bewusst nicht drin
Kein „Paket A erbt von Paket B”, keine Paket-Abhängigkeiten, keine bedingten Schemas, kein Laden aus fremden URLs. Drei Schichten und ein klarer Merge sind erklärbar. Ein Graph aus Paketen ist es nicht mehr.