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
This commit is contained in:
@@ -25,6 +25,7 @@ class CodePressCMS {
|
|||||||
public $currentLanguage;
|
public $currentLanguage;
|
||||||
public $searchResults = [];
|
public $searchResults = [];
|
||||||
private $menu = [];
|
private $menu = [];
|
||||||
|
private ?string $effectiveDefaultPage = null;
|
||||||
private $translations = [];
|
private $translations = [];
|
||||||
private $pluginManager;
|
private $pluginManager;
|
||||||
|
|
||||||
@@ -66,10 +67,12 @@ class CodePressCMS {
|
|||||||
* @param array $params Additional query parameters
|
* @param array $params Additional query parameters
|
||||||
* @return string Clean URL
|
* @return string Clean URL
|
||||||
*/
|
*/
|
||||||
public function buildUrl($page = 'index', $lang = null, $params = []) {
|
public function buildUrl($page = null, $lang = null, $params = []) {
|
||||||
$lang = $lang ?: $this->currentLanguage;
|
$lang = $lang ?: $this->currentLanguage;
|
||||||
$url = '/' . $lang;
|
$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;
|
$url .= '/' . $page;
|
||||||
}
|
}
|
||||||
if (!empty($params)) {
|
if (!empty($params)) {
|
||||||
@@ -78,6 +81,20 @@ class CodePressCMS {
|
|||||||
return $url;
|
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
|
* Build a clean admin URL
|
||||||
*
|
*
|
||||||
@@ -353,10 +370,7 @@ class CodePressCMS {
|
|||||||
return $this->getGuidePage();
|
return $this->getGuidePage();
|
||||||
}
|
}
|
||||||
|
|
||||||
$page = $_GET['page'] ?? $this->config['default_page'];
|
$page = $_GET['page'] ?? $this->getEffectiveDefaultPage();
|
||||||
if ($page === 'auto') {
|
|
||||||
$page = $this->detectDefaultPage();
|
|
||||||
}
|
|
||||||
// Limit length
|
// Limit length
|
||||||
$page = substr($page, 0, 255);
|
$page = substr($page, 0, 255);
|
||||||
// Only remove file extension at the end, not all dots
|
// Only remove file extension at the end, not all dots
|
||||||
@@ -1057,11 +1071,11 @@ class CodePressCMS {
|
|||||||
'search_query' => isset($_GET['search']) ? htmlspecialchars($_GET['search']) : '',
|
'search_query' => isset($_GET['search']) ? htmlspecialchars($_GET['search']) : '',
|
||||||
'menu' => $this->renderMenu($menu),
|
'menu' => $this->renderMenu($menu),
|
||||||
'breadcrumb' => $breadcrumb,
|
'breadcrumb' => $breadcrumb,
|
||||||
'default_page' => $this->config['default_page'],
|
'default_page' => $this->getEffectiveDefaultPage(),
|
||||||
'homepage' => $this->config['default_page'],
|
'homepage' => $this->getEffectiveDefaultPage(),
|
||||||
'homepage_title' => $homepageTitle,
|
'homepage_title' => $homepageTitle,
|
||||||
'is_homepage' => (!isset($_GET['page']) || $_GET['page'] === $this->config['default_page']),
|
'is_homepage' => (!isset($_GET['page']) || $_GET['page'] === $this->getEffectiveDefaultPage()),
|
||||||
'home_active_class' => (!isset($_GET['page']) || $_GET['page'] === $this->config['default_page']) ? 'active' : '',
|
'home_active_class' => (!isset($_GET['page']) || $_GET['page'] === $this->getEffectiveDefaultPage()) ? 'active' : '',
|
||||||
'is_guide_page' => isset($_GET['guide']),
|
'is_guide_page' => isset($_GET['guide']),
|
||||||
'lang_switch_url' => '',
|
'lang_switch_url' => '',
|
||||||
'author_name' => $this->config['author']['name'] ?? 'CodePress Developer',
|
'author_name' => $this->config['author']['name'] ?? 'CodePress Developer',
|
||||||
@@ -1084,11 +1098,11 @@ class CodePressCMS {
|
|||||||
// Language
|
// Language
|
||||||
'current_lang' => $this->currentLanguage,
|
'current_lang' => $this->currentLanguage,
|
||||||
'current_lang_upper' => strtoupper($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) {
|
'available_langs' => array_map(function($lang) {
|
||||||
$lang['is_current'] = $lang['code'] === $this->currentLanguage;
|
$lang['is_current'] = $lang['code'] === $this->currentLanguage;
|
||||||
$page = $_GET['page'] ?? $this->config['default_page'];
|
$page = $_GET['page'] ?? $this->getEffectiveDefaultPage();
|
||||||
$lang['url'] = '/' . $lang['code'] . ($page !== $this->config['default_page'] ? '/' . $page : '');
|
$lang['url'] = '/' . $lang['code'] . ($page !== $this->getEffectiveDefaultPage() ? '/' . $page : '');
|
||||||
return $lang;
|
return $lang;
|
||||||
}, $this->getAvailableLanguages()),
|
}, $this->getAvailableLanguages()),
|
||||||
// Translations
|
// Translations
|
||||||
@@ -1187,12 +1201,12 @@ class CodePressCMS {
|
|||||||
return '<nav aria-label="breadcrumb"><ol class="breadcrumb">' . $sidebarToggle . '<li class="breadcrumb-item"><a href="/' . $this->currentLanguage . '"><i class="bi bi-house"></i></a></li><li class="breadcrumb-item"> > </li><li class="breadcrumb-item active">' . $this->t('search') . '</li></ol></nav>';
|
return '<nav aria-label="breadcrumb"><ol class="breadcrumb">' . $sidebarToggle . '<li class="breadcrumb-item"><a href="/' . $this->currentLanguage . '"><i class="bi bi-house"></i></a></li><li class="breadcrumb-item"> > </li><li class="breadcrumb-item active">' . $this->t('search') . '</li></ol></nav>';
|
||||||
}
|
}
|
||||||
|
|
||||||
$page = $_GET['page'] ?? $this->config['default_page'];
|
$page = $_GET['page'] ?? $this->getEffectiveDefaultPage();
|
||||||
$page = htmlspecialchars($page, ENT_QUOTES, 'UTF-8');
|
$page = htmlspecialchars($page, ENT_QUOTES, 'UTF-8');
|
||||||
$page = preg_replace('/\.[^.]+$/', '', $page);
|
$page = preg_replace('/\.[^.]+$/', '', $page);
|
||||||
|
|
||||||
// Convert page to clean URL format for breadcrumb
|
// Convert page to clean URL format for breadcrumb
|
||||||
if ($page === $this->config['default_page']) {
|
if ($page === $this->getEffectiveDefaultPage()) {
|
||||||
return '<nav aria-label="breadcrumb"><ol class="breadcrumb">' . $sidebarToggle . '<li class="breadcrumb-item active"><i class="bi bi-house"></i></li></ol></nav>';
|
return '<nav aria-label="breadcrumb"><ol class="breadcrumb">' . $sidebarToggle . '<li class="breadcrumb-item active"><i class="bi bi-house"></i></li></ol></nav>';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1274,11 +1288,6 @@ class CodePressCMS {
|
|||||||
} else {
|
} else {
|
||||||
// Show files in root as tabs, files in folders as dropdown items
|
// Show files in root as tabs, files in folders as dropdown items
|
||||||
if ($level === 0) {
|
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' : '';
|
$active = (isset($_GET['page']) && $_GET['page'] === $item['path']) ? 'active' : '';
|
||||||
$html .= '<li class="nav-item">';
|
$html .= '<li class="nav-item">';
|
||||||
$html .= '<a class="nav-link ' . $active . '" href="' . htmlspecialchars($item['url']) . '">';
|
$html .= '<a class="nav-link ' . $active . '" href="' . htmlspecialchars($item['url']) . '">';
|
||||||
@@ -1305,7 +1314,7 @@ class CodePressCMS {
|
|||||||
*/
|
*/
|
||||||
private function getContentType($page) {
|
private function getContentType($page) {
|
||||||
// Try to determine content type from page request
|
// Try to determine content type from page request
|
||||||
$pagePath = $_GET['page'] ?? $this->config['default_page'];
|
$pagePath = $_GET['page'] ?? $this->getEffectiveDefaultPage();
|
||||||
$pagePath = preg_replace('/\.[^.]+$/', '', $pagePath);
|
$pagePath = preg_replace('/\.[^.]+$/', '', $pagePath);
|
||||||
|
|
||||||
$filePath = $this->config['content_dir'] . '/' . $pagePath;
|
$filePath = $this->config['content_dir'] . '/' . $pagePath;
|
||||||
@@ -1363,12 +1372,9 @@ class CodePressCMS {
|
|||||||
* @return string Homepage title
|
* @return string Homepage title
|
||||||
*/
|
*/
|
||||||
private function getHomepageTitle() {
|
private function getHomepageTitle() {
|
||||||
// Use formatted filename for homepage title in navigation
|
// Use a generic "Home" label instead of the page name
|
||||||
$page = $this->config['default_page'];
|
// to avoid duplication with the navigation menu
|
||||||
if ($page === 'auto') {
|
return $this->t('home');
|
||||||
$page = $this->detectDefaultPage();
|
|
||||||
}
|
|
||||||
return $this->formatDisplayName($page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+3
-2
@@ -1675,8 +1675,9 @@ function getAllContentDirs(string $contentDir, string $realContentDir): array
|
|||||||
if (strpos($realPath, $realContentDir) !== 0) continue;
|
if (strpos($realPath, $realContentDir) !== 0) continue;
|
||||||
$relative = substr($realPath, strlen($realContentDir) + 1);
|
$relative = substr($realPath, strlen($realContentDir) + 1);
|
||||||
if ($relative === false || $relative === '') continue;
|
if ($relative === false || $relative === '') continue;
|
||||||
// Skip hidden directories (starting with -)
|
// Skip hidden directories (starting with - or .)
|
||||||
if (strpos(basename($relative), '-') === 0) continue;
|
$base = basename($relative);
|
||||||
|
if ($base[0] === '-' || $base[0] === '.') continue;
|
||||||
$dirs[] = $relative;
|
$dirs[] = $relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user