folderweb/app/router.php
Ruben ca91a18cb7 Add default styles and enable language plugin
Add stylesheet and enable language plugin with Norwegian support
2025-11-27 21:29:35 +01:00

191 lines
6.5 KiB
PHP

<?php
// Load modular components
require_once __DIR__ . '/constants.php';
require_once __DIR__ . '/hooks.php';
require_once __DIR__ . '/context.php';
require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/plugins.php';
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/content.php';
require_once __DIR__ . '/rendering.php';
// Create context
$ctx = createContext();
// Store globally for easy access
$GLOBALS['ctx'] = $ctx;
// Check for assets in /custom/assets/ served at root level
$assetPath = dirname(__DIR__) . '/custom/assets/' . $ctx->requestPath;
if (file_exists($assetPath) && is_file($assetPath)) {
header('Content-Type: ' . (mime_content_type($assetPath) ?: 'application/octet-stream'));
readfile($assetPath);
exit;
}
// Check for assets in content directory (CSS, images, etc.)
$contentAssetPath = $ctx->contentDir . '/' . $ctx->requestPath;
if (file_exists($contentAssetPath) && is_file($contentAssetPath)) {
$ext = pathinfo($contentAssetPath, PATHINFO_EXTENSION);
// Define MIME types for asset files
$mimeTypes = [
'css' => 'text/css',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
'webp' => 'image/webp',
'svg' => 'image/svg+xml',
'pdf' => 'application/pdf',
'woff' => 'font/woff',
'woff2' => 'font/woff2',
'ttf' => 'font/ttf',
'otf' => 'font/otf',
];
$extLower = strtolower($ext);
if (isset($mimeTypes[$extLower])) {
header('Content-Type: ' . $mimeTypes[$extLower]);
readfile($contentAssetPath);
exit;
}
}
// Handle frontpage
if (empty($ctx->requestPath)) {
$contentFiles = findAllContentFiles($ctx->contentDir);
if (!empty($contentFiles)) {
renderMultipleFiles($ctx, $contentFiles, $ctx->contentDir);
}
}
// Parse and handle request
$parsedPath = parseRequestPath($ctx);
switch ($parsedPath['type']) {
case 'page':
$dir = $parsedPath['path'];
// Redirect to add trailing slash if needed
if (!$ctx->hasTrailingSlash) {
header('Location: ' . rtrim($_SERVER['REQUEST_URI'], '/') . '/', true, 301);
exit;
}
$contentFiles = findAllContentFiles($dir);
if (!empty($contentFiles)) {
renderMultipleFiles($ctx, $contentFiles, $dir);
}
break;
case 'list':
$dir = $parsedPath['path'];
// Check for page content files in this directory
$pageContent = null;
$contentFiles = findAllContentFiles($dir);
if (!empty($contentFiles)) {
$pageContent = implode('', array_map('renderContentFile', $contentFiles));
}
// Load metadata for this directory
$metadata = loadMetadata($dir);
// Check if hide_list is enabled - if so, treat as page
if (isset($metadata['hide_list']) && $metadata['hide_list']) {
if (!empty($contentFiles)) {
renderMultipleFiles($ctx, $contentFiles, $dir);
}
break;
}
// Select list template based on metadata page_template
$listTemplate = $ctx->templates->list;
if (isset($metadata['page_template']) && !empty($metadata['page_template'])) {
$templateName = $metadata['page_template'];
if (!str_ends_with($templateName, '.php')) {
$templateName .= '';
}
$customTemplate = dirname(__DIR__) . "/custom/templates/$templateName.php";
$defaultTemplate = __DIR__ . "/default/templates/$templateName.php";
if (file_exists($customTemplate)) {
$listTemplate = $customTemplate;
} elseif (file_exists($defaultTemplate)) {
$listTemplate = $defaultTemplate;
}
}
// Build list items
$subdirs = getSubdirectories($dir);
$items = array_filter(array_map(function($item) use ($dir, $ctx) {
$itemPath = "$dir/$item";
$metadata = loadMetadata($itemPath);
$coverImage = findCoverImage($itemPath);
$pdfFile = findPdfFile($itemPath);
$title = $metadata['title'] ?? extractTitle($itemPath) ?? $item;
$date = null;
if (isset($metadata['date'])) {
$date = $metadata['date'];
// Let plugins format date
$date = Hooks::apply(Hook::PROCESS_CONTENT, $date, 'date_format');
} else {
$date = extractDateFromFolder($item) ?: date("F d, Y", filemtime($itemPath));
}
// Use slug if available
$urlSlug = ($metadata && isset($metadata['slug'])) ? $metadata['slug'] : $item;
$baseUrl = '/' . trim($ctx->requestPath, '/') . '/' . urlencode($urlSlug);
return [
'title' => $title,
'url' => $baseUrl . '/',
'date' => $date,
'summary' => $metadata['summary'] ?? null,
'cover' => $coverImage ? "$baseUrl/$coverImage" : null,
'pdf' => $pdfFile ? "$baseUrl/$pdfFile" : null,
'redirect' => $metadata['redirect'] ?? null
];
}, $subdirs));
// Sort by date (newest first) if dates are present
usort($items, fn($a, $b) => strcmp($b['date'] ?? '', $a['date'] ?? ''));
// Prepare all variables for base template
$navigation = $ctx->navigation;
$homeLabel = $ctx->homeLabel;
$pageTitle = $metadata['title'] ?? null;
$metaDescription = extractMetaDescription($dir, $metadata);
// Check for page-specific CSS
$pageCss = findPageCss($dir, $ctx->contentDir);
// Let plugins add template variables
$templateVars = Hooks::apply(Hook::TEMPLATE_VARS, [
'navigation' => $navigation,
'homeLabel' => $homeLabel,
'pageTitle' => $pageTitle,
'metaDescription' => $metaDescription,
'pageCss' => $pageCss,
'items' => $items,
'pageContent' => $pageContent
], $ctx);
extract($templateVars);
ob_start();
require $listTemplate;
$content = ob_get_clean();
renderTemplate($ctx, $content);
break;
case 'not_found':
http_response_code(404);
renderTemplate($ctx, "<h1>404 - Page Not Found</h1><p>The requested page could not be found.</p>", 404);
break;
}