Theme
Plugins
Ein Plugin ist die Kern-Erweiterungseinheit von newmeta. Alle Admin-Module, Shop-Funktionen, Pagebuilder-Widgets und API-Endpoints leben in Plugins. Das CMS liefert 42 Plugins mit — dieselbe Plugin-API steht fuer eigene Module offen.
Was ist ein Plugin?
Jedes Plugin ist ein Unterordner in _public/extensions/core/backend/{plugin-name}/ und besteht aus:
- einer
bootstrap.php, die das Plugin registriert, - optional Admin-Layouts (
layout/index.vue,layout/index_detail.vue), - optional PHP-Action-Scripts (
script/), - optional API-Models (
api/), - optional Pagebuilder-Widgets (
widgets/), - optional SQL-Migrationen (
migrations/).
Ein Plugin entscheidet selbst, welche dieser Teile es braucht. Kleine Plugins haben nur bootstrap.php + eine Tabelle; grosse Plugins wie shop oder elearning bringen komplette API-Verzeichnisse, eigene Widgets und dutzende Migrationen mit.
Warum ein Plugin bauen?
| Use Case | Plugin-Pattern |
|---|---|
| CRUD fuer ein neues Datenmodell | content_construct=table + content_table=meine_tabelle → automatisches Backend mit Liste + Edit-Modal + API |
| Custom-UI ohne DB-Tabelle | content_construct=template + eigene layout/index.vue |
| Neuer REST-Endpoint | $this->apiEndpoints in bootstrap.php, Model in api/ |
| Integration mit externem Service | Pagebuilder-Widget + Webhook-Event + Scheduled Task |
| Eigenes Pagebuilder-Element | Widget-Unterordner unter widgets/ (siehe Widget-Doku) |
Plugins sind die einzig richtige Stelle, um Funktionalitaet hinzuzufuegen — am Core-Framework wird nie direkt gearbeitet.
Plugin-Lebenszyklus
Ein Plugin durchlaeuft drei Phasen. install() selbst setzt nur Properties — die eigentlichen DB-Inserts passieren in den Core-Installern und muessen nicht idempotent sein (ein Re-Install wird typischerweise vorher per uninstall() entfernt). uninstall() wiederum muss sauber aufraeumen, damit Re-Installationen nicht auf Altlasten stossen.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ install() │ --> │ update() │ --> │ uninstall() │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
plugin_backend Schema-Migration plugin_backend
Eintrag anlegen via MigrationRunner Eintraege entferneninstall() — einmalig beim ersten Aktivieren. Setzt alle Properties (content_construct, content_table, apiEndpoints, scheduledTasks, webhookEvents, …). Der Core ruft danach automatisch folgende Installer auf:
installBackend() → plugin_backend Eintraege (ein Eintrag pro content_construct)
installWidgets() → Pagebuilder-Widgets in pagebuilder_widgets + page_widgets
installDatabase() → Plugin-eigene Migrationen ausfuehren
installInjections() → Script-Injections registrieren
installSources() → CSS/JS Assets fuer Frontend-Bundle
installAPI() → apiEndpoints in pluginAPI-Tabelle
installScheduledTasks() → scheduled_tasks Eintraege
installWebhookEvents() → webhook_events Eintraege (manual + auto aus content_table)update() — bei System-Update. Typisch leer — Schema-Aenderungen laufen ueber Migrationen, nicht ueber update(). Nur noetig wenn bestehende plugin_backend-Eintraege umgeschrieben werden muessen.
uninstall() — beim Deaktivieren. Entfernt die Eintraege aus plugin_backend, pluginAPI, scheduled_tasks und webhook_events. Tabellen werden nicht geloescht — Daten bleiben erhalten, falls das Plugin spaeter wieder aktiviert wird.
Pflicht-Methoden
Jede Plugin-Klasse muss install(), uninstall(), update(), getVersion() und getName() implementieren. Details: Plugin-Anatomie.
Die plugin_backend-Tabelle
Herzstueck der Backend-Integration. Fuer jedes content_construct eines Plugins wird ein Eintrag erzeugt:
sql
CREATE TABLE plugin_backend (
id INT AUTO_INCREMENT PRIMARY KEY,
plugin_id INT NOT NULL, -- FK → plugins.id
content_construct ENUM('table','template','formonly'),
content_table VARCHAR(255), -- DB-Tabelle bei construct=table
content_titles VARCHAR(255), -- UI-Label ("Artikel", "Kurse", …)
content_columns TEXT, -- Sichtbare Spalten (JSON/CSV)
content_button TEXT, -- Zeilen-Buttons (JSON, urlencoded)
action_button TEXT, -- Header-Action-Button (JSON)
content_replace TEXT, -- Spalten-Umbenennungen
header_buttons TEXT, -- Weitere Header-Buttons
url_rewrite VARCHAR(255), -- URL-Slug → /admin/{url_rewrite}
modal_edits TEXT -- Modal-Feld-Config
);content_construct bestimmt die gesamte UI-Logik des Plugins. Die drei Varianten (table, template, formonly) sind in Content Constructs erklaert.
Weitere wichtige Tabellen
| Tabelle | Inhalt |
|---|---|
plugins | Plugin-Registry (name, version, root_folder, type, location) |
plugin_backend | Admin-UI-Einstiegspunkte pro Plugin |
pluginAPI | Registrierte REST-Endpoints (endpoint, modelPath, plugin_id) |
scheduled_tasks | Cron-Jobs pro Plugin |
webhook_events | Registrierte Webhook-Events pro Plugin |
pagebuilder_widgets | Pagebuilder-Widget-Registry (einmal pro Widget-Typ) |
page_widgets | Widget-Instanzen pro Seite (eine Zeile je platziertem Widget) |
_migrations | Ausgefuehrte SQL-Migrationen (scope + migration + checksum) |
Installation & Update
Plugins aktivieren geschieht ueber den Plugin Manager unter /admin/plugin-manager oder via Core-Installer beim System-Update. Beide Wege rufen installPlugin() auf dem install_controller auf und fuehren die oben genannten Schritte aus.
Neue Plugins einfach in _public/extensions/core/backend/ ablegen, Migrationen im Plugin-Unterordner oder zentral unter _migrations/plugins/{name}/. Beim naechsten Admin-Login sieht der Plugin-Manager das Plugin und bietet Installation an.
Details zum Update-Prozess: Plugins › Migrations.
Siehe auch
- Plugin-Anatomie — Ordner-Struktur, Pflicht-Methoden, erste Klasse
- Content Constructs —
tablevs.templatevs.formonly - Buttons — Button-Typen im Admin
- Migrations — SQL-Migrationen schreiben und ausrollen
- API-Endpunkte — REST-Endpoints pro Plugin registrieren
- Webhook-Events — Events emittieren, Webhook-Subscriptions
- Scheduled Tasks — Cron-Jobs aus Plugin heraus
- Beispiel: Hello World — minimales Plugin von null
- Widget-Doku — Pagebuilder-Widgets in Plugins