Refactor to use plugin system for language support Remove hardcoded language features from core Move language handling to plugin system Improve content file discovery Simplify context creation Add plugin system documentation Implement hook system for extensibility Add template variable hook Add context storage for plugins Improve error handling Refactor rendering logic Improve list view sorting Add support for custom list templates Improve metadata handling Add plugin system reference documentation
155 lines
5.3 KiB
PHP
155 lines
5.3 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;
|
|
}
|
|
|
|
// 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);
|
|
|
|
// 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;
|
|
}
|