Files
E.Noorlander c2bcd7be22 System plugin support: admin menu items, admin routes, API integration
- PluginManager: getAdminMenuItems(), handleAdminRoute(), getPluginType()
- admin.php: load PluginManager, pass plugin_admin_menu to Twig
- admin.php: route to plugin admin pages via handleAdminRoute()
- admin.twig: show 'Plugins' sidebar section for system plugins
- plugins-new.twig: choose content or system plugin type
- handlePluginsNew: generate proper template based on type (content/system)
- plugin-admin.twig: renders plugin output in admin layout
- GeoIPInfo: example system plugin (admin page with GeoIP info)
- System plugins: getAdminMenu(), getAdminRoutes(), handleAdminRoute()
- Content plugins: getSidebarContent() (unchanged)
2026-08-11 18:06:17 +02:00

150 lines
4.4 KiB
Twig

<!DOCTYPE html>
<html lang="{{ current_lang }}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ page_title }} - {{ site_title }}</title>
<!-- Skip to content link for accessibility -->
<a href="#main-content" class="skip-link sr-only sr-only-focusable">Skip to main content</a>
<!-- CMS Meta Tags -->
<meta name="generator" content="{{ site_title }} CMS">
<meta name="application-name" content="{{ site_title }}">
<meta name="author" content="{{ author_name }}">
<meta name="creator" content="{{ author_name }}">
<meta name="publisher" content="{{ author_name }}">
<!-- SEO Meta Tags -->
<meta name="description" content="{{ seo_description }}">
<meta name="keywords" content="{{ seo_keywords }}">
{% if block_ai_bots %}
<meta name="robots" content="noai, noimageai">
<meta name="tdm-reservation" content="1">
{% endif %}
{% if block_search_engines %}
<meta name="robots" content="noindex, nofollow">
{% endif %}
<!-- Author Links -->
<link rel="author" href="{{ author_website }}">
<link rel="me" href="{{ author_git }}">
<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="{{ theme_base_url }}/assets/img/favicon.ico">
<link rel="icon" type="image/svg+xml" href="{{ theme_base_url }}/assets/img/favicon.svg">
<link rel="apple-touch-icon" href="{{ theme_base_url }}/assets/img/favicon.svg">
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="{{ theme_config.header_color|default('#0a369d') }}">
<!-- Theme CSS -->
{% for cssFile in theme_css_files %}
<link href="{{ cssFile }}" rel="stylesheet">
{% endfor %}
<!-- Compiled theme CSS (if SCSS was used) -->
{% if theme_css_url %}
<link href="{{ theme_css_url }}" rel="stylesheet">
{% endif %}
<!-- Plugin CSS (loaded after theme so theme can override) -->
{% for cssUrl in plugin_css_urls|default([]) %}
<link href="{{ cssUrl }}" rel="stylesheet">
{% endfor %}
<!-- Accessibility styles -->
<style>
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: #000;
color: #fff;
padding: 8px;
text-decoration: none;
z-index: 100;
}
.skip-link:focus {
top: 6px;
outline: 3px solid #0056b3;
outline-offset: 2px;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.sr-only-focusable:focus {
position: static;
width: auto;
height: auto;
padding: inherit;
margin: inherit;
overflow: visible;
clip: auto;
white-space: normal;
}
</style>
<!-- Dynamic theme styles -->
<style>
html {
min-height: 100%;
}
body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
#site-header > * {
position: relative;
z-index: 1;
}
</style>
</head>
<body>
{% include 'partials/header.twig' %}
<nav role="navigation" aria-label="Main navigation" id="site-navigation">
{% include 'partials/navigation.twig' %}
</nav>
<nav id="site-breadcrumb" class="breadcrumb-section bg-light border-bottom" aria-label="Breadcrumb navigation">
<div class="container-fluid">
<div class="row">
<div class="col-12 py-2">
<h2 class="sr-only">Breadcrumb Navigation</h2>
{{ breadcrumb|raw }}
</div>
</div>
</div>
</nav>
<main role="main" id="main-content" class="main-content" style="padding: 0;">
{% block content %}{% endblock %}
</main>
<footer role="contentinfo" id="site-footer">
{% include 'partials/footer.twig' %}
</footer>
<!-- Theme JS -->
{% for jsFile in theme_js_files %}
<script src="{{ jsFile }}"></script>
{% endfor %}
<!-- Theme-specific JS -->
{% if theme_js_url %}
<script src="{{ theme_js_url }}"></script>
{% endif %}
</body>
</html>