diff --git a/app/config.php b/app/config.php index cb0071b..9551c08 100644 --- a/app/config.php +++ b/app/config.php @@ -14,12 +14,7 @@ $userContentDir = $_SERVER['DOCUMENT_ROOT']; $demoContentDir = __DIR__ . '/default/content'; // Check if user content directory has actual content (more than just . and ..) -$hasUserContent = false; -if (is_dir($userContentDir)) { - $userFiles = scandir($userContentDir) ?: []; - $userFiles = array_diff($userFiles, ['.', '..']); - $hasUserContent = count($userFiles) > 0; -} +$hasUserContent = is_dir($userContentDir) && count(scandir($userContentDir) ?: []) > 2; $contentDir = $hasUserContent ? realpath($userContentDir) : realpath($demoContentDir); @@ -37,15 +32,7 @@ if (!empty($pathParts[0]) && in_array($pathParts[0], $availableLangs) && $pathPa $requestPath = implode('/', $pathParts); } -// Use custom templates with fallback to defaults -$customBaseTemplate = dirname(__DIR__) . '/custom/templates/base.php'; -$defaultBaseTemplate = __DIR__ . '/default/templates/base.php'; -$baseTemplate = file_exists($customBaseTemplate) ? $customBaseTemplate : $defaultBaseTemplate; - -$customPageTemplate = dirname(__DIR__) . '/custom/templates/page.php'; -$defaultPageTemplate = __DIR__ . '/default/templates/page.php'; -$pageTemplate = file_exists($customPageTemplate) ? $customPageTemplate : $defaultPageTemplate; - -$customListTemplate = dirname(__DIR__) . '/custom/templates/list.php'; -$defaultListTemplate = __DIR__ . '/default/templates/list.php'; -$listTemplate = file_exists($customListTemplate) ? $customListTemplate : $defaultListTemplate; +// Resolve templates with custom fallback to defaults +$baseTemplate = resolveTemplate('base'); +$pageTemplate = resolveTemplate('page'); +$listTemplate = resolveTemplate('list'); diff --git a/app/constants.php b/app/constants.php new file mode 100644 index 0000000..e54e340 --- /dev/null +++ b/app/constants.php @@ -0,0 +1,7 @@ += 3) { // Pattern: name.lang.ext $fileLang = $parts[count($parts) - 2]; - if (in_array($fileLang, ['no', 'en'])) { + if (in_array($fileLang, $availableLangs)) { // Only include if it matches current language if ($fileLang === $lang) { $contentFiles[] = [ 'path' => $filePath, 'name' => $file, - 'sort_key' => $parts[0] // Use base name for sorting + 'sort_key' => $parts[0] ]; } continue; } } - // Default files (no language suffix) - include if current lang is default - // or if no language-specific version exists + // Default files (no language suffix) - include if no language-specific version exists $baseName = $parts[0]; $hasLangVersion = false; if ($lang !== $defaultLang) { // Check if language-specific version exists - foreach ($extensions as $checkExt) { + foreach (CONTENT_EXTENSIONS as $checkExt) { if (file_exists("$dir/$baseName.$lang.$checkExt")) { $hasLangVersion = true; break; @@ -86,10 +83,7 @@ function resolveTranslatedPath(string $requestPath, string $contentDir, string $ // Check all subdirectories for slug matches $found = false; if (is_dir($currentPath)) { - $subdirs = array_filter( - scandir($currentPath) ?: [], - fn($item) => !in_array($item, ['.', '..']) && is_dir("$currentPath/$item") - ); + $subdirs = getSubdirectories($currentPath); foreach ($subdirs as $dir) { $metadata = loadMetadata("$currentPath/$dir", $lang, $defaultLang); @@ -123,10 +117,7 @@ function parseRequestPath(string $requestPath, string $contentDir, bool $hasTrai if (is_dir($contentPath)) { // Check if directory has subdirectories - $hasSubdirs = !empty(array_filter( - scandir($contentPath) ?: [], - fn($item) => !in_array($item, ['.', '..']) && is_dir("$contentPath/$item") - )); + $hasSubdirs = !empty(getSubdirectories($contentPath)); // If directory has subdirectories, it's an article-type folder (list view) if ($hasSubdirs) { @@ -176,12 +167,7 @@ function loadTranslations(string $lang): array { function buildNavigation(string $contentDir, string $currentLang, string $defaultLang): array { $navItems = []; - - // Scan top-level directories in content - $items = array_filter( - scandir($contentDir) ?: [], - fn($item) => !in_array($item, ['.', '..']) && is_dir("$contentDir/$item") - ); + $items = getSubdirectories($contentDir); foreach ($items as $item) { $itemPath = "$contentDir/$item"; @@ -204,7 +190,7 @@ function buildNavigation(string $contentDir, string $currentLang, string $defaul // Extract title and build URL $title = $metadata['title'] ?? extractTitle($itemPath, $currentLang, $defaultLang) ?? ucfirst($item); - $langPrefix = $currentLang !== $defaultLang ? "/$currentLang" : ''; + $langPrefix = getLangPrefix($currentLang, $defaultLang); // Use translated slug if available $urlSlug = ($currentLang !== $defaultLang && $metadata && isset($metadata['slug'])) diff --git a/app/helpers.php b/app/helpers.php index 3bd70ed..0638faf 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -1,5 +1,23 @@ !in_array($item, ['.', '..']) && is_dir("$dir/$item") + ); +} + +function getLangPrefix(string $currentLang, string $defaultLang): string { + return $currentLang !== $defaultLang ? "/$currentLang" : ''; +} + function extractTitle(string $filePath, string $lang, string $defaultLang): ?string { $files = findAllContentFiles($filePath, $lang, $defaultLang); if (empty($files)) return null; @@ -37,8 +55,7 @@ function extractDateFromFolder(string $folderName): ?string { } function findCoverImage(string $dirPath): ?string { - $extensions = ['jpg', 'jpeg', 'png', 'webp', 'gif']; - foreach ($extensions as $ext) { + foreach (COVER_IMAGE_EXTENSIONS as $ext) { if (file_exists("$dirPath/cover.$ext")) { return "cover.$ext"; } @@ -47,11 +64,6 @@ function findCoverImage(string $dirPath): ?string { } function findPdfFile(string $dirPath): ?string { - $files = scandir($dirPath) ?: []; - foreach ($files as $file) { - if (pathinfo($file, PATHINFO_EXTENSION) === 'pdf') { - return $file; - } - } - return null; + $pdfs = glob("$dirPath/*.pdf"); + return $pdfs ? basename($pdfs[0]) : null; } diff --git a/app/rendering.php b/app/rendering.php index 94c7c8b..dd3391a 100644 --- a/app/rendering.php +++ b/app/rendering.php @@ -1,18 +1,35 @@ buildNavigation($contentDir, $currentLang, $defaultLang), + 'homeLabel' => loadMetadata($contentDir, $currentLang, $defaultLang)['slug'] ?? 'Home', + 'translations' => loadTranslations($currentLang) + ]; +} + +function renderContentFile(string $filePath): string { + $ext = pathinfo($filePath, PATHINFO_EXTENSION); + + ob_start(); + if ($ext === 'md') { + if (!class_exists('Parsedown')) { + require_once __DIR__ . '/vendor/Parsedown.php'; + } + echo '
' . (new Parsedown())->text(file_get_contents($filePath)) . '
'; + } elseif (in_array($ext, ['html', 'php'])) { + include $filePath; + } + return ob_get_clean(); +} + function renderTemplate(string $content, int $statusCode = 200): void { - global $baseTemplate, $contentDir, $currentLang, $defaultLang; - - // Build navigation for templates - $navigation = buildNavigation($contentDir, $currentLang, $defaultLang); - - // Load frontpage metadata for home button label - $frontpageMetadata = loadMetadata($contentDir, $currentLang, $defaultLang); - $homeLabel = $frontpageMetadata['slug'] ?? 'Home'; - - // Load translations - $translations = loadTranslations($currentLang); - + global $baseTemplate; + + extract(prepareTemplateContext()); + http_response_code($statusCode); include $baseTemplate; exit; @@ -28,33 +45,16 @@ function renderFile(string $filePath): void { $ext = pathinfo($realPath, PATHINFO_EXTENSION); - if (in_array($ext, ['php', 'html', 'md'])) { - ob_start(); - if ($ext === 'md') { - if (!class_exists('Parsedown')) { - require_once __DIR__ . '/vendor/Parsedown.php'; - } - echo '
' . (new Parsedown())->text(file_get_contents($realPath)) . '
'; - } else { - include $realPath; - } - $content = ob_get_clean(); + if (in_array($ext, CONTENT_EXTENSIONS)) { + $content = renderContentFile($realPath); - // Build navigation for templates - $navigation = buildNavigation($contentDir, $currentLang, $defaultLang); - - // Load metadata for current page/directory + // Prepare template variables + extract(prepareTemplateContext()); + $pageDir = dirname($realPath); $pageMetadata = loadMetadata($pageDir, $currentLang, $defaultLang); $pageTitle = $pageMetadata['title'] ?? null; - // Load frontpage metadata for home button label - $frontpageMetadata = loadMetadata($contentDir, $currentLang, $defaultLang); - $homeLabel = $frontpageMetadata['slug'] ?? 'Home'; - - // Load translations - $translations = loadTranslations($currentLang); - // Wrap content with page template ob_start(); include $pageTemplate; @@ -83,38 +83,14 @@ function renderMultipleFiles(array $filePaths, string $pageDir): void { } // Render all content files in order - $content = ''; - foreach ($filePaths as $filePath) { - $ext = pathinfo($filePath, PATHINFO_EXTENSION); - - ob_start(); - if ($ext === 'md') { - if (!class_exists('Parsedown')) { - require_once __DIR__ . '/vendor/Parsedown.php'; - } - echo '
' . (new Parsedown())->text(file_get_contents($filePath)) . '
'; - } elseif ($ext === 'html') { - include $filePath; - } elseif ($ext === 'php') { - include $filePath; - } - $content .= ob_get_clean(); - } + $content = implode('', array_map('renderContentFile', $filePaths)); - // Build navigation for templates - $navigation = buildNavigation($contentDir, $currentLang, $defaultLang); - - // Load metadata for current page/directory + // Prepare template variables + extract(prepareTemplateContext()); + $pageMetadata = loadMetadata($pageDir, $currentLang, $defaultLang); $pageTitle = $pageMetadata['title'] ?? null; - // Load frontpage metadata for home button label - $frontpageMetadata = loadMetadata($contentDir, $currentLang, $defaultLang); - $homeLabel = $frontpageMetadata['slug'] ?? 'Home'; - - // Load translations - $translations = loadTranslations($currentLang); - // Wrap content with page template ob_start(); include $pageTemplate; diff --git a/app/router.php b/app/router.php index 5ec37b0..77e135d 100644 --- a/app/router.php +++ b/app/router.php @@ -1,8 +1,9 @@ text(file_get_contents($file)); - } else { - include $file; - } - } - $pageContent = ob_get_clean(); + $pageContent = implode('', array_map('renderContentFile', $contentFiles)); } // Load metadata for this directory @@ -79,10 +66,10 @@ switch ($parsedPath['type']) { $templateName = $metadata['page_template']; // Add .php extension if not present if (!str_ends_with($templateName, '.php')) { - $templateName .= '.php'; + $templateName = str_replace('.php', '', $templateName); } - $customTemplate = dirname(__DIR__) . '/custom/templates/' . $templateName; - $defaultTemplate = __DIR__ . '/default/templates/' . $templateName; + $customTemplate = dirname(__DIR__) . "/custom/templates/$templateName.php"; + $defaultTemplate = __DIR__ . "/default/templates/$templateName.php"; if (file_exists($customTemplate)) { $listTemplate = $customTemplate; @@ -92,13 +79,11 @@ switch ($parsedPath['type']) { // If template doesn't exist, fall back to default $listTemplate } - // Default directory listing - $subdirs = array_filter( - scandir($dir) ?: [], - fn($item) => !in_array($item, ['.', '..']) && is_dir("$dir/$item") - ); + // Build list items + $subdirs = getSubdirectories($dir); + $langPrefix = getLangPrefix($currentLang, $defaultLang); - $items = array_filter(array_map(function($item) use ($dir, $requestPath, $currentLang, $defaultLang) { + $items = array_filter(array_map(function($item) use ($dir, $requestPath, $currentLang, $defaultLang, $langPrefix) { $itemPath = "$dir/$item"; // Check if content exists for current language @@ -119,20 +104,20 @@ switch ($parsedPath['type']) { $date = extractDateFromFolder($item) ?: date("F d, Y", filemtime($itemPath)); } - $langPrefix = $currentLang !== $defaultLang ? "/$currentLang" : ''; - // Use translated slug if available, otherwise use folder name $urlSlug = ($currentLang !== $defaultLang && $metadata && isset($metadata['slug'])) ? $metadata['slug'] : $item; + $baseUrl = $langPrefix . '/' . trim($requestPath, '/') . '/' . urlencode($urlSlug); + return [ 'title' => $title, 'date' => $date, - 'url' => $langPrefix . '/' . trim($requestPath, '/') . '/' . urlencode($urlSlug), - 'cover' => $coverImage ? $langPrefix . '/' . trim($requestPath, '/') . '/' . urlencode($urlSlug) . '/' . $coverImage : null, + 'url' => $baseUrl, + 'cover' => $coverImage ? "$baseUrl/$coverImage" : null, 'summary' => $metadata['summary'] ?? null, - 'pdf' => $pdfFile ? $langPrefix . '/' . trim($requestPath, '/') . '/' . urlencode($urlSlug) . '/' . $pdfFile : null, + 'pdf' => $pdfFile ? "$baseUrl/$pdfFile" : null, 'redirect' => $metadata['redirect'] ?? null ]; }, $subdirs));