Plugin sidebar order + directory layout from index.md

- PluginManager: iterate allowedPlugins in user-defined order (frontmatter order)
- content-edit.twig: plugin list with up/down arrows to set order
- Directory listing: read layout/plugins from index.md if present
- Directory default layout: full_content (no sidebar) unless index.md says otherwise
This commit is contained in:
2026-08-11 17:04:27 +02:00
parent 342112cd21
commit 03a14126ca
4 changed files with 143 additions and 33 deletions
@@ -29,13 +29,33 @@
</div>
{% if availablePlugins is not empty %}
<div class="col-md-4">
<label class="form-label d-block">Zichtbare plugins</label>
<div class="d-flex flex-wrap gap-1">
{% for plugin in availablePlugins %}
<input type="checkbox" class="btn-check" id="plugin-{{ plugin }}" name="plugins[]" value="{{ plugin }}" autocomplete="off" {{ plugin in selectedPlugins ? 'checked' : '' }}>
<label class="btn btn-outline-primary btn-sm" for="plugin-{{ plugin }}">{{ plugin }}</label>
<label class="form-label d-block">Zichtbare plugins (volgorde = sidebar volgorde)</label>
<ul class="list-group list-group-flush" id="plugin-order-list">
{% for plugin in selectedPlugins %}
<li class="list-group-item d-flex align-items-center justify-content-between px-2 py-1" data-plugin="{{ plugin }}">
<div class="form-check">
<input type="checkbox" class="form-check-input" id="plugin-{{ plugin }}" name="plugins[]" value="{{ plugin }}" autocomplete="off" checked>
<label class="form-check-label" for="plugin-{{ plugin }}">{{ plugin }}</label>
</div>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-outline-secondary py-0 px-1 plugin-up" title="Omhoog"><i class="bi bi-arrow-up"></i></button>
<button type="button" class="btn btn-outline-secondary py-0 px-1 plugin-down" title="Omlaag"><i class="bi bi-arrow-down"></i></button>
</div>
</li>
{% endfor %}
</div>
{% for plugin in availablePlugins if plugin not in selectedPlugins %}
<li class="list-group-item d-flex align-items-center justify-content-between px-2 py-1" data-plugin="{{ plugin }}">
<div class="form-check">
<input type="checkbox" class="form-check-input" id="plugin-{{ plugin }}" name="plugins[]" value="{{ plugin }}" autocomplete="off">
<label class="form-check-label" for="plugin-{{ plugin }}">{{ plugin }}</label>
</div>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-outline-secondary py-0 px-1 plugin-up" title="Omhoog"><i class="bi bi-arrow-up"></i></button>
<button type="button" class="btn btn-outline-secondary py-0 px-1 plugin-down" title="Omlaag"><i class="bi bi-arrow-down"></i></button>
</div>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% endif %}
@@ -119,6 +139,36 @@ document.addEventListener('DOMContentLoaded', function () {
}
window.__onContentChange = markChanged;
// Plugin order: move list items up/down
var pluginList = document.getElementById('plugin-order-list');
if (pluginList) {
pluginList.addEventListener('click', function (e) {
var upBtn = e.target.closest('.plugin-up');
var downBtn = e.target.closest('.plugin-down');
if (!upBtn && !downBtn) return;
var item = e.target.closest('li[data-plugin]');
if (!item) return;
if (upBtn && item.previousElementSibling) {
pluginList.insertBefore(item, item.previousElementSibling);
markChanged();
} else if (downBtn && item.nextElementSibling) {
pluginList.insertBefore(item, item.nextElementSibling.nextElementSibling);
markChanged();
}
});
// On form submit, reorder the checkboxes to match the visual order
var form = document.getElementById('editor-form');
if (form) {
form.addEventListener('submit', function () {
// The DOM order of the <li> elements already determines the form submission order
// because the checkboxes are inside the <li> elements
});
}
}
});
</script>
{% endblock %}