Zum Hauptinhalt springen

Handhabung statischer Dateien

Open2C bietet einen komfortablen Weg, um statische CSS- oder JS-Dateien genau dann im Frontend einzubinden, wenn sie benötigt werden.

Das ist insbesondere für Plugin- und Theme-Autoren interessant, die auf diese Art benötigte statische Dateien zielgenau in der HTML-Ausgabe nachladen können, ohne z.B. die Templates anzupassen oder über Hooks in den PHP-Output eingreifen zu müssen.

Kern sind Dateien namens statics.json, die im Stammverzeichnis eines Plugins oder Themes hinterlegt werden können und nach der Aktivierung automatisch von Open2C ausgelesen werden.

In diesen statics.json-Dateien hinterlegen Entwickler Frontend-Abhängigkeiten, die sie verwenden wollen. Ein einfacher Eintrag in einem Plugin <DOCROOT>/plugins/my_plugin/statics.json sieht z.B. so aus:

{
"my_plugin_styles.css": {
"path": "PLUGIN/statics/my_plugin_styles.css"
}
}

Der Platzhalter PLUGIN wird beim Auslesen durch die korrekte URL in das Pluginverzeichnis ersetzt.

Soll die CSS-Datei verwendet werden, z.B. weil die Einbettung eines dazugehörigen Actioncodes entdeckt wurde, wird im PHP-Code des Plugins notiert:

global $o2c_info;
$o2c_info->requireStaticFile('my_plugin_styles.css');

Alles weitere, z.B. die Ausgabe im HTML und das Hinzufügen eines Cache-Busters, übernimmt Open2C automatisch.

Aufbau einer statics.json-Datei

statics.json-Dateien liegen im Stammverzeichnis von Plugins und Themes. Sie werden dort von Open2C automatisch gefunden und gelesen, sofern ein Plugin aktiviert wurde oder es sich um das aktuell aktive Theme handelt.

Der Aufbau ist stets gleich: Ein Root-Objekt hat die Identifier als Properties, die dann im PHP-Code referenziert werden:

{
"lib1": {...},
"lib2": {...},
"lib3": {...}
}

Jeder dieser Einträge ist wiederum ein Objekt mit einem oder mehreren der folgenden Eigenschaften:

EigenschaftBedeutung
#Kommentarfeld. Wird ignoriert, erlaubt aber, einen Entwicklerkommentar anzugeben.
aliasAlias-Namen, unter denen diese Bibliothek auch eingebettet werden kann.
asyncJS-Ressource: Setze das async-Attribut beim einbettenden <script>.
compressErlaubt es, die Ressource von Kompressor-Plugins auszunehmen, die andererseits statische Daten serverseitig zusammenfassen.
deferJS-Ressource: Setze das defer-Attribut beim einbettenden <script>.
moduleJS-Ressource: Setze type="module" beim einbettenden <script>.
pathPfad auf dem Server. Der Pfad wird relativ zum Docroot ausgewertet. Die Platzhalter PLUGIN und THEME werden jeweils durch den Pfad zum aktiven Plugin/Theme ersetzt.
requiresErlaubt es, andere statische Ressourcen als Voraussetzungen zu definieren. Diese werden automatisch von Open2C ebenfalls geladen und vor der aktuellen Ressource eingebunden.
typeArt der Ressource. Wenn nicht angegeben, wird der Wert aus dem Dateinamen von path bestimmt. Kann die Werte js, js-head (JavaScript im <head>) und css haben.
urlURL zur Ressource. Nicht notwendig, wenn path angegeben wurde. Erlaubt das Einbinden von 3rd-party-Bibliotheken oder CDNs.
warn_on_useErlaubt es, Seitenbesitzer darauf hinzuweisen, dass dieses Paket nicht mehr verwendet werden soll.

Eine vollständige statics.json-Datei findet man in Open2C-Installationen unter dem Pfad config/statics.json. Dort sind alle von Open2C mitgelieferten statischen Dateien referenziert.

