Ein dateibasiertes, deklaratives Website-System ohne klassische Datenbank.
Webseiten werden durch eine formale Beschreibungssprache definiert und zur Laufzeit interpretiert. Das System erzwingt strikte Trennung von semantischer Struktur, Inhalten und Darstellung.
Tag-Press begann als geistiges Trainingsgerät und Lern-Experimentierrahmen – und ist inzwischen ein System, mit dem sich echte Websites erstellen lassen. Eine Website wird nicht gebaut, sondern beschrieben. Rendering ist lediglich die Interpretation dieser Beschreibung.
Ziel: Eleganz durch Reduktion. Das System ist absichtlich einfach und streng, um klare Denkweisen zu fördern.
| Ebene | Beschreibung |
|---|---|
| Struktur | Semantische Geometrie: WAS existiert, WO und WARUM |
| Daten | Nur rohe Inhalte und Metadaten, keine Position oder Layout-Info |
| Darstellung | Wie wird es visuell umgesetzt (CSS/Grid) |
Alles basiert auf flachen Dateien (PHP-Arrays). Vollständige Transparenz, Versionierbarkeit und Determinismus.
Keine impliziten Fallbacks. Ungültige Definitionen führen zu hartem Abbruch mit klarer Fehlermeldung. Das System ist korrekt oder es existiert nicht.
Jede Seite muss vor Rendering vollständig validiert werden. Fehler sind keine Warnungen, sondern Abbruchbedingungen. Der Validator sammelt alle Fehler einer Seite und meldet sie gemeinsam – inklusive „Meinten Sie …?"-Vorschlägen bei Tippfehlern.
Nur das Nötigste. Erweiterungen nur durch explizite, dokumentierte Regeln.
Tag-Press generiert semantisches, WCAG 2.1 AA konformes HTML mit vollständiger Keyboard-Navigation, ARIA-Support und Screen Reader Optimierung. Mehr Details →
Die Platzierung von Objekten steht ausschließlich in den page_assignments (Tag-Notation). Seitentitel, Navigation und Sprache kommen aus der Geometrie – nichts wird doppelt gepflegt.
tag-press/
├── index.php # Interpreter (lädt, validiert, rendert)
├── assets/
│ ├── styles.css # Globale Styles (lokal, keine CDNs)
│ └── images/ # Lokale Bilder (SVG/JPG/PNG)
├── bin/
│ ├── validate.php # CLI: alle Seiten prüfen (CI-tauglich)
│ ├── new-object.php # CLI: Datenobjekt-Gerüst generieren
│ └── export.php # CLI: statischer HTML-Export
├── config/
│ ├── Config.php # Zentrale Pfadauflösung m()
│ ├── layout/
│ │ └── grid_master.php # Physisches Grid (CSS-Klassen, Breakpoints)
│ └── classes/
│ ├── main_classes.php # Parser, DataLoader, Renderer, TagPress
│ ├── Validator.php # Zentrale Prüfinstanz
│ ├── HtmlDocument.php # Dokument-Gerüst (Head, Navigation, Footer)
│ └── TagPressException.php
├── struktur/
│ └── main_geometrie.php # Semantische Geometrie (zentrale Wahrheit)
├── daten/ # Inhaltsdateien (sprechende Namen empfohlen)
└── tests/
└── ValidatorTest.php # Standalone-Testsuite (php tests/ValidatorTest.php)
Die Datei struktur/main_geometrie.php ist die zentrale Wahrheit des Systems. Sie definiert:
site: Name, Sprache, Beschreibung, Footer)page_assignments)'Z1=hero_bild,hero_titel'
Bedeutet: Zone Z1 enthält die Objekte hero_bild und hero_titel – in dieser Reihenfolge. Die Objekt-ID ist zugleich der Dateiname: daten/hero_bild.php.
Sprechende Namen sind empfohlen. Klassische IDs (O1, O2, …) funktionieren weiterhin, aber Z1=hero_bild,hero_titel erklärt sich selbst.
Jede Seite hat einen Slug für lesbare URLs:
| Aufruf | Ergebnis |
|---|---|
/?page=startseite |
Startseite (per Slug) |
/?page=A |
Startseite (per ID) |
/ |
Erste Seite der Geometrie |
/?page=tippfehler |
Fehlerseite 404 mit Liste aller Seiten |
Die Navigation wird automatisch aus der Geometrie generiert (mit aria-current für die aktive Seite). Seiten mit 'in_nav' => false erscheinen nicht im Menü.
Eine Zone ist ein semantischer Raum mit klarer Funktion. Ihre Bedeutung ist unabhängig von ihrer visuellen Position.
| Zone | Bedeutung (Beispiel Startseite) |
|---|---|
| Z1 | Primärfokusbereich (Hero) |
| Z2 | Hauptinhaltsbereich |
| Z3 | Sekundärbereich |
| Z4 | Abschlussbereich |
Optional kann eine Zone 'allowed_objects' definieren – dann wird die Zuweisung zusätzlich gegen diese Whitelist validiert.
Das System beschränkt sich bewusst auf wenige, klar definierte Typen. Die Attribute und Werte sind formal festgelegt:
| Typ | Pflichtattribute | Optionale Attribute | Werte/Details |
|---|---|---|---|
image |
src (url), alt (string, min 5 Zeichen) | title (string), caption (string) | alt darf nicht Dateiname sein; lokale Bilddateien müssen existieren |
text |
content (string), role (enum) | - | role: heading, subheading, intro, paragraph, note |
list |
items (array, min 1) | list_type (enum) | list_type: ordered, unordered |
action |
label (string), href (url) | action_type (enum) | action_type: link, button (steuert nur die Optik – gerendert wird immer ein Link) |
Wichtig: Ein Bildobjekt ohne Alt-Text existiert in Tag-Press nicht!
Dateien im daten/-Verzeichnis enthalten ausschließlich Inhalte und Metadaten:
<?php // daten/hero_bild.php return [ 'type' => 'image', 'src' => '/assets/images/hero-banner.svg', 'alt' => 'Beschreibung des Bildes', 'title' => 'Optionaler Titel' ];
Datenobjekte wissen nichts über:
Der Grid-Master (config/layout/grid_master.php) übersetzt semantische Zonen in CSS-Klassen:
<?php return [ 'zones' => [ 'Z1' => 'zone-hero full-width bg-gradient', // global 'B.Z2' => 'zone-main container flow-container', // seitenspezifisch ], 'objects' => [ 'image' => 'img-responsive img-cover', 'text' => 'text-block prose', ] ];
Der Grid-Master:
Ein Eintrag 'B.Z2' (Seite.Zone) hat Vorrang vor dem globalen 'Z2' – so kann dieselbe Zonen-ID pro Seite unterschiedlich dargestellt werden, ohne die Geometrie anzufassen.
Validierung ist ein zentrales Prinzip. Geprüft wird:
Bei Fehlern: Harter Abbruch mit vollständigem Bericht – alle Fehler und Warnungen einer Seite auf einmal, bei Tippfehlern mit „Meinten Sie …?"-Vorschlag.
php bin/validate.php # alle Seiten prüfen (Exit-Code für CI) php bin/validate.php A kontakt # nur bestimmte Seiten (ID oder Slug)
index.php zeigen lassen (oder statisch exportieren, s.u.)/?page=startseite (oder ohne Parameter für die erste Seite)cd tag-press
php -S localhost:8080
Dann im Browser: http://localhost:8080
Debug-Panel (Pfade, Cache, geladene Dateien): http://localhost:8080/?debug=1
1. Inhalte anlegen – Datenobjekt-Gerüste generieren lassen:
php bin/new-object.php hero_titel text php bin/new-object.php hero_bild image
Der Generator füllt alle Pflichtattribute aus der formalen Grammatik vor und dokumentiert erlaubte Werte. Danach die TODO-Werte in daten/*.php ausfüllen.
2. Seite beschreiben – in struktur/main_geometrie.php:
'pages' => [ 'D' => [ 'name' => 'Leistungen', 'slug' => 'leistungen', 'zones' => [ 'Z1' => ['meaning' => 'Überblick über das Angebot'], ], ], ], 'page_assignments' => [ 'D' => ['Z1=hero_titel,hero_bild'], ],
Titel, Navigation und URL entstehen automatisch – nichts weiter nötig.
3. Prüfen:
php bin/validate.php
4. Veröffentlichen – entweder mit PHP-Hosting (Schritt „Installation") oder als statisches HTML:
php bin/export.php
Der Export rendert alle Seiten nach export/ (index.html, <slug>.html, Assets inklusive) – lauffähig auf jedem Hosting, ganz ohne PHP. Möglich, weil Tag-Press deterministisch ist: gleiche Eingabe, gleiche Ausgabe.
Jeder Azubi schreibt eine Dokumentation: "Was bedeutet Z1 semantisch?"
Neue Zone oder Objekttyp definieren (muss argumentiert werden!)
Validierungslogik nachvollziehen und erweitern (config/classes/Validator.php)
Renderer-Klasse für neue Objekttypen ergänzen
Erste vollständige Seite bauen und testen – die Seiten „Über uns" (/?page=ueber-uns) und „Kontakt" (/?page=kontakt) sind als Referenz bereits umgesetzt
┌─────────────────────────────────────────────────────────────┐
│ index.php │
│ (Interpreter: Slug-Auflösung, Orchestrierung) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ GeometryParser │
│ (Lädt main_geometrie.php: Seiten, Slugs, Navigation) │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────┴───────────────┐
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────────┐
│ Validator │ │ DataLoader │
│ (Sammelt ALLE Fehler) │ │ (Lädt daten/*.php sicher) │
└─────────────────────────┘ └─────────────────────────────┘
│ │
└───────────────┬───────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ Renderer │
│ (+ Grid-Master für CSS-Klassen) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ HtmlDocument │
│ (Head, Navigation, Footer – für Server UND Export) │
└─────────────────────────────────────────────────────────────┘
unsafe-inline ist möglichphp tests/ValidatorTest.php
Die Testsuite läuft standalone (ohne PHPUnit) und prüft Parser, Validator, DataLoader, Renderer, Slug-Auflösung, Navigation und Sicherheits-Prüfungen.
Tag-Press ist kein weiteres CMS, sondern ein strukturelles Gegenmodell zu datenbankzentrierten Systemen. Es ist:
Wer Tag-Press verstanden hat, versteht automatisch auch andere Systeme besser, weil er gelernt hat, zwischen Bedeutung, Struktur, Darstellung und Daten zu unterscheiden.