diff --git a/config.json b/config.json index b8f56f1..b3b9f43 100644 --- a/config.json +++ b/config.json @@ -1,12 +1,18 @@ { "site_title": "CodePress", - "content_dir": "public/content", + "content_dir": "content", "templates_dir": "engine/templates", "default_page": "welkom", "theme": { - "primary_color": "#0d6efd", - "navbar_style": "bg-primary" + "header_color": "#0a369d", + "header_font_color": "#ffffff", + "navigation_color": "#2754b4", + "navigation_font_color": "#ffffff" + }, + "language": { + "default": "nl", + "available": ["nl", "en"] }, "seo": { "description": "CodePress CMS - Lightweight file-based content management system", @@ -22,4 +28,4 @@ "search_enabled": true, "breadcrumbs_enabled": true } -} \ No newline at end of file +} diff --git a/engine/core/class/CodePressCMS.php b/engine/core/class/CodePressCMS.php index f7a670a..245a5ea 100644 --- a/engine/core/class/CodePressCMS.php +++ b/engine/core/class/CodePressCMS.php @@ -24,6 +24,8 @@ class CodePressCMS { private $config; private $menu = []; private $searchResults = []; + private $currentLanguage; + private $translations = []; /** * Constructor - Initialize the CMS with configuration @@ -32,6 +34,8 @@ class CodePressCMS { */ public function __construct($config) { $this->config = $config; + $this->currentLanguage = $this->getCurrentLanguage(); + $this->translations = $this->loadTranslations($this->currentLanguage); $this->buildMenu(); if (isset($_GET['search'])) { @@ -39,6 +43,46 @@ class CodePressCMS { } } + /** + * Get current language from URL or use default + * + * @return string Current language code + */ + private function getCurrentLanguage() { + return $_GET['lang'] ?? $this->config['language']['default'] ?? 'nl'; + } + + /** + * Load translations for specified language + * + * @param string $lang Language code + * @return array Translations array + */ + private function loadTranslations($lang) { + $langFile = __DIR__ . '/../../lang/' . $lang . '.php'; + error_log("Loading language file: " . $langFile); + if (file_exists($langFile)) { + $translations = include $langFile; + error_log("Loaded translations for " . $lang . ": " . print_r($translations, true)); + return $translations; + } + // Fallback to default language + $defaultLang = $this->config['language']['default'] ?? 'nl'; + $defaultLangFile = __DIR__ . '/../../lang/' . $defaultLang . '.php'; + error_log("Fallback to default language: " . $defaultLangFile); + return file_exists($defaultLangFile) ? include $defaultLangFile : []; + } + + /** + * Get translated text + * + * @param string $key Translation key + * @return string Translated text + */ + public function t($key) { + return $this->translations[$key] ?? $key; + } + /** * Build menu structure from content directory * @@ -263,12 +307,12 @@ class CodePressCMS { */ private function getSearchResults() { $query = $_GET['search']; - $content = '
No results found.
'; + $content .= '' . $this->t('no_results') . '.
'; } else { - $content .= 'Found ' . count($this->searchResults) . ' results:
'; + $content .= '' . count($this->searchResults) . ' ' . $this->t('results_found') . ':
'; foreach ($this->searchResults as $result) { $content .= 'Deze map is leeg.
'; + $content .= '' . $this->t('directory_empty') . '.
'; } return [ @@ -726,8 +756,8 @@ class CodePressCMS { */ private function getError404() { return [ - 'title' => 'Page Not Found', - 'content' => 'The page you are looking for does not exist.
' + 'title' => $this->t('page_not_found'), + 'content' => '' . $this->t('page_not_found_text') . '
' ]; } @@ -748,7 +778,7 @@ class CodePressCMS { public function render() { $page = $this->getPage(); $menu = $this->getMenu(); - $breadcrumb = $this->getBreadcrumb(); + $breadcrumb = $this->generateBreadcrumb(); // Get homepage title $homepageTitle = $this->getHomepageTitle(); @@ -764,30 +794,57 @@ class CodePressCMS { 'default_page' => $this->config['default_page'], 'homepage' => $this->config['default_page'], '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' : '', 'author_name' => $this->config['author']['name'] ?? 'CodePress Developer', 'author_website' => $this->config['author']['website'] ?? '#', 'author_git' => $this->config['author']['git'] ?? '#', 'seo_description' => $this->config['seo']['description'] ?? 'CodePress CMS - Lightweight file-based content management system', - 'seo_keywords' => $this->config['seo']['keywords'] ?? 'cms, php, content management, file-based' + 'seo_keywords' => $this->config['seo']['keywords'] ?? 'cms, php, content management, file-based', + // Theme colors + 'header_color' => $this->config['theme']['header_color'] ?? '#0d6efd', + 'header_font_color' => $this->config['theme']['header_font_color'] ?? '#ffffff', + 'navigation_color' => $this->config['theme']['navigation_color'] ?? '#f8f9fa', + 'navigation_font_color' => $this->config['theme']['navigation_font_color'] ?? '#000000', + // Language + 'current_lang' => $this->currentLanguage, + 'current_lang_upper' => strtoupper($this->currentLanguage), + 'available_langs' => $this->config['language']['available'] ?? ['nl', 'en'], + // Translations + 't_home' => $this->t('home'), + 't_search' => $this->t('search'), + 't_search_placeholder' => $this->t('search_placeholder'), + 't_search_button' => $this->t('search_button'), + 't_welcome' => $this->t('welcome'), + 't_created' => $this->t('created'), + 't_modified' => $this->t('modified'), + 't_author' => $this->t('author'), + 't_manual' => $this->t('manual'), + 't_no_content' => $this->t('no_content'), + 't_no_results' => $this->t('no_results'), + 't_results_found' => $this->t('results_found'), + 't_breadcrumb_home' => $this->t('breadcrumb_home'), + 't_file_details' => $this->t('file_details'), + 't_guide' => $this->t('guide'), + 't_powered_by' => $this->t('powered_by'), + 't_directory_empty' => $this->t('directory_empty'), + 't_page_not_found' => $this->t('page_not_found'), + 't_page_not_found_text' => $this->t('page_not_found_text'), + 't_mappen' => $this->t('mappen'), + 't_paginas' => $this->t('paginas') ]; // File info for footer if (isset($page['file_info'])) { - $templateData['file_info'] = 'Created: ' . htmlspecialchars($page['file_info']['created']) . - ' | Modified: ' . htmlspecialchars($page['file_info']['modified']); + $templateData['file_info'] = $this->t('created') . ': ' . htmlspecialchars($page['file_info']['created']) . + ' | ' . $this->t('modified') . ': ' . htmlspecialchars($page['file_info']['modified']); $templateData['file_info_block'] = ' | ' . $templateData['file_info'] . ''; } else { $templateData['file_info'] = ''; $templateData['file_info_block'] = ''; } - // File info for footer - if (isset($page['file_info'])) { - $templateData['file_info'] = 'Created: ' . htmlspecialchars($page['file_info']['created']) . - ' | Modified: ' . htmlspecialchars($page['file_info']['modified']); - } else { - $templateData['file_info'] = ''; - } + // Check if content exists for guide link $hasContent = !$this->isContentDirEmpty(); @@ -796,60 +853,35 @@ class CodePressCMS { // Don't show site title link on guide page $templateData['show_site_link'] = !$this->isContentDirEmpty() && !isset($_GET['guide']); - // Load partials manually - $hasContent = !$this->isContentDirEmpty() && !isset($_GET['guide']); - - $headerContent = file_get_contents($this->config['templates_dir'] . '/assets/header.mustache'); - if (!$hasContent) { - // Remove the link from header when no content - $headerContent = preg_replace('/\s*