Zur Validierung einer statics.json-Datei lässt sich das folgende offizielle JSON-Schema verwenden: https://dokumentation.open2c.de/schema/statics.json .

Tipps und Rezepte

Metapakete

Für viele Features ist der benötigte Frontend-Code aufgespalten in eine CSS- und eine JS-Datei. Um diese mit einer einzigen Anweisung immer zusammen einzubinden, bietet es sich an ein Metapaket dazu zu definieren. Das ist ein Eintrag, der selbst kein path- oder url-Feld hat, aber weitere Pakete „nachlädt“.

Beispiel:

{
"my_feature": {
"requires": ["my_feature.css", "my_feature.js"]
},
"my_feature.css": {
"path": "PLUGIN/statics/my_feature.css"
},
"my_feature.js": {
"path": "PLUGIN/statics/my_feature.js"
}
}

Mit dieser Definition lassen sich beide Dateien stets synchron einbinden:

// lädt sowohl CSS als auch JS
$o2c_info->requireStaticFile('my_feature');

Abhängigkeiten definieren

Manche Pakete sind von anderen statischen Dateien abhängig. Ein oft benötigtes Beispiel dafür ist die jQuery-Bibliothek. Diese Abhängigkeiten können in der statics.json-Datei angegeben werden und werden dann bei Bedarf von Open2C automatisch aufgelöst und verwendet.

Beispiel:

{
"some_jquery_plugin.js": {
"requires": ["jquery"],
"path": "THEME/statics/some_jquery_plugin.js"
}
}

Automatisch Theme-Dateien einbinden

Benötigt ein Theme zusätzliche CSS- oder JS-Dateien außer der automatisch eingebundenen style.css, können diese Abhängigkeiten mit einer statics.json-Angabe eingebunden werden, ohne Templates oder PHP-Code anzupassen. Dafür wird das spezielle Ziel „theme“ verwendet.

Beispiel:

{
"theme": {
"requires": ["main.js", "other.css"]
},
"main.js": {
"path": "THEME/main.js"
}
"other.css": {
"path": "THEME/statics/other.css"
}
}

Externe Dateien laden

Werden externe Abhängigkeiten benötigt, z.B. Google Maps oder eine Analytics-Lösung, können diese ebenfalls mit den Mechanismen der statics.json-Dateien verwaltet werden.

Beispiel: Laden von React v18.

{
"react": {
"url": "https://unpkg.com/react@18.2.0/umd/react.production.min.js",
"type": "js"
},
"my_react_app": {
"requires": ["react"],
"path": "PLUGIN/statics/my_react_app.js"
}
}

Beachten Sie die Angabe von "type". Normalerweise bestimmt Open2C den Typ automatisch aus der Dateiendung. Da wir aber sichergehen wollen, dass bei einem Update der URL diese auch dann noch als JavaScript erkannt wird, wenn sie nicht mehr auf .js endet, fügen wir den Typ explizit bei.

Überschreiben von Paketen

Werden andere Versionen einer von Open2C oder einem Plugin mitgelieferten Datei benötigt, kann man diese dadurch laden, dass man den statics.json-Eintrag an geeigneter Stelle überschreibt.

Beispiel: Open2C liefert jQuery in Version 3.7.1 aus, ein Plugin benötigt aber jQuery v3.8.0. Das Plugin liefert dann die entsprechende jQuery-Datei selbst mit und überschreibt den Pfad in seiner eigenen statics.json-Datei:

{
"jquery": {
"#": "Wir überschreiben jQuery mit unserer eigenen Version hier",
"alias": ["jQuery", "jquery.js"],
"compress": "nocompress",
"type": "js",
"path": "PLUGIN/statics/jquery_3.8.0.js"
},
}

:::Achtung Wichtig!

Wenn Sie eine mitgelieferte Bibliothek auf diese Art überschreiben, ist es möglich, dass dadurch nicht rückwärtskompatible Änderungen eingeführt werden, die die Funktionsweise von anderen Plugins oder Open2C-Kernfeatures beeinträchtigen.

