v2.6.0: Content backup/git versioning, plugin type system, docs update

New features:
- ContentBackup class with ZIP backup/restore and git versioning
- Admin backup & restore page (content-backup.twig) with git init/commit/log/restore
- Plugin type system: system (blue) vs content (green) with visual badges
- PluginAPIInterface + AdminPluginAPI for plugin architecture
- Essential plugin flag (cannot edit/deactivate/delete)

Improvements:
- Consolidated enabled_plugins config (removed plugins.enabled)
- Removed Analytics/Logging toggles from admin config page
- Fixed Dashboard plugin Twig comments rendered as text
- Updated 20 guide files (NL+EN): configuratie, plugins, plugin-development,
  core-classes, theme-json, layouts, scss-styling, admin-beheerder, nieuw-thema, architectuur
- Improved accessibility test script (grep -E, min/max checks)

Cleanup:
- Removed unused classes: ARIAComponents, AccessibilityManager, ContentSecurityPolicy, etc.
- Removed vendor packages: mustache/mustache, php-mqtt/client
- Removed old templates: logs.twig, statistics.twig (now plugins)
- Moved language files to language/ directory

Tests:
- Pentest: 30/30 passed, 0 vulnerabilities
- WCAG 2.1 AA: 25/25 passed, 100% compliance
This commit is contained in:
2026-08-15 19:21:04 +02:00
parent cd498c8c3a
commit 1492dcf71f
207 changed files with 3742 additions and 22688 deletions
+36 -39
View File
@@ -1,9 +1,9 @@
<!DOCTYPE html>
<html lang="nl">
<html lang="{{ admin_lang|default('nl') }}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}CodePress Admin{% endblock %}</title>
<title>{% block title %}{{ ta.admin_title|default('CodePress Admin') }}{% endblock %}</title>
<link rel="stylesheet" href="/admin/assets/css/bootstrap.min.css">
<link rel="stylesheet" href="/admin/assets/css/bootstrap-icons.css">
<link rel="stylesheet" href="/admin/assets/css/style.css">
@@ -37,98 +37,95 @@
<body>
<nav class="admin-sidebar d-flex flex-column">
<div class="admin-brand">
<i class="bi bi-gear-fill"></i> CodePress Admin
<i class="bi bi-gear-fill"></i> {{ ta.admin_title|default('CodePress Admin') }}
</div>
<ul class="nav flex-column mt-2">
<li class="nav-section">Algemeen</li>
{# Algemene sectie: Dashboard (plugin) + plugin items met section=general #}
{% set general_plugins = plugin_admin_menu|filter(item => (item.section|default('general')) == 'general') %}
{% if general_plugins is not empty or has_permission('dashboard') or true %}
<li class="nav-section">{{ ta.section_general|default('Algemeen') }}</li>
{% for item in general_plugins %}
<li class="nav-item">
<a class="nav-link {{ route == 'dashboard' or route == '' ? 'active' : '' }}" href="/admin/dashboard">
<i class="bi bi-speedometer2"></i> Dashboard
<a class="nav-link {{ route == item.route or route starts with item.route ~ '/' ? 'active' : '' }}" href="/admin/{{ item.route }}">
<i class="bi {{ item.icon|default('bi-puzzle') }}"></i> {{ item.label|default(item.route) }}
</a>
</li>
{% endfor %}
{% endif %}
{% if has_permission('content') %}
<li class="nav-section">Content</li>
<li class="nav-section">{{ ta.section_content|default('Content') }}</li>
<li class="nav-item">
<a class="nav-link {{ route starts with 'content' ? 'active' : '' }}" href="/admin/content">
<i class="bi bi-file-earmark-text"></i> Content
<i class="bi bi-file-earmark-text"></i> {{ ta.content|default('Content') }}
</a>
</li>
{% endif %}
{% if has_permission('config') or has_permission('theme') or has_permission('security') %}
<li class="nav-section">Instellingen</li>
<li class="nav-section">{{ ta.section_settings|default('Instellingen') }}</li>
{% if has_permission('config') %}
<li class="nav-item">
<a class="nav-link {{ route == 'config' ? 'active' : '' }}" href="/admin/config">
<i class="bi bi-sliders"></i> Configuratie
<i class="bi bi-sliders"></i> {{ ta.configuration|default('Configuratie') }}
</a>
</li>
{% endif %}
{% if has_permission('theme') %}
<li class="nav-item">
<a class="nav-link {{ route == 'theme' ? 'active' : '' }}" href="/admin/theme">
<i class="bi bi-palette"></i> Thema
<i class="bi bi-palette"></i> {{ ta.theme|default('Thema') }}
</a>
</li>
{% endif %}
{% if has_permission('security') %}
<li class="nav-item">
<a class="nav-link {{ route == 'security' ? 'active' : '' }}" href="/admin/security">
<i class="bi bi-shield-check"></i> Beveiliging
<i class="bi bi-shield-check"></i> {{ ta.security|default('Beveiliging') }}
</a>
</li>
{% endif %}
{% endif %}
{% if has_permission('statistics') or has_permission('logs') %}
<li class="nav-section">Gegevens</li>
{% if has_permission('statistics') %}
<li class="nav-item">
<a class="nav-link {{ route == 'statistics' ? 'active' : '' }}" href="/admin/statistics">
<i class="bi bi-bar-chart"></i> Statistieken
</a>
</li>
{% endif %}
{% if has_permission('logs') %}
<li class="nav-item">
<a class="nav-link {{ route == 'logs' ? 'active' : '' }}" href="/admin/logs">
<i class="bi bi-journal-text"></i> Logs
</a>
</li>
{% endif %}
{% endif %}
{% if has_permission('plugins') or has_permission('users') or has_permission('update') %}
<li class="nav-section">Systeem</li>
{# Systeem sectie: core admin items + plugin items met section=system #}
{% set system_plugins = plugin_admin_menu|filter(item => (item.section|default('general')) == 'system') %}
{% if has_permission('plugins') or has_permission('users') or has_permission('update') or system_plugins is not empty %}
<li class="nav-section">{{ ta.section_system|default('Systeem') }}</li>
{% if has_permission('plugins') %}
<li class="nav-item">
<a class="nav-link {{ route == 'plugins' ? 'active' : '' }}" href="/admin/plugins">
<i class="bi bi-plug"></i> Plugins
<i class="bi bi-plug"></i> {{ ta.plugins|default('Plugins') }}
</a>
</li>
{% endif %}
{% if has_permission('users') %}
<li class="nav-item">
<a class="nav-link {{ route == 'users' ? 'active' : '' }}" href="/admin/users">
<i class="bi bi-people"></i> Gebruikers
<i class="bi bi-people"></i> {{ ta.users|default('Gebruikers') }}
</a>
</li>
{% endif %}
{% if has_permission('update') %}
<li class="nav-item">
<a class="nav-link {{ route == 'update' ? 'active' : '' }}" href="/admin/update">
<i class="bi bi-cloud-arrow-down"></i> Update
<i class="bi bi-cloud-arrow-down"></i> {{ ta.update|default('Update') }}
</a>
</li>
{% endif %}
{% for item in system_plugins %}
<li class="nav-item">
<a class="nav-link {{ route == item.route or route starts with item.route ~ '/' ? 'active' : '' }}" href="/admin/{{ item.route }}">
<i class="bi {{ item.icon|default('bi-puzzle') }}"></i> {{ item.label|default(item.route) }}
</a>
</li>
{% endfor %}
{% endif %}
{% if has_permission('guide') %}
<li class="nav-section">Help</li>
<li class="nav-section">{{ ta.section_help|default('Help') }}</li>
<li class="nav-item">
<a class="nav-link {{ route == 'guide' ? 'active' : '' }}" href="/admin/guide">
<i class="bi bi-book"></i> Handleiding
<i class="bi bi-book"></i> {{ ta.guide|default('Handleiding') }}
</a>
</li>
{% endif %}
@@ -137,12 +134,12 @@
<ul class="nav flex-column mt-auto mb-5">
<li class="nav-item">
<a class="nav-link" href="/" target="_blank">
<i class="bi bi-box-arrow-up-right"></i> Website bekijken
<i class="bi bi-box-arrow-up-right"></i> {{ ta.view_website|default('Website bekijken') }}
</a>
</li>
<li class="nav-item">
<a class="nav-link text-warning" href="/admin/logout">
<i class="bi bi-box-arrow-left"></i> Uitloggen
<i class="bi bi-box-arrow-left"></i> {{ ta.logout|default('Uitloggen') }}
</a>
</li>
</ul>