Einrichtung deiner Entwicklungsumgebung

Diese Anleitung erklärt, wie du deine Entwicklungsumgebung für die Plugin-Entwicklung einrichtest.

Ein Plugin in Neleto ist einfach ein normaler Webserver. Das bedeutet, dass du Plugins in jeder Programmiersprache schreiben kannst.

Die einzigen 2 Anforderungen, damit dein Webserver als Plugin funktioniert, sind:

  1. Die Manifest-Datei plugin.json. Diese Datei definiert den Namen, die Version, den Startbefehl (bin) und Metadaten deines Plugins. Hier ist ein minimales Beispiel:
{
    "name": "example-plugin",
    "version": "0.1.0",
    "bin": "bun run main.js"
}
  1. Das gepackte Plugin muss alles enthalten, was zum Ausführen unter einem x86 Ubuntu 24.04 Docker-Container benötigt wird. Dies umfasst Laufzeiten für Programmiersprachen wie JavaScript, was bedeutet, dass du sie mit deinem Plugin bündeln musst. Im Fall von Bun kannst du --compile beim Bauen deines Plugins verwenden, um die Bun-Laufzeit einzubinden.

Die Manifest-Datei plugin.json

Um dein Plugin besser in Neleto zu integrieren, kannst du weitere Werte in der plugin.json angeben. Die Manifest-Datei plugin.json muss diesem TypeScript-Typ entsprechen:

export type ApiEndpoint = {
    /**
     * Wenn dieses Array nicht angegeben ist, können alle eingeloggten Benutzer auf diese Route zugreifen
     */
    allowed_roles?: Array<Role>;
    /**
     * Dies ist die Route, in einem Format wie `/foo/:bar/:somepath*`
     */
    route: string;
};

export type PluginHelper = {
    /**
     * Der Name des Helpers
     */
    name: string;
    /**
     * Die Route, unter der sich der Helper befindet. Diese Route erhält die Argumente als Eingabe und sollte den Wert zurückgeben
     */
    route: string;
    /**
     * Der Typ dieses Helpers
     */
    type: PluginHelperType;
};

export type PluginHelperType = {
    /**
     * Die Typen der Argumente, die dieser Helper erwartet. Die Länge definiert die Anzahl der Argumente
     */
    arguments: Array<VariableType>;
    /**
     * Der Typ des Rückgabewerts dieses Helpers
     */
    return_value: VariableType;
};

export type PluginManifest = {
    /**
     * Der Name des Plugins
     */
    name: PluginName;
    /**
     * Die Version des Plugins
     */
    version: string;
    /**
     * Der Befehl zum Starten des Plugins
     */
    bin: string | null;
    /**
     * Rewriter ist eine Route, die dein Plugin behandelt. Diese Route wird per POST aufgerufen, wann immer
     * eine Seite gerendert wird, mit dem gerenderten HTML im Request-Body. Die Antwort dieser
     * Route wird entweder an das nächste Plugin oder an die Render-Ausgabe weitergeleitet.
     */
    rewriter?: string;
    /**
     * Hier kannst du Routen definieren, die als Handlebars-Helper beim Rendern fungieren
     */
    helpers?: Array<PluginHelper>;
    /**
     * Hier kannst du Routen definieren, die als Seiten verwendet werden, wenn ein Benutzer die Website besucht. Diese
     * Routen haben das Präfix nicht vor ihrem Pfad, wenn sie aufgerufen werden.
     */
    pages?: Array<PluginPage>;
    /**
     * Hier kannst du Routen definieren, die als authentifizierte API-Endpunkte verwendet werden. Der Schlüssel ist die
     * Route, in einem Format wie `/foo/:bar/:somepath*`. Diese Routen haben das Präfix
     * `/api/rest/plugins/<dein-plugin-name>/api`, wenn sie vom Client aufgerufen werden, da sie
     * durch das CMS-Backend weitergeleitet werden.
     */
    api?: Array<ApiEndpoint>;
    /**
     * Dies ist der Pfad, in dem dein Plugin Voreinstellungen für Komponenten definiert. Dieser Pfad muss
     * in deinem gebauten Plugin-Paket enthalten sein. Komponenten müssen in Ordnern mit diesen
     * Dateien bereitgestellt werden: `template.hbs`, `script.js`, `style.css`, `.meta.json` (erforderlich),
     * `form.json` (erforderlich)
     */
    components?: string;
    /**
     * Dies ist der Pfad, in dem dein Plugin Voreinstellungen für Seiten-Layouts definiert. Dieser Pfad muss
     * in deinem gebauten Plugin-Paket enthalten sein. Layouts müssen in Ordnern mit diesen
     * Dateien bereitgestellt werden: `template.hbs`, `script.js`, `style.css`, `.meta.json` (erforderlich)
     */
    layouts?: string;
    /**
     * Diese Route wird als Einstiegspunkt für die Benutzeroberfläche deines Plugins verwendet. Diese Routen haben das
     * Präfix `/api/rest/plugins/<dein-plugin-name>/ui`. Der Zugriff auf diese UI-Routen ist nur
     * auf Benutzer beschränkt, die auch Plugins verwalten können.
     */
    ui?: string;
};

export type PluginName = string;

export type PluginPage = {
    /**
     * Der Name der Seite
     */
    name: string;
    /**
     * Dies ist die Route, in einem Format wie `/foo/:bar/:somepath*`
     */
    route: string;
    /**
     * Erlaubt die Auswahl eines Layouts für diese Seite im CMS. Wenn ein Layout ausgewählt ist,
     * wird die Seite darin gerendert (siehe First Steps -> Seiten-Endpunkt). Standard: false.
     */
    allow_select_layout?: boolean;
    /**
     * Erzeugt Tailwind-Klassen für das ausgewählte Layout. Ohne Wirkung, wenn
     * allow_select_layout nicht aktiviert ist.
     */
    enable_tailwind?: boolean;
};

Routen mit diesem Format /foo/:bar/:somepath* folgen diesen Regeln:

MusterArtBeschreibung
:nameNormalEntspricht einem Pfadstück, schließt / aus
:name?OptionalEntspricht einem optionalen Pfadstück, schließt / aus
/:name?/ /:name?OptionalSegmentEntspricht einem optionalen Pfadsegment, schließt / aus, Präfix oder Suffix sollte / sein
+ :name+OneOrMoreEntspricht einem Pfadstück, inkludiert /
* :name*ZeroOrMoreEntspricht einem optionalen Pfadstück, inkludiert /
/*/ /* /:name*/ /:name*ZeroOrMoreSegmentEntspricht null oder mehr Pfadsegmenten, Präfix oder Suffix sollte / sein
FallParameter
:a:ba b
:a:b?a b
:a-:b :a.:b :a~:ba b
:a_a-:b_ba_a b_b
:a\\: :a\\_a
:a\\::b :a\\_:ba b
:a*a
**1
*.**1 *2
:a+a
++1
+.++1 +2
/*/abc/+/def/g*1 +2