Darüber hinaus werden bei einem späteren Upgrade von Open2C ggf. neuere mitgelieferte Versionen der Bibliothek ignoriert.

:::

JavaScript im <head> ausgeben

Einige Anwendungen, z.B. Consent Manager für Cookie-Banner, erfordern, dass ihr JavaScript im <head>-Bereich der Seite ausgegeben wird. Dies kann durch explizite Angabe des Typs js-head erzwungen werden.

Beispiel:

{
"cookie_consent": {
"type": "js-head",
"url": "https://example.com/cookie_consent.js"
}
}

Alle JS-Abhängigkeiten, die diesen Typ nicht gesetzt haben, werden im Template erst am Ende kurz vor dem schließenden </body> ausgegeben.

JavaScript-Module verwenden

Neuere Brower unterstützen JavaScript-Module zur Kapselung von JS-Code. Diese müssen allerdings mit der Anweisung <script type="module"> im HTML geladen werden. Um das zu erzwingen, gibt es die Anweisung module.

Beispiel:

{
"my_module": {
"path": "PLUGIN/statics/modules/main.js",
"module": true
}
}

Dadurch wird der Code als Modul geladen:

<script type="module" src="/plugins/my_plugin/statics/modules/main.js"></script>

Diese Anweisung hat bei CSS-Abhängigkeiten keine Auswirkung.

Kleine Schnippsel ohne eigene Datei einfügen

Gelegentlich wird nur eine minimale Menge an JS oder CSS für ein Feature benötigt. Um dies in eine Seite einzubauen ohne eine ganze Datei dafür anzulegen, unterstützen statics.json-Dateien die beiden Pseudoprotokolle javascript: und css:.

Beispiel:

{
"minimal_js": {
"url": "javascript:console.log('hallo welt!');"
},
"minimal_css": {
"url": "css:body { background: pink !important; }"
}
}

Pakete als veraltet kennzeichnen

Wenn eine statische Datei in einem Plugin ausgeliefert wird und von anderen Plugins oder Themes verwendet wird, kann der Pluginautor verwendende Seiten warnen, falls die statische Datei veraltet ist und in zukünftigen Versionen nicht mehr unterstützt wird.

Beispiel:

{
"outdated.js": {
"warn_on_use": "Dieses Paket wird nicht mehr unterstützt und in der nächsten Version entfernt werden. Bitte ändern Sie Ihren Code!",
"path": "PLUGIN/statics/war_frueher_fancy.js"
}
}

Der Warnhinweis wird dann im Error-Log ausgegeben jedes Mal, wenn die statische Datei eingebunden wird.

Upgrade-Hinweise

Open2C v3.54

  1. In dieser Version von Open2C wurde jQuery als Standardabhängigkeit des Frontends entfernt. Open2C liefert immer noch eine gebündelte Version von jQuery mit, die mit

    "requires": ["jquery"]

    von jedem Paket angefordert werden kann.

    Frontend-Code, der sich bislang auf die Anwesenheit von jQuery verlassen hat, muss daraufhin überprüft werden, dass diese Abhängigkeit auch korrekt angegeben wurde.

    Wird Frontend-Code anders eingebettet, z.B. via direktem Einbinden in Templates, empfehlen wir, die Einbettung auf die statics.json-Methode umzuschreiben. Ist das nicht möglich, kann das jquery-Paket auch als Abhängigkeit des Metapakets theme angegeben werden, um jquery unkonditional immer zu laden. Dazu wird im Theme-Ordner eine statics.json mit folgendem Inhalt angelegt:

    {
    "theme": {
    "requires": ["jquery"]
    }
    }
  2. Mehrere historisch mitgelieferte Pakete wurden als veraltet gekennzeichnet und mit einer warn_on_use-Warnung versehen:

    • swfobject
    • html5shiv
    • iosorientationfix.js
    • chosen