The share image and featured image of a page become image fields with the library dialog, as do image settings of plugins. The editor offers forms, sections, categories and tags as lists, a page search next to every link target and in text links, the redirect target has a page search, and the form editor picks the reply field, the condition and the option images. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
86 lines
6.1 KiB
Twig
86 lines
6.1 KiB
Twig
{% extends 'admin/shell.html.twig' %}
|
||
{% set nav = 'plugins' %}
|
||
{% block title %}Plugins{% endblock %}
|
||
{% block heading %}Plugins{% endblock %}
|
||
{% block styles %}<link rel="stylesheet" href="/assets/media-dialog.css?v={{ kant_version() }}">{% endblock %}
|
||
{% block scripts %}<script type="module" src="/assets/media-field.js?v={{ kant_version() }}"></script>{% endblock %}
|
||
{% block lead %}Erweiterungen bringen eigene Bausteine, Vorlagen und Adressen mit. Sie liegen als Ordner unter <code>plugins/</code>; hier schaltest du sie ein und aus und stellst sie ein. Ein ausgeschaltetes Plugin lässt seine Bausteine in den Seiten stehen, zeigt sie aber nicht mehr.{% endblock %}
|
||
|
||
{# Ein Feld aus dem Schema eines Plugins - dieselben sieben Arten wie im Editor. #}
|
||
{% macro feld(plugin, key, schema, value) %}
|
||
{% set id = 'plugin-' ~ plugin ~ '-' ~ key %}
|
||
{% set name = 'settings[' ~ key ~ ']' %}
|
||
{% if schema.kind == 'media' %}
|
||
<div>{% include 'admin/media-field.html.twig' with {id: id, name: name, label: schema.label, value: value|default(''), help: schema.help|default('')} only %}</div>
|
||
{% elseif schema.kind == 'boolean' %}
|
||
<div><label class="check-label" for="{{ id }}"><input id="{{ id }}" type="checkbox" name="{{ name }}" value="1"{{ value ? ' checked' : '' }}> {{ schema.label }}</label>{% if schema.help %}<p class="field-help">{{ schema.help }}</p>{% endif %}</div>
|
||
{% else %}
|
||
<div>
|
||
<label for="{{ id }}">{{ schema.label }}</label>
|
||
{% if schema.kind == 'textarea' %}<textarea id="{{ id }}" name="{{ name }}" rows="3" maxlength="{{ schema.maxLength }}">{{ value }}</textarea>
|
||
{% elseif schema.kind == 'select' %}<select id="{{ id }}" name="{{ name }}">{% for wert, text in schema.choices %}<option value="{{ wert }}"{{ value == wert ? ' selected' : '' }}>{{ text }}</option>{% endfor %}</select>
|
||
{% elseif schema.kind == 'number' %}<input id="{{ id }}" name="{{ name }}" type="number" step="any" min="{{ schema.min }}" max="{{ schema.max }}" value="{{ value }}">
|
||
{% else %}<input id="{{ id }}" name="{{ name }}" value="{{ value }}" maxlength="{{ schema.maxLength }}">{% endif %}
|
||
{% if schema.help %}<p class="field-help">{{ schema.help }}</p>{% endif %}
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% block content %}
|
||
{% import _self as f %}
|
||
{% if plugins is empty %}
|
||
<div class="empty"><h3>Keine Plugins gefunden.</h3><p>Ein Plugin ist ein Ordner unter <code>{{ directory }}</code> mit einer <code>plugin.json</code>. Wie eine aussieht, steht in <code>docs/PLUGINS.md</code>.</p></div>
|
||
{% else %}
|
||
<div class="rows">
|
||
{% for plugin in plugins %}
|
||
<article class="row row-top">
|
||
<div class="row-main">
|
||
<h2>{{ plugin.title }} <span class="count">{{ plugin.version }}</span></h2>
|
||
{% if plugin.description %}<p>{{ plugin.description }}</p>{% endif %}
|
||
{% if plugin.error %}
|
||
<p class="field-error">Nicht ladbar: {{ plugin.error }}</p>
|
||
{% else %}
|
||
<p class="muted">Ordner <code>plugins/{{ plugin.name }}</code>{% if plugin.requires %} · braucht KantSites {{ plugin.requires }}{% endif %}{% if plugin.active and plugin.activatedVersion and plugin.activatedVersion != plugin.version %} · seit dem Einschalten aktualisiert (war {{ plugin.activatedVersion }}){% endif %}</p>
|
||
<dl class="submission-data">
|
||
{% for block in plugin.blocks %}
|
||
<dt>{{ block.icon }} {{ block.label }}</dt>
|
||
<dd><code>{{ block.type }}</code>{% if block.description %} – {{ block.description }}{% endif %} · {{ block.props|length }} {{ block.props|length == 1 ? 'Eigenschaft' : 'Eigenschaften' }}{% if block.container %} · Container{% if block.children %} für {{ block.children|join(', ') }}{% endif %}{% endif %}{% if block.css %} · Stylesheet{% endif %}{% if block.script %} · Skript{% endif %}</dd>
|
||
{% endfor %}
|
||
{% for preset in plugin.presets %}
|
||
<dt>⬡ Vorlage „{{ preset.label }}“</dt>
|
||
<dd>{{ preset.description ?: 'Seitenvorlage für den Editor' }} · {{ preset.blocks|length }} {{ preset.blocks|length == 1 ? 'Baustein' : 'Bausteine' }}</dd>
|
||
{% endfor %}
|
||
{% for route in plugin.routes %}
|
||
<dt>↗ Adresse</dt>
|
||
<dd>{% if plugin.active %}<a href="{{ route.path }}">{{ route.path }}</a>{% else %}<code>{{ route.path }}</code>{% endif %} · {{ route.type }}</dd>
|
||
{% endfor %}
|
||
</dl>
|
||
{% if plugin.active and plugin.settings is not empty %}
|
||
<form method="post" action="{{ path('admin_plugin_settings', {name: plugin.name}) }}" class="plugin-settings">
|
||
<input type="hidden" name="_csrf_token" value="{{ csrf_token('plugins') }}">
|
||
<h3 class="form-part">Einstellungen</h3>
|
||
<div class="fields">
|
||
{% for key, schema in plugin.settings %}{{ f.feld(plugin.name, key, schema, plugin.values[key]|default('')) }}{% endfor %}
|
||
</div>
|
||
<button class="secondary" type="submit">Einstellungen speichern</button>
|
||
</form>
|
||
{% endif %}
|
||
{% endif %}
|
||
</div>
|
||
<div class="row-side">
|
||
<span class="pill {{ plugin.active ? 'pill-live' : 'pill-off' }}">{{ plugin.active ? 'Eingeschaltet' : 'Aus' }}</span>
|
||
{% if not plugin.error %}
|
||
<form method="post" action="{{ path('admin_plugin_toggle', {name: plugin.name, state: plugin.active ? 'aus' : 'an'}) }}">
|
||
<input type="hidden" name="_csrf_token" value="{{ csrf_token('plugins') }}">
|
||
<button class="{{ plugin.active ? 'secondary' : 'primary' }}" type="submit">{{ plugin.active ? 'Ausschalten' : 'Einschalten' }}</button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
</article>
|
||
{% endfor %}
|
||
</div>
|
||
{% endif %}
|
||
<p class="field-help">Plugin-Vorlagen laufen mit den Rechten der Website – es gibt keinen Sandkasten. Installiere nur, was du gelesen hast. Farben, Schriften und Buttons änderst du ausschließlich unter Design – ein Plugin fasst sie nicht an.</p>
|
||
<p class="footnote">KantSites · Arbeitsstand</p>
|
||
{% endblock %}
|