From 561832161e16dc390b46ce5f3dcaa1c2083df2c2 Mon Sep 17 00:00:00 2001 From: Edwin Noorlander Date: Sat, 22 Nov 2025 18:00:35 +0100 Subject: [PATCH] Fix title extraction to always use filename/directory name instead of content - Remove H1 and HTML title extraction from parse methods - Always use formatDisplayName() for consistent filename-based titles - Add file path parameters to parseMarkdown() and parseHTML() - Fix directory precedence to check directories before files - Update AGENTS.md with title vs filename clarification - Remove debug code from templates and methods Resolves: Page titles now consistently show file/directory names without language prefixes and extensions, never content titles. --- AGENTS.md | 12 ++++- engine/core/class/CodePressCMS.php | 61 ++++++++++++++++--------- engine/templates/assets/footer.mustache | 1 - 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index fbd61b5..bf7a27d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,4 +16,14 @@ - **Templating**: Simple string replacement `{{placeholder}}` in `templates/layout.html`. - **Navigation**: Auto-generated from directory structure. Folders require an index file to be clickable in breadcrumbs. - **Security**: Always use `htmlspecialchars()` for outputting user/content data. -- **Git**: `main` is the clean CMS core. `e.noorlander` contains personal content. Do not mix them. \ No newline at end of file +- **Git**: `main` is the clean CMS core. `e.noorlander` contains personal content. Do not mix them. + +## Important: Title vs File/Directory Name Logic +- **CRITICAL**: When user asks for "title" corrections, they usually mean **FILE/DIRECTORY NAME WITHOUT LANGUAGE PREFIX AND EXTENSIONS**, not the HTML title from content! +- **Examples**: + - `nl.test.md` → display as "Test" (not content title) + - `nl.test/` directory → display as "Test" (not H1 content) + - `en.php-testen` → display as "Php Testen" (not "ICT") +- **Method**: Use `formatDisplayName()` to process file/directory names correctly +- **Priority**: Directory names take precedence over file names when both exist +- **Language prefixes**: Always remove `nl.` or `en.` prefixes from display names \ No newline at end of file diff --git a/engine/core/class/CodePressCMS.php b/engine/core/class/CodePressCMS.php index 7c45d31..b6247cb 100644 --- a/engine/core/class/CodePressCMS.php +++ b/engine/core/class/CodePressCMS.php @@ -234,12 +234,26 @@ class CodePressCMS { $pageWithoutExt = preg_replace('/\.(md|php|html)$/', '', $page); $filePath = $this->config['content_dir'] . '/' . $pageWithoutExt; + + // Check if directory exists FIRST (directories take precedence over files) + if (is_dir($filePath)) { + return $this->getDirectoryListing($pageWithoutExt, $filePath); + } + $actualFilePath = null; - // Check for exact file matches first + // Check if directory exists first (directories take precedence over files) + if (is_dir($filePath)) { + $directoryResult = $this->getDirectoryListing($pageWithoutExt, $filePath); + + return $directoryResult; + } + + // Check for exact file matches if no directory found if (file_exists($filePath . '.md')) { $actualFilePath = $filePath . '.md'; - $result = $this->parseMarkdown(file_get_contents($actualFilePath)); + + $result = $this->parseMarkdown(file_get_contents($actualFilePath), $actualFilePath); } elseif (file_exists($filePath . '.php')) { $actualFilePath = $filePath . '.php'; $result = $this->parsePHP($actualFilePath); @@ -250,7 +264,7 @@ class CodePressCMS { $actualFilePath = $filePath; $extension = pathinfo($filePath, PATHINFO_EXTENSION); if ($extension === 'md') { - $result = $this->parseMarkdown(file_get_contents($actualFilePath)); + $result = $this->parseMarkdown(file_get_contents($actualFilePath), $actualFilePath); } elseif ($extension === 'php') { $result = $this->parsePHP($actualFilePath); } elseif ($extension === 'html') { @@ -265,7 +279,7 @@ class CodePressCMS { if (file_exists($this->config['content_dir'] . '/' . $langPrefix . '.' . $pageWithoutExt . '.md')) { $actualFilePath = $this->config['content_dir'] . '/' . $langPrefix . '.' . $pageWithoutExt . '.md'; - $result = $this->parseMarkdown(file_get_contents($actualFilePath)); + $result = $this->parseMarkdown(file_get_contents($actualFilePath), $actualFilePath); } elseif (file_exists($this->config['content_dir'] . '/' . $langPrefix . '.' . $pageWithoutExt . '.php')) { $actualFilePath = $this->config['content_dir'] . '/' . $langPrefix . '.' . $pageWithoutExt . '.php'; $result = $this->parsePHP($actualFilePath); @@ -275,11 +289,9 @@ class CodePressCMS { } } - // If no file found, check if it's a directory + // If no file found, check if it's a directory (directories take precedence) if (!isset($result) && is_dir($filePath)) { - $directoryResult = $this->getDirectoryListing($pageWithoutExt, $filePath); - file_put_contents('/tmp/debug_directory.txt', "Directory result title: '" . $directoryResult['title'] . "'\n"); - return $directoryResult; + return $this->getDirectoryListing($pageWithoutExt, $filePath); } if (isset($result) && $actualFilePath) { @@ -364,7 +376,7 @@ class CodePressCMS { * @param string $content Raw Markdown content * @return array Parsed content with title and body */ - private function parseMarkdown($content) { + private function parseMarkdown($content, $actualFilePath = '') { // Extract title from first H1 $title = ''; if (preg_match('/^#\s+(.+)$/m', $content, $matches)) { @@ -399,6 +411,8 @@ class CodePressCMS { $filename = basename($actualFilePath); $cleanName = $this->formatDisplayName($filename); + + // Auto-link page titles to existing content pages (but not in H1 tags) $body = $this->autoLinkPageTitles($body, $cleanName); @@ -549,6 +563,9 @@ class CodePressCMS { * @return string Formatted display name */ private function formatDisplayName($filename) { + // Debug: log input + error_log("DEBUG: formatDisplayName input: '$filename'"); + // Remove language prefixes (nl. or en.) from display names if (preg_match('/^(nl|en)\.(.+)$/', $filename, $matches)) { $filename = $matches[2]; @@ -625,12 +642,15 @@ class CodePressCMS { */ private function parsePHP($filePath) { ob_start(); - $title = 'Untitled'; include $filePath; $content = ob_get_clean(); + // Extract filename for title + $filename = basename($filePath); + $cleanName = $this->formatDisplayName($filename); + return [ - 'title' => $title, + 'title' => $cleanName ?: 'Untitled', 'content' => $content ]; } @@ -641,17 +661,13 @@ class CodePressCMS { * @param string $content Raw HTML content * @return array Parsed content with title and body */ - private function parseHTML($content) { - $title = 'Untitled'; - - if (preg_match('/(.*?)<\/title>/i', $content, $matches)) { - $title = strip_tags($matches[1]); - } elseif (preg_match('/<h1[^>]*>(.*?)<\/h1>/i', $content, $matches)) { - $title = strip_tags($matches[1]); - } + private function parseHTML($content, $actualFilePath = '') { + // Extract filename for title + $filename = basename($actualFilePath); + $cleanName = $this->formatDisplayName($filename); return [ - 'title' => $title, + 'title' => $cleanName ?: 'Untitled', 'content' => $content ]; } @@ -723,7 +739,8 @@ class CodePressCMS { $pathParts = explode('/', $pagePath); $dirName = end($pathParts); - // Get the directory name from path, not from a potential file + // Debug: log what we're working with + error_log("DEBUG: getDirectoryListing - dirName: '$dirName', formatDisplayName result: '" . $this->formatDisplayName($dirName) . "'"); $title = $this->formatDisplayName($dirName) ?: 'Home'; @@ -843,7 +860,7 @@ class CodePressCMS { $templateData = [ 'site_title' => $this->config['site_title'], 'page_title' => htmlspecialchars($page['title']), - 'debug_page_title' => $page['title'], // Debug: show raw title + 'content' => $page['content'], 'search_query' => isset($_GET['search']) ? htmlspecialchars($_GET['search']) : '', 'menu' => $this->renderMenu($menu), diff --git a/engine/templates/assets/footer.mustache b/engine/templates/assets/footer.mustache index 8629b31..def810e 100644 --- a/engine/templates/assets/footer.mustache +++ b/engine/templates/assets/footer.mustache @@ -6,7 +6,6 @@ <div class="file-info"> <i class="bi bi-file-text"></i> <span class="page-title" title="{{page_title}}">{{page_title}}</span> - <!-- DEBUG: Raw title: {{debug_page_title}} --> {{{file_info_block}}} </div> <div class="site-info">