folderweb/app/helpers.php
Ruben a205f2cbd7 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
2025-11-25 20:19:12 +01:00

109 lines
3.4 KiB
PHP

<?php
function resolveTemplate(string $templateName): string {
$customTemplate = dirname(__DIR__) . "/custom/templates/$templateName.php";
$defaultTemplate = __DIR__ . "/default/templates/$templateName.php";
return file_exists($customTemplate) ? $customTemplate : $defaultTemplate;
}
function getSubdirectories(string $dir): array {
if (!is_dir($dir)) return [];
return array_filter(
scandir($dir) ?: [],
fn($item) => !in_array($item, ['.', '..']) && is_dir("$dir/$item")
);
}
function extractTitle(string $filePath): ?string {
$files = findAllContentFiles($filePath);
if (empty($files)) return null;
// Check the first content file for a title
$file = $files[0];
$ext = pathinfo($file, PATHINFO_EXTENSION);
$content = file_get_contents($file);
if ($ext === 'md' && preg_match('/^#\s+(.+)$/m', $content, $matches)) {
return trim($matches[1]);
}
if (in_array($ext, ['html', 'php']) && preg_match('/<h1[^>]*>(.*?)<\/h1>/i', $content, $matches)) {
return strip_tags($matches[1]);
}
return null;
}
function extractDateFromFolder(string $folderName): ?string {
if (preg_match('/^(\d{4})-(\d{2})-(\d{2})-/', $folderName, $matches)) {
$dateString = $matches[1] . '-' . $matches[2] . '-' . $matches[3];
// Let plugins format the date
return Hooks::apply(Hook::PROCESS_CONTENT, $dateString, 'date_format');
}
return null;
}
function findCoverImage(string $dirPath): ?string {
$found = array_find(
COVER_IMAGE_EXTENSIONS,
fn($ext) => file_exists("$dirPath/cover.$ext")
);
return $found ? "cover.$found" : null;
}
function findPdfFile(string $dirPath): ?string {
$pdfs = glob("$dirPath/*.pdf") ?: [];
return $pdfs ? basename($pdfs[0]) : null;
}
function findPageCss(string $dirPath, string $contentDir): ?array {
$cssFile = "$dirPath/styles.css";
if (!file_exists($cssFile) || !is_file($cssFile)) {
return null;
}
$relativePath = str_replace($contentDir, '', $dirPath);
$relativePath = trim($relativePath, '/');
$cssUrl = '/' . ($relativePath ? $relativePath . '/' : '') . 'styles.css';
return [
'url' => $cssUrl,
'hash' => hash_file('md5', $cssFile)
];
}
function extractMetaDescription(string $dirPath, ?array $metadata): ?string {
// 1. Check for search_description in metadata
if ($metadata && isset($metadata['search_description'])) {
return $metadata['search_description'];
}
// 2. Fall back to summary in metadata
if ($metadata && isset($metadata['summary'])) {
return $metadata['summary'];
}
// 3. Fall back to first paragraph in content files
$files = findAllContentFiles($dirPath);
if (empty($files)) return null;
foreach ($files as $file) {
$ext = pathinfo($file, PATHINFO_EXTENSION);
$content = file_get_contents($file);
if ($ext === 'md') {
$lines = explode("\n", $content);
foreach ($lines as $line) {
$line = trim($line);
if (empty($line) || str_starts_with($line, '#')) continue;
if (strlen($line) > 20) {
return strip_tags($line);
}
}
} elseif (in_array($ext, ['html', 'php'])) {
if (preg_match('/<p[^>]*>(.*?)<\/p>/is', $content, $matches)) {
return strip_tags($matches[1]);
}
}
}
return null;
}