Files
CodePress/admin/theme/default/views/layouts/admin.twig
T
E.Noorlander 06beef43d7 v2.6.3 (Lyra): Content multi-type handling, getAllPages() structuur, . verberg-prefix
- Content bestanden met dezelfde naam maar ander type (md/php/html) worden
  correct geserveerd: URL met extensie opent dat bestand, URL zonder extensie
  valt terug op md > php > html (resolveContentByType helper)
- Admin content editor accepteert bestanden met dezelfde naam (ander type);
  preview-knop linkt per extensie
- Frontend navigatie/directory listing/search tonen elk bestandstype apart
- getAllPages() array structuur gewijzigd naar list van
  ['path','title','type'] met type 'md'/'php'/'html'/'folder'
- Verberg-prefix logica: _ is geen verberg-prefix meer, alleen . (en -);
  admin toont wél alle . bestanden/mappen
- ContentAPI getPage()/pageExists() respecteren expliciete extensie
- Handleiding content-api.md (NL+EN) herschreven
- File-tree unificatie: _file-tree.twig + _editor-styles.twig includes
- Versie verhoogd naar 2.6.3
2026-08-20 16:45:53 +00:00

242 lines
14 KiB
Twig

<!DOCTYPE html>
<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 %}{{ 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">
<link rel="stylesheet" href="/plugins/Navigation/assets/css/navigation.css">
<style>
body { background-color: #f5f6fa; min-height: 100vh; }
.admin-sidebar { background-color: {{ sidebar_color|default('#0a369d') }}; height: 100vh; width: 240px; position: fixed; top: 0; left: 0; z-index: 100; overflow-y: auto; }
.admin-sidebar .nav-link { color: rgba(255,255,255,0.8); padding: 0.75rem 1.25rem; border-radius: 0; }
.admin-sidebar .nav-link:hover { color: #fff; background-color: rgba(255,255,255,0.1); }
.admin-sidebar .nav-link.active { color: #fff; background-color: rgba(255,255,255,0.2); border-left: 3px solid #fff; }
.admin-sidebar .nav-link i { width: 24px; text-align: center; margin-right: 0.5rem; }
.admin-sidebar .nav-section { color: rgba(255,255,255,0.4); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; padding: 1rem 1.25rem 0.3rem 1.25rem; }
.admin-main { margin-left: 240px; padding: 2rem; }
.admin-brand { color: #fff; padding: 1.25rem; font-size: 1.1rem; border-bottom: 1px solid rgba(255,255,255,0.15); }
.admin-brand i { margin-right: 0.5rem; }
.stat-card { border: none; border-radius: 0.5rem; }
.stat-card .stat-icon { font-size: 2rem; opacity: 0.7; }
.admin-user { color: rgba(255,255,255,0.6); padding: 0.75rem 1.25rem; font-size: 0.85rem; border-top: 1px solid rgba(255,255,255,0.15); }
@media (max-width: 768px) {
.admin-sidebar { width: 100%; height: auto; position: relative; }
.admin-main { margin-left: 0; }
}
</style>
{% if needs_editor %}
<link rel="stylesheet" href="/admin/assets/codemirror/codemirror.min.css">
<link rel="stylesheet" href="/admin/assets/css/editor.css">
{% endif %}
{% block extra_css %}{% endblock %}
</head>
<body>
<nav class="admin-sidebar" id="adminSidebar">
<div class="admin-brand">
<i class="bi bi-gear-fill"></i> {{ ta.admin_title|default('CodePress Admin') }}
</div>
<ul class="nav flex-column mt-2">
{# Algemene sectie: Dashboard (altijd zichtbaar) + plugin items met section=general #}
{% set general_plugins = plugin_admin_menu|filter(item => (item.section|default('general')) == 'general' and item.route != 'dashboard' and (item.permission is not defined or item.permission == 'dashboard' or has_permission(item.permission)) and (item.required_roles is not defined or user_role == 'admin' or user_role in item.required_roles)) %}
<li class="nav-section">{{ ta.section_general|default('Algemeen') }}</li>
<li class="nav-item">
<a class="nav-link {{ route == 'dashboard' or route == '' ? 'active' : '' }}" href="/admin/dashboard">
<i class="bi bi-speedometer2"></i> {{ ta.dashboard|default('Dashboard') }}
</a>
</li>
{% for item in general_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> {{ plugin_menu_label(item) }}
</a>
</li>
{% endfor %}
{% if has_permission('content') %}
<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> {{ ta.content|default('Content') }}
</a>
</li>
{% endif %}
{% if has_permission('config') or has_permission('theme') or has_permission('security') %}
<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> {{ 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> {{ 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> {{ ta.security|default('Beveiliging') }}
</a>
</li>
{% endif %}
{% endif %}
{# Systeem sectie: core admin items + plugin items met section=system #}
{% set system_plugins = plugin_admin_menu|filter(item => (item.section|default('general')) == 'system' and (item.permission is not defined or item.permission == 'dashboard' or has_permission(item.permission)) and (item.required_roles is not defined or user_role == 'admin' or user_role in item.required_roles)) %}
{% 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> {{ 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> {{ 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> {{ 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> {{ plugin_menu_label(item) }}
</a>
</li>
{% endfor %}
{% endif %}
{% if has_permission('guide') %}
<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> {{ ta.guide|default('Handleiding') }}
</a>
</li>
{% endif %}
</ul>
<ul class="nav flex-column mt-3 mb-4">
{% if user_real_role == 'admin' %}
<li class="nav-item">
<a class="nav-link" href="#" data-bs-toggle="modal" data-bs-target="#roleSwitchModal">
<i class="bi bi-person-bounding-box"></i>
{% if has_role_override %}
{{ ta.role_testing|default('Testen') }}: {{ role_label(user_role) }}
{% else %}
{{ ta.role_switch|default('Rol wisselen') }}
{% endif %}
</a>
</li>
{% endif %}
<li class="nav-item">
<a class="nav-link" href="/" target="_blank">
<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> {{ ta.logout|default('Uitloggen') }}
</a>
</li>
</ul>
<div class="admin-user">
<i class="bi bi-person-circle"></i> {{ user.username|default('') }}
<br><small>{{ role_label(user_role)|default('') }}{% if has_role_override %} <span class="badge bg-warning text-dark">{{ ta.role_testing|default('Test') }}</span>{% endif %}</small>
</div>
</nav>
{# Role switch modal (only rendered for real admins) #}
{% if user_real_role == 'admin' %}
<div class="modal fade" id="roleSwitchModal" tabindex="-1" aria-labelledby="roleSwitchModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form method="POST" action="/admin/{% if has_role_override %}role-reset{% else %}role-switch{% endif %}">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<div class="modal-header">
<h5 class="modal-title" id="roleSwitchModalLabel">
<i class="bi bi-person-bounding-box"></i>
{% if has_role_override %}{{ ta.role_reset_title|default('Rol terugzetten') }}{% else %}{{ ta.role_switch_title|default('Rol wisselen') }}{% endif %}
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{% if has_role_override %}
<p>{{ ta.role_override_active|default('Je test momenteel als') }}: <strong>{{ role_label(user_role) }}</strong></p>
<p class="text-muted small">{{ ta.role_reset_help|default('Klik hieronder om terug te keren naar je admin rol.') }}</p>
{% else %}
<p>{{ ta.role_switch_help|default('Test de admin vanuit een andere rol. Je echte account blijft admin.') }}</p>
<div class="mb-3">
<label for="role_switch_select" class="form-label">{{ ta.new_role|default('Nieuwe rol') }}</label>
<select class="form-select" id="role_switch_select" name="new_role">
{% for roleKey, roleLabel in roles|default([]) %}
{% if roleKey != 'admin' %}
<option value="{{ roleKey }}">{{ roleLabel }}</option>
{% endif %}
{% endfor %}
</select>
</div>
{% endif %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">{{ ta.cancel|default('Annuleren') }}</button>
<button type="submit" class="btn btn-primary">
{% if has_role_override %}<i class="bi bi-arrow-counterclockwise"></i> {{ ta.role_reset_btn|default('Terug naar admin') }}{% else %}<i class="bi bi-check-lg"></i> {{ ta.role_switch_btn|default('Wissel naar rol') }}{% endif %}
</button>
</div>
</form>
</div>
</div>
</div>
{% endif %}
<main class="admin-main">
{% if message is defined and message %}
<div class="alert alert-{{ message_type|default('info') }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endif %}
{% block content %}{% endblock %}
</main>
{% if needs_editor %}
{% include 'pages/_media-modal.twig' %}
{% endif %}
<script src="/admin/assets/js/bootstrap.bundle.min.js"></script>
{% if needs_editor %}
<script src="/admin/assets/codemirror/codemirror.min.js"></script>
<script src="/admin/assets/codemirror/mode/markdown.min.js"></script>
<script src="/admin/assets/codemirror/mode/xml.min.js"></script>
<script src="/admin/assets/codemirror/mode/css.min.js"></script>
<script src="/admin/assets/codemirror/mode/javascript.min.js"></script>
<script src="/admin/assets/codemirror/mode/htmlmixed.min.js"></script>
<script src="/admin/assets/codemirror/mode/php.min.js"></script>
<script src="/admin/assets/codemirror/mode/clike.min.js"></script>
<script src="/admin/assets/codemirror/addon/edit/closebrackets.min.js"></script>
<script src="/admin/assets/codemirror/addon/selection/active-line.min.js"></script>
<script src="/admin/assets/js/editor-toolbar.js"></script>
{% endif %}
{% block extra_js %}{% endblock %}
</body>
</html>