Remove language-specific content handling
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
This commit is contained in:
parent
24ee209e17
commit
a205f2cbd7
8 changed files with 524 additions and 315 deletions
124
app/router.php
124
app/router.php
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
// 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';
|
||||
|
|
@ -9,9 +10,12 @@ require_once __DIR__ . '/config.php';
|
|||
require_once __DIR__ . '/content.php';
|
||||
require_once __DIR__ . '/rendering.php';
|
||||
|
||||
// Create context - no more globals!
|
||||
// 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)) {
|
||||
|
|
@ -22,7 +26,7 @@ if (file_exists($assetPath) && is_file($assetPath)) {
|
|||
|
||||
// Handle frontpage
|
||||
if (empty($ctx->requestPath)) {
|
||||
$contentFiles = findAllContentFiles($ctx->contentDir, $ctx->currentLang, $ctx->defaultLang, $ctx->availableLangs);
|
||||
$contentFiles = findAllContentFiles($ctx->contentDir);
|
||||
if (!empty($contentFiles)) {
|
||||
renderMultipleFiles($ctx, $contentFiles, $ctx->contentDir);
|
||||
}
|
||||
|
|
@ -33,50 +37,43 @@ $parsedPath = parseRequestPath($ctx);
|
|||
|
||||
switch ($parsedPath['type']) {
|
||||
case 'page':
|
||||
// Page-type folder with content files (no subdirectories)
|
||||
// Redirect to add trailing slash if needed
|
||||
if (!empty($parsedPath['needsSlash'])) {
|
||||
header('Location: ' . rtrim($_SERVER['REQUEST_URI'], '/') . '/', true, 301);
|
||||
exit;
|
||||
}
|
||||
renderMultipleFiles($ctx, $parsedPath['files'], $parsedPath['path']);
|
||||
|
||||
case 'file':
|
||||
// Direct file access or legacy single file
|
||||
// Redirect to add trailing slash if this is a directory-based page
|
||||
if (!empty($parsedPath['needsSlash'])) {
|
||||
header('Location: ' . rtrim($_SERVER['REQUEST_URI'], '/') . '/', true, 301);
|
||||
exit;
|
||||
}
|
||||
renderFile($ctx, $parsedPath['path']);
|
||||
|
||||
case 'directory':
|
||||
$dir = $parsedPath['path'];
|
||||
if (file_exists("$dir/index.php")) {
|
||||
renderFile($ctx, "$dir/index.php");
|
||||
|
||||
// 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, $ctx->currentLang, $ctx->defaultLang, $ctx->availableLangs);
|
||||
$contentFiles = findAllContentFiles($dir);
|
||||
if (!empty($contentFiles)) {
|
||||
$pageContent = implode('', array_map('renderContentFile', $contentFiles));
|
||||
}
|
||||
|
||||
// Load metadata for this directory
|
||||
$metadata = loadMetadata($dir, $ctx->currentLang, $ctx->defaultLang);
|
||||
$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'];
|
||||
// Add .php extension if not present
|
||||
if (!str_ends_with($templateName, '.php')) {
|
||||
$templateName = str_replace('.php', '', $templateName);
|
||||
$templateName .= '';
|
||||
}
|
||||
$customTemplate = dirname(__DIR__) . "/custom/templates/$templateName.php";
|
||||
$defaultTemplate = __DIR__ . "/default/templates/$templateName.php";
|
||||
|
||||
|
||||
if (file_exists($customTemplate)) {
|
||||
$listTemplate = $customTemplate;
|
||||
} elseif (file_exists($defaultTemplate)) {
|
||||
|
|
@ -89,73 +86,70 @@ switch ($parsedPath['type']) {
|
|||
|
||||
$items = array_filter(array_map(function($item) use ($dir, $ctx) {
|
||||
$itemPath = "$dir/$item";
|
||||
|
||||
// Check if content exists for current language
|
||||
if ($ctx->currentLang !== $ctx->defaultLang && shouldHideUntranslated()) {
|
||||
$hasLangContent = hasLanguageContent($itemPath, $ctx->currentLang, CONTENT_EXTENSIONS);
|
||||
$hasLangMetadata = hasLanguageMetadata($itemPath, $ctx->currentLang);
|
||||
if (!$hasLangContent && !$hasLangMetadata) return null;
|
||||
}
|
||||
|
||||
$metadata = loadMetadata($itemPath, $ctx->currentLang, $ctx->defaultLang);
|
||||
$metadata = loadMetadata($itemPath);
|
||||
$coverImage = findCoverImage($itemPath);
|
||||
$pdfFile = findPdfFile($itemPath);
|
||||
|
||||
$title = $metadata['title'] ?? extractTitle($itemPath, $ctx->currentLang, $ctx->defaultLang) ?? $item;
|
||||
$title = $metadata['title'] ?? extractTitle($itemPath) ?? $item;
|
||||
$date = null;
|
||||
if (isset($metadata['date'])) {
|
||||
$date = formatDate($metadata['date'], $ctx->currentLang);
|
||||
$date = $metadata['date'];
|
||||
// Let plugins format date
|
||||
$date = Hooks::apply(Hook::PROCESS_CONTENT, $date, 'date_format');
|
||||
} else {
|
||||
$date = extractDateFromFolder($item, $ctx->currentLang) ?: date("F d, Y", filemtime($itemPath));
|
||||
$date = extractDateFromFolder($item) ?: date("F d, Y", filemtime($itemPath));
|
||||
}
|
||||
|
||||
// Use translated slug if available, otherwise use folder name
|
||||
$urlSlug = ($ctx->currentLang !== $ctx->defaultLang && $metadata && isset($metadata['slug']))
|
||||
? $metadata['slug']
|
||||
: $item;
|
||||
// Use slug if available
|
||||
$urlSlug = ($metadata && isset($metadata['slug'])) ? $metadata['slug'] : $item;
|
||||
|
||||
$baseUrl = $ctx->langPrefix . '/' . trim($ctx->requestPath, '/') . '/' . urlencode($urlSlug);
|
||||
$baseUrl = '/' . trim($ctx->requestPath, '/') . '/' . urlencode($urlSlug);
|
||||
|
||||
return [
|
||||
'title' => $title,
|
||||
'url' => $baseUrl . '/',
|
||||
'date' => $date,
|
||||
'url' => $baseUrl,
|
||||
'cover' => $coverImage ? "$baseUrl/$coverImage" : null,
|
||||
'summary' => $metadata['summary'] ?? null,
|
||||
'cover' => $coverImage ? "$baseUrl/$coverImage" : null,
|
||||
'pdf' => $pdfFile ? "$baseUrl/$pdfFile" : null,
|
||||
'redirect' => $metadata['redirect'] ?? null
|
||||
];
|
||||
}, $subdirs));
|
||||
|
||||
ob_start();
|
||||
include $listTemplate;
|
||||
$content = ob_get_clean();
|
||||
// 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
|
||||
$currentLang = $ctx->currentLang;
|
||||
$navigation = $ctx->navigation;
|
||||
$homeLabel = $ctx->homeLabel;
|
||||
$translations = $ctx->translations;
|
||||
$pageTitle = $metadata['title'] ?? null;
|
||||
$metaDescription = extractMetaDescription($dir, $metadata, $ctx->currentLang, $ctx->defaultLang);
|
||||
$metaDescription = extractMetaDescription($dir, $metadata);
|
||||
|
||||
// Check for page-specific CSS
|
||||
$pageCss = findPageCss($dir, $ctx->contentDir);
|
||||
$pageCssUrl = $pageCss['url'] ?? null;
|
||||
$pageCssHash = $pageCss['hash'] ?? null;
|
||||
|
||||
// Check for cover image for social media
|
||||
$coverImage = findCoverImage($dir);
|
||||
$socialImageUrl = null;
|
||||
if ($coverImage) {
|
||||
$relativePath = str_replace($ctx->contentDir, '', $dir);
|
||||
$relativePath = trim($relativePath, '/');
|
||||
$socialImageUrl = '/' . ($relativePath ? $relativePath . '/' : '') . $coverImage;
|
||||
}
|
||||
// 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();
|
||||
|
||||
include $ctx->templates->base;
|
||||
exit;
|
||||
renderTemplate($ctx, $content);
|
||||
break;
|
||||
|
||||
case 'not_found':
|
||||
renderTemplate($ctx, "<h1>404 Not Found</h1><p>The requested resource was not found.</p>", 404);
|
||||
http_response_code(404);
|
||||
renderTemplate($ctx, "<h1>404 - Page Not Found</h1><p>The requested page could not be found.</p>", 404);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue