Add global and page-level plugin support Implement language-aware content filtering Add month translations to language files Refactor date formatting to use translations Move translation loading to plugin system Improve content availability checks
161 lines
6.3 KiB
PHP
161 lines
6.3 KiB
PHP
<?php
|
|
|
|
// Load modular components
|
|
require_once __DIR__ . '/constants.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 - no more globals!
|
|
$ctx = createContext();
|
|
|
|
// 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, $ctx->currentLang, $ctx->defaultLang, $ctx->availableLangs);
|
|
if (!empty($contentFiles)) {
|
|
renderMultipleFiles($ctx, $contentFiles, $ctx->contentDir);
|
|
}
|
|
}
|
|
|
|
// Parse and handle request
|
|
$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");
|
|
}
|
|
|
|
// Check for page content files in this directory
|
|
$pageContent = null;
|
|
$contentFiles = findAllContentFiles($dir, $ctx->currentLang, $ctx->defaultLang, $ctx->availableLangs);
|
|
if (!empty($contentFiles)) {
|
|
$pageContent = implode('', array_map('renderContentFile', $contentFiles));
|
|
}
|
|
|
|
// Load metadata for this directory
|
|
$metadata = loadMetadata($dir, $ctx->currentLang, $ctx->defaultLang);
|
|
|
|
// 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);
|
|
}
|
|
$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";
|
|
|
|
// 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);
|
|
$coverImage = findCoverImage($itemPath);
|
|
$pdfFile = findPdfFile($itemPath);
|
|
|
|
$title = $metadata['title'] ?? extractTitle($itemPath, $ctx->currentLang, $ctx->defaultLang) ?? $item;
|
|
$date = null;
|
|
if (isset($metadata['date'])) {
|
|
$date = formatDate($metadata['date'], $ctx->currentLang);
|
|
} else {
|
|
$date = extractDateFromFolder($item, $ctx->currentLang) ?: 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;
|
|
|
|
$baseUrl = $ctx->langPrefix . '/' . trim($ctx->requestPath, '/') . '/' . urlencode($urlSlug);
|
|
|
|
return [
|
|
'title' => $title,
|
|
'date' => $date,
|
|
'url' => $baseUrl,
|
|
'cover' => $coverImage ? "$baseUrl/$coverImage" : null,
|
|
'summary' => $metadata['summary'] ?? null,
|
|
'pdf' => $pdfFile ? "$baseUrl/$pdfFile" : null,
|
|
'redirect' => $metadata['redirect'] ?? null
|
|
];
|
|
}, $subdirs));
|
|
|
|
ob_start();
|
|
include $listTemplate;
|
|
$content = ob_get_clean();
|
|
|
|
// 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);
|
|
|
|
// 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;
|
|
}
|
|
|
|
include $ctx->templates->base;
|
|
exit;
|
|
|
|
case 'not_found':
|
|
renderTemplate($ctx, "<h1>404 Not Found</h1><p>The requested resource was not found.</p>", 404);
|
|
}
|