Entwickler
Mach es zu deinem System.
Ein schlanker PHPWeit verbreitete Programmiersprache für Websites. KLXM Studio ist in PHP geschrieben und läuft deshalb auf fast jedem üblichen Webhosting.php.net (öffnet in neuem Tab)-Kern ohne Framework, offene Schnittstellen und klar dokumentierte Erweiterungspunkte – vom KitIn KLXM Studio das Paket aus Gestaltung und Bausteinen einer Website: Layout, Farben, Schriften und die passenden Blöcke. Ein Kit lässt sich anpassen oder wechseln, die Inhalte bleiben. bis zum eigenen CLI-Befehl.
Tech-Stack
Womit KLXM Studio gebaut ist.
Versionen laut composer.lock und tools/package.json von Version 1.0.0.
| Bereich | Technik | Details |
|---|---|---|
| Laufzeit | PHP ≥ 8.4, ohne Framework | Front-Controller, PSR-4-Autoload (Core\ → app/) über Composer; Erweiterungen sodium, gd, mbstring, dom, pdo. |
| Datenbank | SQLiteDatenbank in einer einzigen Datei, ohne eigenen Datenbank-Server. Ideal für kleine und mittlere Websites: einfach zu sichern und umzuziehen.sqlite.org (öffnet in neuem Tab) oder MySQLVerbreitete Datenbank-Server für Websites. MariaDB ist eine weitgehend kompatible, freie Weiterentwicklung von MySQL.mariadb.org (öffnet in neuem Tab) | Je Website SQLite (Standard, eine Datei) oder MySQL/MariaDB ('db' in config/sites/{key}.php); Sicherung per VACUUM INTO bzw. mysqldump. Suchindex, Chat, geteilte Tabellen, Medien-PoolGemeinsame Mediathek für mehrere Websites einer Installation: Bilder und Dateien liegen einmal vor und lassen sich auf allen beteiligten Websites verwenden., Support und KIKünstliche Intelligenz: Software, die aus vielen Beispielen Muster lernt und damit z. B. Texte entwirft, übersetzt oder Bilder beschreibt.-Protokolle bleiben immer SQLite – pdo_sqlite ist Pflicht, SQLite ≥ 3.35 (Debian 12/13, Ubuntu 22.04/24.04; AlmaLinux/RHEL 8/9 zu alt). Doctrine DBAL 4.4.4 (MIT) für Tabellen-Schemas. |
| Server | Apache, nginx oder php -S | Keine .htaccess – nur public/ liegt im Webroot; läuft auf Plesk und üblichem PHP-HostingBereitstellung einer Website auf einem Server im Internet – mit Speicher, Domain, E-Mail, Sicherungen und Wartung., lokal mit php -S. |
| Suche | loupe/loupe 1.1.0 (MIT) | Volltext mit Tippfehlertoleranz auf SQLite; optional semantisch/hybrid über EmbeddingZahlenfolge, mit der eine KI die Bedeutung eines Textes beschreibt. Ähnliche Inhalte haben ähnliche Embeddings – darauf beruht die semantische Suche.de.wikipedia.org (öffnet in neuem Tab) (Symfony AI Store). |
| KI | Symfony AI 0.14 (MIT) | platform + store; Anbieter OllamaKostenlose Software, mit der sich KI-Sprachmodelle auf eigenen Rechnern oder Servern betreiben lassen – ohne dass Texte an externe Cloud-Anbieter gehen.ollama.com (öffnet in neuem Tab), Mistral, OpenAI und generisch/OpenAI-kompatibel; lokale Transkription mit whisper.cpp. |
| Sicherheit | PasskeyAnmeldung ohne Passwort: Ein Schlüsselpaar wird auf Ihrem Gerät gespeichert und per Fingerabdruck, Gesichtserkennung oder PIN freigegeben. Passkeys sind gegen Phishing weitgehend immun.fidoalliance.org (öffnet in neuem Tab), Zwei-Faktor-AnmeldungAnmeldung mit zwei Nachweisen, etwa Passwort plus sechsstelliger Code aus einer App (TOTP). Selbst wenn das Passwort bekannt wird, bleibt das Konto so geschützt.de.wikipedia.org (öffnet in neuem Tab), libsodium, Content-Security-PolicyAngabe des Servers, aus welchen Quellen eine Seite Skripte, Stile, Bilder usw. laden darf. Sie erschwert Angriffe wie Cross-Site-Scripting erheblich.developer.mozilla.org (öffnet in neuem Tab) | Passkeys mit lbuchs/webauthn 2.2.0 (MIT), TOTP mit QR-Code (chillerlan/php-qrcode 5.0.5, MIT/Apache-2.0), libsodium für verschlüsselte Anfragen und Geheimnisse, Content Security Policy ohne unsafe-inline. |
| Kalender & Sync | rlanvin/php-rrule 3.0.0 · sabre/dav 4.7.1 | Wiederholungen (MIT); CalDAVOffene Standards, mit denen Kalender (CalDAV) und Adressbücher (CardDAV) zwischen Server und Programmen wie Outlook, Thunderbird oder dem Smartphone abgeglichen werden.de.wikipedia.org (öffnet in neuem Tab) in der Erweiterung dav (BSD-3-Clause). |
| HTTPProtokoll, mit dem Browser und Webserver Seiten austauschen. In der verschlüsselten Form heißt es HTTPS. & Mail | symfony/http-client 8.0.16 · symfony/mailer 8.0.15 | Proxy für Karten und Vorschaubilder, KI-Anbieter, SMTP-Versand (MIT). |
| Frontend | Vanilla JS, esbuild 0.25.12 | Skripte als IIFE und ES-Module (.mjs), gebaut mit esbuild in tools/ (pnpm); Verwaltungs-Oberfläche per Shadow DOM vom Kit isoliert; CSSSprache für das Aussehen von Webseiten: Farben, Schriften, Abstände und das Verhalten auf verschiedenen Bildschirmgrößen.-Budgets je Kit. |
| Vendor-Assets | Editor.js 2.31.7 · PDF.js 6.3.289 · MapLibre GL JS 6.11.2 | Blockeditor (Apache-2.0) mit editorjs-drag-drop 1.1.16 (MIT), PDF-Viewer (Apache-2.0), Karten (BSD-3-Clause); Schrift Lato (OFL). |
| Symbole | Phosphor Icons 2.1.1 duotone (MIT) | 511 Symbole in 23 Themenbereichen, als Sprite je Website. |
| Lizenz | MIT | Kern, Kits und Erweiterungen; eigene Kits und Erweiterungen unter beliebiger Lizenz. Drittsoftware siehe THIRD-PARTY-NOTICES.md. |
Erweiterungspunkte
Wo Sie ansetzen können.
Jeder Ausschnitt stammt aus dem Quelltext von Version 1.0.0.
-
Kits
Ein Kit ist ein eigenständiges Paket: BlockBaustein einer Seite, etwa Text, Bild, Galerie, Karte oder Formular. Seiten setzen Sie aus Blöcken zusammen; jeder Block hat Felder für seine Inhalte und Optionen für die Darstellung., zentrale Einstellungen, Design-Tokens, bedingtes CSS je Block und JSON-LDFormat für strukturierte Daten im Code einer Seite: Es beschreibt Suchmaschinen maschinenlesbar, worum es geht – etwa Organisation, Veranstaltung oder Artikel (Vokabular von schema.org).developers.google.com (öffnet in neuem Tab). Neues Kit: php bin/console kit:create <name> [--from=…] – Standard ist das Start-Kit. Technisch liegt ein Kit unter kits/{name}/theme.php.
kits/essenz/theme.php 'jsonld' => 'essenz_jsonld', 'conditional_css' => [ 'css/b-faq.css' => ['faq'], 'js/video.js' => ['video'], ], 'design' => require __DIR__ . '/design.php', -
Blöcke als PHP-Vorlage
Renderer je Blocktyp in kits/{name}/blocks – mit Inline-Editing über $b->edit(). Der Block erscheint automatisch im Editor, in der REST-APIVerbreitete Form einer Programmierschnittstelle über HTTP: Inhalte werden über Adressen abgerufen, angelegt oder geändert, meist im Format JSON.de.wikipedia.org (öffnet in neuem Tab) und im MCPModel Context Protocol: offener Standard, über den KI-Assistenten auf Werkzeuge und Daten zugreifen. Über einen MCP-Server können solche Assistenten zum Beispiel Inhalte einer Website lesen oder Entwürfe anlegen.modelcontextprotocol.io (öffnet in neuem Tab).
kits/basis/blocks/richtext.php <div class="wrap wrap--text"> <?= basis_head($b) ?> <div class="prose"<?= $b->edit('text', 'rich') ?>><?= rich($d['text']) ?></div> </div> -
Block-Designer
Eigene Blöcke ohne PHP: Felder, eine sichere Vorlagensprache mit Escaping und begrenztes CSS (nur im Block); Export als Kit-Block. Auszug aus dem Block „Kommandozeile“ dieser Website:
Verwaltung → Blöcke <ol class="cli-list"> {% for c in commands %}<li class="cli-row"> <code class="cli-cmd">{{ c.cmd }}</code> <span class="cli-text">{{ c.text }}</span> </li>{% endfor %} </ol> -
Erweiterungen
Eine Erweiterung bringt Funktionen, Rechte, Migrationen, Menüeinträge, Routen, Blöcke, Proxy-Quellen und CLI-Befehle mit – aktiv je Website über 'extensions' => ['dav']. Erweiterungen liegen in extensions/{name} oder kommen als Composer-Paket vom Typ „klxm-studio-extension“ (composer require hersteller/paket) – der Kern findet sie automatisch.
extensions/dav/extension.php 'boot' => function (Core\Extension $x): void { $x->feature('dav', 'CalDAV/CardDAV (Kalender und Kontakte in Apps)', ['dav.use']); $x->permissions('CalDAV/CardDAV', ['dav.use' => '…']); $x->migration(1, fn(Core\Database $db) => MyCms\Dav\Dav::migrate($db)); $x->nav('/admin/dav', 'Kalender & Kontakte in Apps', 'dav', 'dav.use'); -
Beispiel: Consent Kit
Eine vollständige Erweiterung mit eigener README, LICENSE (MIT) und THIRD-PARTY-NOTICES: Einwilligungsverwaltung mit 38 TemplateVorlage für wiederkehrende Seiten oder Dokumente: Aufbau und Gestaltung stehen fest, die Inhalte werden eingesetzt., Web Component im Shadow DOM, Consent Mode v2 und einer CSP, die sich erst nach Einwilligung erweitert. Port des REDAXOOpen-Source-CMS aus Deutschland mit großer Community: schlank, flexibel erweiterbar und für Websites jeder Größe geeignet.redaxo.org (öffnet in neuem Tab)-AddOns consent_kit von KLXM.
extensions/consent_kit // config/sites/{key}.php bzw. config/config.local.php 'extensions' => ['consent_kit'], // abschalten, ohne die Erweiterung zu entfernen: 'features' => ['consent' => false], -
Hooks für die Ausgabe
Erweiterungen können das HTMLAuszeichnungssprache für den Aufbau von Webseiten: Überschriften, Absätze, Links und Bilder werden darin beschrieben. der Website nachbearbeiten, Quellen zur CSP ergänzen (nie unsafe-inline) und Links in die Rechtliches-Zeile setzen.
app/Extension.php $x->htmlFilter(fn(string $html, array $ctx) => $html) $x->csp(fn() => ['script-src' => ['https://…']]) $x->footerLinks(fn() => [['label' => …, 'href' => '#…']]) -
Ereignisse & Filter
Typisierte Ereignisse melden nach der Änderung, was passiert ist – Seiten angelegt, verschoben, übersetzt, Formular abgeschickt, Anmeldung, Einstellungen, Tabellen. Filter ändern Ergebnisse an festen Stellen: Suche, Sitemap, Menü, SEOSuchmaschinenoptimierung: Maßnahmen, damit eine Website bei Google & Co. gut gefunden wird – von hilfreichen Inhalten und Seitentiteln über schnelle Ladezeiten bis zu sauberer Technik.developers.google.com (öffnet in neuem Tab), Formular-Prüfung, E-Mails, Datenliste. Fehler einer Erweiterung brechen nie die Seite.
app/Filters.php $x->on(FormSubmitted::class, fn(FormSubmitted $e) => Warteliste::pruefen($e->entryId)); $x->filter('search.document', fn(array $doc, array $c) => ($c['table'] ?? '') === 'notizen' ? false : $doc); $x->filter('seo.meta', fn(array $m, array $c) => ['title' => 'Termine · ' . $m['title']] + $m); -
Blöcke & Editor
Erweiterungen lösen Blöcke für Ausgabe, Suche und APIProgrammierschnittstelle: Über sie tauschen Programme Daten aus, ohne die Bedienoberfläche zu nutzen – etwa um Einträge aus einem anderen System zu übernehmen.de.wikipedia.org (öffnet in neuem Tab) auf, prüfen sie vor dem Speichern und bieten Vorlagen in der Blockauswahl an. Im Seiten-Editor ergänzen sie das Block-Menü, Kennzeichen und „Bearbeiten“ – ohne den Editor zu kennen.
app/Extension.php $x->blocksResolve(fn(array $blocks, array $ctx) => Bausteine::aufloesen($blocks, $ctx['purpose'])); $x->blockPresets(fn() => [['type' => 'shared', 'label' => 'Kontakt-Box', 'data' => ['ref' => 'k1'], 'group' => 'Gemeinsam']]); // im Browser: CMSAdmin.editorExt.addBlockAction({ id, label, run: b => … }) -
Oberfläche der Verwaltung
Verwaltungsseiten von Erweiterungen sehen aus wie der Kern: Kopf, Bereichsliste links, gruppierte Zeilen und Speichern-Leiste aus Core\AdminUi. Seiten melden sich mit Art an (Inhalt, Werkzeug, Einstellungen, Statistik) – der Ort im Menü ergibt sich daraus. Musterseite mit allen Bausteinen in jeder Installation unter /admin/hilfe/ui.
app/AdminUi.php echo AdminUi::head(__('Mitglieder'), __('Erweiterung'), __('Einladen, Gruppen, geschützte Seiten')); echo AdminUi::open($bereiche, 'groups', __('Mitglieder')); echo AdminUi::group(__('Gruppen'), [AdminUi::row(__('Name'), $wert, __('Hinweis'))]); echo AdminUi::close(); -
Diagramme
Diagramme in einem eigenen, schlichten Format – gezeichnet von einer austauschbaren Engine (Standard: Apache ECharts, gebündelt, lädt erst in Sichtweite). Farben aus dem Kit, Tooltip ohne Inline-Stile, Tabelle als Rückfall; Erweiterungen bieten Datenquellen für den Block „Diagramm“ an.
app/Charts.php echo \Core\Charts::render(['type' => 'bar', 'labels' => ['Jan', 'Feb'], 'series' => [['name' => __('Anfragen'), 'data' => [12, 19]]]]); // Engine tauschen: ES-Modul mit render(el, spec, theme) \Core\Charts::registerEngine('meine', asset('ext/meine/js/charts-meine.mjs')); // Datenquelle für den Block „Diagramm“ \Core\Charts::registerSource('stats.visitors', __('Besucher je Tag'), fn($d) => [...]); -
PDF erzeugen
HTML → PDF für Kern und Erweiterungen, mit austauschbarer Engine. Standard dompdf als eigenes Paket (klxm/studio-pdf, installiert = verfügbar); freie Schriften von Fontsource, Seitenzahlen, keine Netzzugriffe, kein PHP im HTML.
app/Pdf.php if (\Core\Pdf::available()) { $pdf = \Core\Pdf::render($html, ['font' => 'source-sans-3', 'display' => 'source-serif-4', 'pages' => true]); return \Core\Pdf::response($pdf, 'Bericht.pdf'); } -
Geplante Aufgaben
Ein CronZeitplan-Dienst des Servers, der Aufgaben regelmäßig von selbst startet – etwa den Suchindex abgleichen, Sicherungen anlegen oder Feeds abrufen.de.wikipedia.org (öffnet in neuem Tab) für die Installation (cron:run). Kern und Erweiterungen melden Aufgaben an – Erweiterungen im Manifest; sie laufen auf jeder Website, auf der die Erweiterung aktiv ist. Sperre, Zeitlimit, Warteschlange und Protokoll inklusive.
app/Cron.php // extension.php (Manifest) 'schedule' => [ 'purge' => ['label' => 'Alte Einträge löschen', 'command' => 'xyz:purge', 'cron' => '10 4 * * *'], ], // crontab – eine Zeile für alles * * * * * cd /pfad && php bin/console cron:run -
REST-API
OpenAPIStandard, der eine REST-API maschinenlesbar beschreibt. Daraus lassen sich Dokumentation, Testwerkzeuge und Programmcode für die Anbindung erzeugen.openapis.org (öffnet in neuem Tab) 3.1 unter /api/v1/openapi.json. Tokens mit Stufe read oder write, Ablaufdatum und Modus „Direkt übernehmen“ oder „Zur Freigabe“ – gespeichert wird nur ein SHA-256-Hash.
curl curl -H "Authorization: Bearer $TOKEN" https://ihre-domain.de/api/v1/me -
MCP-Server
Model Context Protocol über Streamable HTTP mit 48 Werkzeugen, u. a. list_pages, update_block, save_entry, upload_media, set_design, publish_page – mit denselben Tokens und Regeln wie die API.
Claude Code claude mcp add --transport http mycms https://ihre-domain.de/mcp --header "Authorization: Bearer cms_…" -
Kommandozeile
Über 100 Befehle für Konten, Websites, Netzwerk, Kits, Schriften, Migration, Sicherungen, geteilte Daten, Suche und KI; Erweiterungen ergänzen eigene.
bin/console php bin/console site:create kunde www.kunde.de,kunde.de basis php bin/console migrate --all php bin/console health php bin/console blocks:selftest -
Datentabellen
Eigene Tabellen mit 30 Feldtypen, Bedingungen, Detailseiten und öffentlichen Formularen – geteilt zwischen mehreren Websites einer Installation.
bin/console php bin/console data:share <handle> --members=a,b [--see-members] [--merge] php bin/console shared:list -
Externe Quellen
RSSFormat für Nachrichten-Feeds: Eine Website stellt neue Beiträge als Liste bereit, die andere Programme oder Websites automatisch abrufen können.de.wikipedia.org (öffnet in neuem Tab) 2.0/1.0, Atom, JSONEinfaches Textformat für strukturierte Daten, das Menschen lesen und Programme leicht verarbeiten können. Standard für den Datenaustausch über Web-Schnittstellen.de.wikipedia.org (öffnet in neuem Tab) (Pfad), XMLTextformat für strukturierte Daten mit Auszeichnungen in spitzen Klammern. Viele Feeds und Austauschformate (z. B. RSS, OpenImmo) bauen darauf auf.de.wikipedia.org (öffnet in neuem Tab) (XPath) und OpenImmoBranchenstandard zum Austausch von Immobilienangeboten zwischen Maklersoftware und Portalen bzw. Websites.openimmo.de (öffnet in neuem Tab) 1.2 (XML, ZIP oder Abruf-URL) werden serverseitig geholt, per Zuordnung mit Umwandlungen in Einträge einer DatentabelleStrukturierte Inhalte wie Team, Termine, Produkte oder Referenzen: gleich aufgebaute Einträge mit festen Feldern, die auf mehreren Seiten erscheinen können – oft mit eigener Detailseite je Eintrag. übersetzt und abgeglichen; Bilder landen in der Mediathek, übernommene Einträge sind schreibgeschützt. Schutz vor SSRF, XXE und ZIP-Slip.
Zuordnung (JSON) · bin/console {"id_path": "guid | link", "rows": {"titel": {"path": "title", "tx": "text"}, "datum": {"path": "pubDate | dc:date", "tx": "date"}, "bild": {"path": "enclosure@url | media:content@url", "alt": "title"}}} */15 * * * * php bin/console sources:sync --all -
Sprachen
Feste Texte laufen über lt('…') (Website) bzw. __('…') (Verwaltung); Übersetzungen als PHP-Array je Sprache, fehlende zeigt i18n:missing.
kits/essenz/lang/site/en.php 'Datenschutz' => 'Privacy', # php bin/console i18n:missing en --site-texts -
Design-Tokens
Jeder Token wird eine CSS-Variable oder Klasse; der Style-Editor zeigt Vorlagen und prüft Kontraste, auch über API und MCP (get_design/set_design).
kits/essenz/design.php $color('accent', 'Signal (Füllfarbe)', '--e-a', '#D85B19', '#F0782F', ['with' => 'background', 'min' => 3], -
Funktionsumfang je Website
Presets und einzelne Funktionen je Website; abgeschaltete Funktionen sperren ihre Rechte – Navigation, API und MCP folgen automatisch.
config/sites/{key}.php 'preset' => 'full' | 'content' | 'minimal', 'features' => ['data.schema' => false, 'api' => false], 'blocks' => ['deny' => ['video'], 'allow' => null],
Loslegen
In vier Schritten lokal.
Aus dem Schnellstart der README. Das Entwicklerhandbuch liegt in der Verwaltung unter /admin/hilfe/technik.
-
Quelltext holen
Öffentliches Repository: github.com/KLXM-Opensource/studio – Fehler und Wünsche unter github.com/KLXM-Opensource/studio/issues.
git git clone https://github.com/KLXM-Opensource/studio.git cd studio -
Abhängigkeiten und Build
Composer 2 für PHP, Node 22 + pnpm 10 nur für den Build – der Server braucht weder Node noch pnpm.
shell composer install cd tools && pnpm install && pnpm build && cd .. -
Starten
Der erste Aufruf legt Datenbank und config/config.local.php (app_key, setup_token) an und spielt die Startinhalte des Kits ein.
shell php -S localhost:8000 -t public public/index.php -
Konto anlegen
Oder /admin/setup mit dem Setup-Token öffnen. Danach: Verschlüsselung, E-Mail-Versand und Kit-Angaben einrichten.
shell php bin/console user:create name@example.org admin
Kontakt
Sprechen Sie mit KLXM Crossmedia.
Vorführung, Einsatz in Ihrem Projekt oder eine Erweiterung nach Ihren Wünschen – sprechen Sie uns an. Wir antworten persönlich.
Am Schürmannshütt 40g
47441 Moers
Deutschland
- Telefon
- +49 2841 889998-0
- info@klxm.de