v2.6.1d (Lyra): Plugin i18n, plugin editor vernieuwd, media invoegen
Plugin internationalisatie: plugins hebben eigen language/ mappen. Systeem plugins volgen admin taal (admin.php), content plugins volgen content taal (site.php). Fallback chain: geselecteerd -> plugin default_language -> CMS default. PluginManager/AdminPluginAPI/CMSAPI uitgebreid met getPluginTranslations()/t(). plugin.json settings ondersteunen label_key/help_key/option_label_key. Plugin uniformiteit: alle 6 plugins hebben uniforme structuur (README.md, assets/.gitkeep, language/nl|en/). plugins/README.md herschreven. guide plugin-development.md (NL+EN) volledig herschreven. Plugin editor vernieuwd: geneste bestandsbrowser zijbalk, nieuw bestand aanmaken, uploaden naar assets/, verwijderen en verplaatsen. Nieuwe routes: plugins-file-upload, plugins-file-delete, plugins-file-move. Path-traversal bescherming + protected plugins geblokkeerd. Media invoegen in editor: nieuw /admin/media-list JSON endpoint + herbruikbare _media-modal.twig include. Plugin-context scant assets/ map. editor-toolbar.js modeMap uitgebreid voor css/scss/js/json. Plugin overzicht knoppen: alleen iconen met title/aria-label. Tests: pentest 30/30, WCAG 2.1 AA 25/25.
This commit is contained in:
@@ -25,8 +25,10 @@ class Dashboard
|
||||
'plugin' => 'Dashboard',
|
||||
'route' => 'dashboard',
|
||||
'label' => 'Dashboard',
|
||||
'label_key' => 'menu_label',
|
||||
'icon' => 'bi-speedometer2',
|
||||
'section' => 'general',
|
||||
'permission' => 'dashboard',
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -39,6 +41,12 @@ class Dashboard
|
||||
$enabledPlugins = $this->api ? $this->api->getEnabledPlugins() : [];
|
||||
$versionInfo = $this->api ? $this->api->getVersionInfo() : ['version' => '0.0.0'];
|
||||
|
||||
// Plugin translations (admin context). Falls back to plugin default_language.
|
||||
$t = $this->api ? $this->api->getPluginTranslations('Dashboard') : [];
|
||||
$tr = function (string $key) use ($t): string {
|
||||
return $t[$key] ?? $key;
|
||||
};
|
||||
|
||||
$stats = [
|
||||
'pages' => $this->countFiles($contentDir, ['md', 'php', 'html']),
|
||||
'directories' => $this->countDirs($contentDir),
|
||||
@@ -68,20 +76,20 @@ class Dashboard
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<h2 class="mb-4"><i class="bi bi-speedometer2"></i> Dashboard</h2>
|
||||
<h2 class="mb-4"><i class="bi bi-speedometer2"></i> <?= htmlspecialchars($tr('page_title')) ?></h2>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-md-6">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header"><i class="bi bi-info-circle"></i> Site informatie</div>
|
||||
<div class="card-header"><i class="bi bi-info-circle"></i> <?= htmlspecialchars($tr('site_info')) ?></div>
|
||||
<div class="card-body">
|
||||
<table class="table table-sm mb-0">
|
||||
<tr><td class="text-muted">Site titel</td><td><?= htmlspecialchars($siteTitle) ?></td></tr>
|
||||
<tr><td class="text-muted">Standaard taal</td><td><?= htmlspecialchars($defaultLang) ?></td></tr>
|
||||
<tr><td class="text-muted">CodePress versie</td><td><?= htmlspecialchars($stats['cms_version']) ?></td></tr>
|
||||
<tr><td class="text-muted">PHP versie</td><td><?= htmlspecialchars($stats['php_version']) ?></td></tr>
|
||||
<tr><td class="text-muted">Besturingssysteem</td><td><?= htmlspecialchars($stats['os']) ?></td></tr>
|
||||
<tr><td class="text-muted">Config geladen</td><td><?php if ($stats['config_exists']): ?><span class="badge bg-success">Ja</span><?php else: ?><span class="badge bg-danger">Nee</span><?php endif; ?></td></tr>
|
||||
<tr><td class="text-muted"><?= htmlspecialchars($tr('site_title')) ?></td><td><?= htmlspecialchars($siteTitle) ?></td></tr>
|
||||
<tr><td class="text-muted"><?= htmlspecialchars($tr('default_lang')) ?></td><td><?= htmlspecialchars($defaultLang) ?></td></tr>
|
||||
<tr><td class="text-muted"><?= htmlspecialchars($tr('cms_version')) ?></td><td><?= htmlspecialchars($stats['cms_version']) ?></td></tr>
|
||||
<tr><td class="text-muted"><?= htmlspecialchars($tr('php_version')) ?></td><td><?= htmlspecialchars($stats['php_version']) ?></td></tr>
|
||||
<tr><td class="text-muted"><?= htmlspecialchars($tr('os')) ?></td><td><?= htmlspecialchars($stats['os']) ?></td></tr>
|
||||
<tr><td class="text-muted"><?= htmlspecialchars($tr('config_loaded')) ?></td><td><?php if ($stats['config_exists']): ?><span class="badge bg-success"><?= htmlspecialchars($tr('yes')) ?></span><?php else: ?><span class="badge bg-danger"><?= htmlspecialchars($tr('no')) ?></span><?php endif; ?></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -89,12 +97,12 @@ class Dashboard
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header"><i class="bi bi-folder2-open"></i> Content informatie</div>
|
||||
<div class="card-header"><i class="bi bi-folder2-open"></i> <?= htmlspecialchars($tr('content_info')) ?></div>
|
||||
<div class="card-body">
|
||||
<table class="table table-sm mb-0">
|
||||
<tr><td class="text-muted">Pagina's</td><td><span class="badge bg-primary"><?= $stats['pages'] ?></span></td></tr>
|
||||
<tr><td class="text-muted">Mappen</td><td><span class="badge bg-warning text-dark"><?= $stats['directories'] ?></span></td></tr>
|
||||
<tr><td class="text-muted">Content grootte</td><td><?= htmlspecialchars($stats['content_size']) ?></td></tr>
|
||||
<tr><td class="text-muted"><?= htmlspecialchars($tr('pages')) ?></td><td><span class="badge bg-primary"><?= $stats['pages'] ?></span></td></tr>
|
||||
<tr><td class="text-muted"><?= htmlspecialchars($tr('folders')) ?></td><td><span class="badge bg-warning text-dark"><?= $stats['directories'] ?></span></td></tr>
|
||||
<tr><td class="text-muted"><?= htmlspecialchars($tr('content_size')) ?></td><td><?= htmlspecialchars($stats['content_size']) ?></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -103,8 +111,8 @@ class Dashboard
|
||||
<div class="col-md-6">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<span><i class="bi bi-plug"></i> Plugins</span>
|
||||
<a href="/admin/plugins" class="btn btn-sm btn-outline-secondary">Beheren</a>
|
||||
<span><i class="bi bi-plug"></i> <?= htmlspecialchars($tr('plugins')) ?></span>
|
||||
<a href="/admin/plugins" class="btn btn-sm btn-outline-secondary"><?= htmlspecialchars($tr('manage')) ?></a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-sm mb-0">
|
||||
@@ -113,22 +121,22 @@ class Dashboard
|
||||
<td>
|
||||
<i class="bi bi-plug-fill"></i> <?= htmlspecialchars($pluginName) ?>
|
||||
<?php if ($info['type'] === 'system'): ?>
|
||||
<span class="badge bg-secondary fs-7">systeem</span>
|
||||
<span class="badge bg-secondary fs-7"><?= htmlspecialchars($tr('plugin_type_system')) ?></span>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-info fs-7">content</span>
|
||||
<span class="badge bg-info fs-7"><?= htmlspecialchars($tr('plugin_type_content')) ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($info['enabled']): ?>
|
||||
<span class="badge bg-success">Actief</span>
|
||||
<span class="badge bg-success"><?= htmlspecialchars($tr('active')) ?></span>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-secondary">Inactief</span>
|
||||
<span class="badge bg-secondary"><?= htmlspecialchars($tr('inactive')) ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($pluginOverview)): ?>
|
||||
<tr><td colspan="2" class="text-muted text-center">Geen plugins gevonden.</td></tr>
|
||||
<tr><td colspan="2" class="text-muted text-center"><?= htmlspecialchars($tr('no_plugins')) ?></td></tr>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# Dashboard Plugin
|
||||
|
||||
Toont site informatie, content statistieken en een plugin overzicht op het admin dashboard.
|
||||
|
||||
## Plugin type
|
||||
|
||||
**Systeem** plugin. De plugin-output volgt de geselecteerde **admin taal** (via `AdminPluginAPI::getPluginTranslations()` met `admin.php`).
|
||||
|
||||
## Bestandsstructuur
|
||||
|
||||
```
|
||||
Dashboard/
|
||||
├── Dashboard.php # Hoofd plugin class
|
||||
├── plugin.json # Plugin metadata + instellingen
|
||||
├── README.md # Dit bestand
|
||||
├── assets/ # Optionele CSS/JS (leeg)
|
||||
└── language/ # Vertalingen
|
||||
├── nl/admin.php # Nederlandse admin labels
|
||||
└── en/admin.php # Engelse admin labels
|
||||
```
|
||||
|
||||
## Functies
|
||||
|
||||
- **Site informatie**: Site titel, standaard taal, CodePress/PHP versie, OS, config status
|
||||
- **Content informatie**: Aantal pagina's, mappen, content grootte
|
||||
- **Plugin overzicht**: Lijst van alle plugins met type (systeem/content) en actief/inactief status
|
||||
|
||||
## Instellingen
|
||||
|
||||
Deze plugin heeft geen instelbare configuratie (`hasConfig: false`).
|
||||
|
||||
## Taal support
|
||||
|
||||
De plugin gebruikt `AdminPluginAPI::getPluginTranslations('Dashboard')` om labels op te halen. Fallback chain:
|
||||
1. Geselecteerde admin taal
|
||||
2. Plugin `default_language` (`nl`)
|
||||
3. Lege array (sleutel wordt ongewijzigd getoond)
|
||||
|
||||
Beschikbare sleutels staan in `language/<lang>/admin.php`. Het admin-menu label wordt vertaald via `label_key: 'menu_label'` in `getAdminMenu()`.
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
return [
|
||||
// Menu
|
||||
'menu_label' => 'Dashboard',
|
||||
|
||||
// Page header
|
||||
'page_title' => 'Dashboard',
|
||||
|
||||
// Site information card
|
||||
'site_info' => 'Site information',
|
||||
'site_title' => 'Site title',
|
||||
'default_lang' => 'Default language',
|
||||
'cms_version' => 'CodePress version',
|
||||
'php_version' => 'PHP version',
|
||||
'os' => 'Operating system',
|
||||
'config_loaded' => 'Config loaded',
|
||||
'yes' => 'Yes',
|
||||
'no' => 'No',
|
||||
|
||||
// Content information card
|
||||
'content_info' => 'Content information',
|
||||
'pages' => 'Pages',
|
||||
'folders' => 'Folders',
|
||||
'content_size' => 'Content size',
|
||||
|
||||
// Plugins card
|
||||
'plugins' => 'Plugins',
|
||||
'manage' => 'Manage',
|
||||
'plugin_type_system' => 'system',
|
||||
'plugin_type_content' => 'content',
|
||||
'active' => 'Active',
|
||||
'inactive' => 'Inactive',
|
||||
'no_plugins' => 'No plugins found.',
|
||||
];
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
return [
|
||||
// Menu
|
||||
'menu_label' => 'Dashboard',
|
||||
|
||||
// Page header
|
||||
'page_title' => 'Dashboard',
|
||||
|
||||
// Site informatie card
|
||||
'site_info' => 'Site informatie',
|
||||
'site_title' => 'Site titel',
|
||||
'default_lang' => 'Standaard taal',
|
||||
'cms_version' => 'CodePress versie',
|
||||
'php_version' => 'PHP versie',
|
||||
'os' => 'Besturingssysteem',
|
||||
'config_loaded' => 'Config geladen',
|
||||
'yes' => 'Ja',
|
||||
'no' => 'Nee',
|
||||
|
||||
// Content informatie card
|
||||
'content_info' => 'Content informatie',
|
||||
'pages' => "Pagina's",
|
||||
'folders' => 'Mappen',
|
||||
'content_size' => 'Content grootte',
|
||||
|
||||
// Plugins card
|
||||
'plugins' => 'Plugins',
|
||||
'manage' => 'Beheren',
|
||||
'plugin_type_system' => 'systeem',
|
||||
'plugin_type_content' => 'content',
|
||||
'active' => 'Actief',
|
||||
'inactive' => 'Inactief',
|
||||
'no_plugins' => 'Geen plugins gevonden.',
|
||||
];
|
||||
@@ -5,5 +5,7 @@
|
||||
"description": "Toont site informatie, content statistieken en plugin overzicht op het dashboard.",
|
||||
"type": "system",
|
||||
"essential": true,
|
||||
"hasConfig": false
|
||||
"hasConfig": false,
|
||||
"default_language": "nl",
|
||||
"settings": []
|
||||
}
|
||||
Reference in New Issue
Block a user