Media browser: recursive scan entire content/ tree, /-media/ URL prefix, editor change detection fix

- handleMediaList() now scans content/ recursively for all media files
- URLs use /-media/ prefix mapping directly to content/ (no special cases)
- index.php: added /-media/ route, kept /-assets/ for backward compat
- editor-toolbar.js: fixed editor.on('change') placement (was inside switchMode)
- content-edit.php and content-new.php: back-btn unsaved-changes detection
- Removed unused __editorCleanup global
This commit is contained in:
2026-06-24 17:00:59 +02:00
parent d97c67c6a9
commit dc0d370e65
50 changed files with 2796 additions and 140 deletions

View File

@@ -45,7 +45,7 @@ class CodePressCMS {
$this->currentLanguage = $this->getCurrentLanguage();
$this->translations = $this->loadTranslations($this->currentLanguage);
// Initialize plugin manager (files already loaded in engine/core/index.php)
// Initialize plugin manager (files already loaded in cms/core/index.php)
$this->pluginManager = new PluginManager(__DIR__ . '/../../../plugins');
$api = new CMSAPI($this);
$this->pluginManager->setAPI($api);
@@ -182,7 +182,10 @@ class CodePressCMS {
$result = [];
foreach ($items as $item) {
if ($item[0] === '.') continue;
if ($item[0] === '.' || $item[0] === '-') continue;
// Skip assets directory (old name, kept for safety)
if ($item === 'assets' && is_dir($dir . '/' . $item)) continue;
// Skip language-specific content that doesn't match current language
$availableLangs = array_keys($this->getAvailableLanguages());
@@ -640,6 +643,12 @@ class CodePressCMS {
* @return string Formatted display name
*/
private function formatDisplayName($filename) {
// Preserve leading dash before processing
$hasLeadingDash = $filename[0] === '-';
if ($hasLeadingDash) {
$filename = substr($filename, 1);
}
// Remove language prefixes dynamically based on available languages
$availableLangs = array_keys($this->getAvailableLanguages());
$langPattern = '/^(' . implode('|', $availableLangs) . ')\.(.+)$/';
@@ -656,11 +665,12 @@ class CodePressCMS {
'ict' => 'ICT',
];
if (isset($specialCases[strtolower($filename)])) {
return $specialCases[strtolower($filename)];
return ($hasLeadingDash ? '- ' : '') . $specialCases[strtolower($filename)];
}
// Replace hyphens and underscores with spaces, then title case
$name = str_replace(['-', '_'], ' ', $filename);
$name = trim($name);
$name = ucwords(strtolower($name));
// Post-process special cases in compound names
@@ -668,7 +678,7 @@ class CodePressCMS {
$name = str_ireplace(ucfirst($lower), $correct, $name);
}
return $name;
return ($hasLeadingDash ? '- ' : '') . $name;
}
/**
@@ -983,8 +993,12 @@ private function getGuidePage() {
// Get homepage title
$homepageTitle = $this->getHomepageTitle();
// Get sidebar content from plugins
$sidebarContent = $this->pluginManager->getSidebarContent();
// Get sidebar content from plugins (filtered per-page if specified in frontmatter)
$allowedPlugins = null;
if (!empty($page['metadata']['plugins'])) {
$allowedPlugins = array_map('trim', explode(',', $page['metadata']['plugins']));
}
$sidebarContent = $this->pluginManager->getSidebarContent($allowedPlugins);
// Get layout from page metadata
$layout = $page['layout'] ?? 'sidebar-content';
@@ -994,7 +1008,7 @@ private function getGuidePage() {
'site_title' => $this->config['site_title'],
'page_title' => htmlspecialchars($page['title']),
'content' => $page['content'],
'content' => $this->processContent($page['content']),
'sidebar_content' => $sidebarContent,
'layout' => $layout,
'page_metadata' => $page['metadata'] ?? [],
@@ -1017,10 +1031,14 @@ private function getGuidePage() {
// Theme colors
'header_color' => $this->config['theme']['header_color'] ?? '#0d6efd',
'header_font_color' => $this->config['theme']['header_font_color'] ?? '#ffffff',
'header_height' => $this->config['theme']['header_height'] ?? '56',
'navigation_color' => $this->config['theme']['navigation_color'] ?? '#f8f9fa',
'navigation_font_color' => $this->config['theme']['navigation_font_color'] ?? '#000000',
'nav_height' => $this->config['theme']['nav_height'] ?? '42',
'sidebar_background' => $this->config['theme']['sidebar_background'] ?? '#f8f9fa',
'sidebar_border' => $this->config['theme']['sidebar_border'] ?? '#dee2e6',
'background_image_css' => $this->getBackgroundImageCss(),
'background_image_opacity' => $this->getBackgroundImageOpacity(),
// Language
'current_lang' => $this->currentLanguage,
'current_lang_upper' => strtoupper($this->currentLanguage),
@@ -1286,4 +1304,27 @@ private function getGuidePage() {
}
return false;
}
private function getBackgroundImageCss(): string
{
$bg = $this->config['theme']['background_image'] ?? '';
if (empty($bg)) {
return 'none';
}
if (str_starts_with($bg, 'http')) {
return 'url(' . $bg . ')';
}
return 'url(/themes/' . $bg . ')';
}
private function getBackgroundImageOpacity(): int
{
$opacity = intval($this->config['theme']['background_image_opacity'] ?? 100);
return max(0, min(100, $opacity));
}
private function processContent(string $content): string
{
return str_replace('-/assets/', '/-assets/', $content);
}
}