Add support for page-specific JavaScript files with cache busting via MD5 hash. The script is loaded at the end of the body with defer attribute. The JavaScript file must be named script.js and located in the same directory as the page content.
126 lines
4.1 KiB
PHP
126 lines
4.1 KiB
PHP
<?php
|
|
|
|
function renderContentFile(string $filePath, ?Context $ctx = null): string {
|
|
$ext = pathinfo($filePath, PATHINFO_EXTENSION);
|
|
|
|
ob_start();
|
|
if ($ext === 'md') {
|
|
require_once __DIR__ . '/cache.php';
|
|
$langPrefix = $ctx ? $ctx->get('langPrefix', '') : '';
|
|
$cached = getCachedMarkdown($filePath, $langPrefix);
|
|
|
|
if ($cached !== null) {
|
|
echo $cached;
|
|
} else {
|
|
// Update to newer versions before PHP 9.0 release
|
|
// Current versions have been patched for PHP 8.4+ compatibility
|
|
if (!class_exists('Parsedown')) {
|
|
require_once __DIR__ . '/vendor/Parsedown.php';
|
|
}
|
|
if (!class_exists('ParsedownExtra')) {
|
|
require_once __DIR__ . '/vendor/ParsedownExtra.php';
|
|
}
|
|
$html = (new ParsedownExtra())->text(file_get_contents($filePath));
|
|
|
|
if ($langPrefix) {
|
|
$html = preg_replace(
|
|
'/href="(\/[^"]*)"/',
|
|
'href="' . $langPrefix . '$1"',
|
|
$html
|
|
);
|
|
}
|
|
|
|
setCachedMarkdown($filePath, $html, $langPrefix);
|
|
echo $html;
|
|
}
|
|
} elseif (in_array($ext, ['html', 'php'])) {
|
|
if ($ctx !== null && $ext === 'php') {
|
|
$templateVars = Hooks::apply(Hook::TEMPLATE_VARS, [], $ctx);
|
|
extract($templateVars);
|
|
}
|
|
include $filePath;
|
|
}
|
|
return ob_get_clean();
|
|
}
|
|
|
|
function renderTemplate(Context $ctx, string $content, int $statusCode = 200): void {
|
|
global $GLOBALS;
|
|
|
|
$navigation = $ctx->navigation;
|
|
$homeLabel = $ctx->homeLabel;
|
|
|
|
$templateVars = Hooks::apply(Hook::TEMPLATE_VARS, [
|
|
'content' => $content,
|
|
'navigation' => $navigation,
|
|
'homeLabel' => $homeLabel,
|
|
'pageTitle' => $ctx->get('pageTitle'),
|
|
'metaDescription' => $ctx->get('metaDescription'),
|
|
'pageCssUrl' => $ctx->get('pageCssUrl'),
|
|
'pageCssHash' => $ctx->get('pageCssHash'),
|
|
'pageJsUrl' => $ctx->get('pageJsUrl'),
|
|
'pageJsHash' => $ctx->get('pageJsHash'),
|
|
'feedUrl' => $ctx->get('feedUrl')
|
|
], $ctx);
|
|
|
|
extract($templateVars);
|
|
|
|
http_response_code($statusCode);
|
|
include $ctx->templates->base;
|
|
exit;
|
|
}
|
|
|
|
|
|
function renderMultipleFiles(Context $ctx, array $files, string $pageDir): void {
|
|
// Load metadata and page plugins BEFORE rendering content files
|
|
// so that plugin-provided template variables are available to PHP content files
|
|
$pageMetadata = loadMetadata($pageDir);
|
|
getPluginManager()->loadPagePlugins($pageMetadata);
|
|
|
|
$content = '';
|
|
foreach ($files as $file) {
|
|
$content .= renderContentFile($file, $ctx);
|
|
}
|
|
|
|
$navigation = $ctx->navigation;
|
|
$homeLabel = $ctx->homeLabel;
|
|
$pageTitle = $pageMetadata['title'] ?? null;
|
|
$metaDescription = extractMetaDescription($pageDir, $pageMetadata);
|
|
|
|
$pageCss = findPageCss($pageDir, $ctx->contentDir);
|
|
$pageCssUrl = $pageCss['url'] ?? null;
|
|
$pageCssHash = $pageCss['hash'] ?? null;
|
|
|
|
$pageJs = findPageJs($pageDir, $ctx->contentDir);
|
|
$pageJsUrl = $pageJs['url'] ?? null;
|
|
$pageJsHash = $pageJs['hash'] ?? null;
|
|
|
|
$coverImage = findCoverImage($pageDir);
|
|
$socialImageUrl = null;
|
|
if ($coverImage) {
|
|
$relativePath = str_replace($ctx->contentDir, '', $pageDir);
|
|
$relativePath = trim($relativePath, '/');
|
|
$socialImageUrl = '/' . ($relativePath ? $relativePath . '/' : '') . $coverImage;
|
|
}
|
|
|
|
$templateVars = Hooks::apply(Hook::TEMPLATE_VARS, [
|
|
'content' => $content,
|
|
'navigation' => $navigation,
|
|
'homeLabel' => $homeLabel,
|
|
'pageTitle' => $pageTitle,
|
|
'metaDescription' => $metaDescription,
|
|
'pageCssUrl' => $pageCssUrl,
|
|
'pageCssHash' => $pageCssHash,
|
|
'pageJsUrl' => $pageJsUrl,
|
|
'pageJsHash' => $pageJsHash,
|
|
'socialImageUrl' => $socialImageUrl
|
|
], $ctx);
|
|
|
|
extract($templateVars);
|
|
|
|
ob_start();
|
|
require $ctx->templates->page;
|
|
$wrappedContent = ob_get_clean();
|
|
|
|
include $ctx->templates->base;
|
|
exit;
|
|
}
|