From b203f6d12a1b954ec21f0df4ba93b32bd70a6f0b Mon Sep 17 00:00:00 2001 From: Edwin Noorlander Date: Tue, 28 Jul 2026 16:09:44 +0200 Subject: [PATCH] Fix unreachable index page and duplicate homepage entry in navigation buildUrl() hardcoded 'index' as the homepage, so the menu link for index.md pointed at /nl. With a different default_page that root URL served another page, making index.md unreachable. - Add getEffectiveDefaultPage(): resolves 'auto' to the detected page and caches the result - buildUrl() now omits the page segment only for the effective default page instead of the literal string 'index' - Route getPage(), generateBreadcrumb(), getContentType() and the render() template data (default_page, homepage, is_homepage, home_active_class, current_page, lang switch URLs) through it - getHomepageTitle() returns t('home') so the home button no longer duplicates a menu item label - Drop the now-redundant default_page skip in renderMenu() so every page stays reachable from the menu - getAllContentDirs() also skips dot-directories (.git) in the move dropdown --- cms/core/class/CodePressCMS.php | 60 ++++++++++++++++++--------------- public/admin.php | 5 +-- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/cms/core/class/CodePressCMS.php b/cms/core/class/CodePressCMS.php index c505f12..b8fb745 100644 --- a/cms/core/class/CodePressCMS.php +++ b/cms/core/class/CodePressCMS.php @@ -25,6 +25,7 @@ class CodePressCMS { public $currentLanguage; public $searchResults = []; private $menu = []; + private ?string $effectiveDefaultPage = null; private $translations = []; private $pluginManager; @@ -66,10 +67,12 @@ class CodePressCMS { * @param array $params Additional query parameters * @return string Clean URL */ - public function buildUrl($page = 'index', $lang = null, $params = []) { + public function buildUrl($page = null, $lang = null, $params = []) { $lang = $lang ?: $this->currentLanguage; $url = '/' . $lang; - if ($page && $page !== 'index') { + // Only omit the page segment for the actual homepage (default_page), + // not for a page that happens to be called 'index' + if ($page && $page !== $this->getEffectiveDefaultPage()) { $url .= '/' . $page; } if (!empty($params)) { @@ -78,6 +81,20 @@ class CodePressCMS { return $url; } + /** + * Resolve the effective default page (handles 'auto' mode) + * + * @return string Page key that is served on the language root URL + */ + public function getEffectiveDefaultPage(): string + { + if ($this->effectiveDefaultPage === null) { + $page = $this->config['default_page'] ?? 'auto'; + $this->effectiveDefaultPage = ($page === 'auto') ? $this->detectDefaultPage() : $page; + } + return $this->effectiveDefaultPage; + } + /** * Build a clean admin URL * @@ -353,10 +370,7 @@ class CodePressCMS { return $this->getGuidePage(); } - $page = $_GET['page'] ?? $this->config['default_page']; - if ($page === 'auto') { - $page = $this->detectDefaultPage(); - } + $page = $_GET['page'] ?? $this->getEffectiveDefaultPage(); // Limit length $page = substr($page, 0, 255); // Only remove file extension at the end, not all dots @@ -1057,11 +1071,11 @@ class CodePressCMS { 'search_query' => isset($_GET['search']) ? htmlspecialchars($_GET['search']) : '', 'menu' => $this->renderMenu($menu), 'breadcrumb' => $breadcrumb, - 'default_page' => $this->config['default_page'], - 'homepage' => $this->config['default_page'], + 'default_page' => $this->getEffectiveDefaultPage(), + 'homepage' => $this->getEffectiveDefaultPage(), 'homepage_title' => $homepageTitle, - 'is_homepage' => (!isset($_GET['page']) || $_GET['page'] === $this->config['default_page']), - 'home_active_class' => (!isset($_GET['page']) || $_GET['page'] === $this->config['default_page']) ? 'active' : '', + 'is_homepage' => (!isset($_GET['page']) || $_GET['page'] === $this->getEffectiveDefaultPage()), + 'home_active_class' => (!isset($_GET['page']) || $_GET['page'] === $this->getEffectiveDefaultPage()) ? 'active' : '', 'is_guide_page' => isset($_GET['guide']), 'lang_switch_url' => '', 'author_name' => $this->config['author']['name'] ?? 'CodePress Developer', @@ -1084,11 +1098,11 @@ class CodePressCMS { // Language 'current_lang' => $this->currentLanguage, 'current_lang_upper' => strtoupper($this->currentLanguage), - 'current_page' => $_GET['page'] ?? $this->config['default_page'], + 'current_page' => $_GET['page'] ?? $this->getEffectiveDefaultPage(), 'available_langs' => array_map(function($lang) { $lang['is_current'] = $lang['code'] === $this->currentLanguage; - $page = $_GET['page'] ?? $this->config['default_page']; - $lang['url'] = '/' . $lang['code'] . ($page !== $this->config['default_page'] ? '/' . $page : ''); + $page = $_GET['page'] ?? $this->getEffectiveDefaultPage(); + $lang['url'] = '/' . $lang['code'] . ($page !== $this->getEffectiveDefaultPage() ? '/' . $page : ''); return $lang; }, $this->getAvailableLanguages()), // Translations @@ -1187,12 +1201,12 @@ class CodePressCMS { return ''; } - $page = $_GET['page'] ?? $this->config['default_page']; + $page = $_GET['page'] ?? $this->getEffectiveDefaultPage(); $page = htmlspecialchars($page, ENT_QUOTES, 'UTF-8'); $page = preg_replace('/\.[^.]+$/', '', $page); // Convert page to clean URL format for breadcrumb - if ($page === $this->config['default_page']) { + if ($page === $this->getEffectiveDefaultPage()) { return ''; } @@ -1274,11 +1288,6 @@ class CodePressCMS { } else { // Show files in root as tabs, files in folders as dropdown items if ($level === 0) { - // Don't show the homepage file as a separate tab since it's already the Home button - if ($item['path'] === $this->config['default_page']) { - continue; - } - $active = (isset($_GET['page']) && $_GET['page'] === $item['path']) ? 'active' : ''; $html .= '