Compare commits

..

No commits in common. "33943a907b85b6cda0515da8ec68214f4b4b408b" and "0e63ed14440ec0fdbf71153e358942a6ca19f16d" have entirely different histories.

5 changed files with 12 additions and 27 deletions

View file

@ -46,7 +46,10 @@ Hooks::add(Hook::PROCESS_CONTENT, function(mixed $data, string $dirOrType, strin
// Filter content files by language variant // Filter content files by language variant
if (is_array($data) && !empty($data) && isset($data[0]['path'])) { if (is_array($data) && !empty($data) && isset($data[0]['path'])) {
return filterFilesByLanguage($data, $dirOrType, $ctx); error_log("filterFilesByLanguage called with " . count($data) . " files, current lang: $currentLang");
$filtered = filterFilesByLanguage($data, $dirOrType, $ctx);
error_log("Filtered to " . count($filtered) . " files");
return $filtered;
} }
return $data; return $data;

View file

@ -59,8 +59,7 @@ function renderTemplate(Context $ctx, string $content, int $statusCode = 200): v
'pageCssHash' => $ctx->get('pageCssHash'), 'pageCssHash' => $ctx->get('pageCssHash'),
'pageJsUrl' => $ctx->get('pageJsUrl'), 'pageJsUrl' => $ctx->get('pageJsUrl'),
'pageJsHash' => $ctx->get('pageJsHash'), 'pageJsHash' => $ctx->get('pageJsHash'),
'feedUrl' => $ctx->get('feedUrl'), 'feedUrl' => $ctx->get('feedUrl')
'socialImageUrl' => $ctx->get('socialImageUrl')
], $ctx); ], $ctx);
extract($templateVars); extract($templateVars);
@ -74,8 +73,8 @@ function renderTemplate(Context $ctx, string $content, int $statusCode = 200): v
function renderMultipleFiles(Context $ctx, array $files, string $pageDir): void { function renderMultipleFiles(Context $ctx, array $files, string $pageDir): void {
// Load metadata and page plugins BEFORE rendering content files // Load metadata and page plugins BEFORE rendering content files
// so that plugin-provided template variables are available to PHP content files // so that plugin-provided template variables are available to PHP content files
$metadata = loadMetadata($pageDir); $pageMetadata = loadMetadata($pageDir);
getPluginManager()->loadPagePlugins($metadata); getPluginManager()->loadPagePlugins($pageMetadata);
$content = ''; $content = '';
foreach ($files as $file) { foreach ($files as $file) {
@ -84,8 +83,8 @@ function renderMultipleFiles(Context $ctx, array $files, string $pageDir): void
$navigation = $ctx->navigation; $navigation = $ctx->navigation;
$homeLabel = $ctx->homeLabel; $homeLabel = $ctx->homeLabel;
$pageTitle = $metadata['title'] ?? null; $pageTitle = $pageMetadata['title'] ?? null;
$metaDescription = extractMetaDescription($pageDir, $metadata); $metaDescription = extractMetaDescription($pageDir, $pageMetadata);
$pageCss = findPageCss($pageDir, $ctx->contentDir); $pageCss = findPageCss($pageDir, $ctx->contentDir);
$pageCssUrl = $pageCss['url'] ?? null; $pageCssUrl = $pageCss['url'] ?? null;
@ -113,8 +112,7 @@ function renderMultipleFiles(Context $ctx, array $files, string $pageDir): void
'pageCssHash' => $pageCssHash, 'pageCssHash' => $pageCssHash,
'pageJsUrl' => $pageJsUrl, 'pageJsUrl' => $pageJsUrl,
'pageJsHash' => $pageJsHash, 'pageJsHash' => $pageJsHash,
'socialImageUrl' => $socialImageUrl, 'socialImageUrl' => $socialImageUrl
'metadata' => $metadata
], $ctx); ], $ctx);
extract($templateVars); extract($templateVars);

View file

@ -249,14 +249,6 @@ switch ($parsedPath['type']) {
? $langPrefix . '/' . trim($ctx->requestPath, '/') . '/feed.xml' ? $langPrefix . '/' . trim($ctx->requestPath, '/') . '/feed.xml'
: null; : null;
// Build social image URL from cover image if present
$coverImage = findCoverImage($dir);
$socialImageUrl = null;
if ($coverImage) {
$relativePath = trim(str_replace($ctx->contentDir, '', $dir), '/');
$socialImageUrl = '/' . ($relativePath ? $relativePath . '/' : '') . $coverImage;
}
// Store for base template (renderTemplate reads these from context) // Store for base template (renderTemplate reads these from context)
$ctx->set('pageTitle', $pageTitle); $ctx->set('pageTitle', $pageTitle);
$ctx->set('metaDescription', $metaDescription); $ctx->set('metaDescription', $metaDescription);
@ -265,7 +257,6 @@ switch ($parsedPath['type']) {
$ctx->set('pageJsUrl', $pageJsUrl); $ctx->set('pageJsUrl', $pageJsUrl);
$ctx->set('pageJsHash', $pageJsHash); $ctx->set('pageJsHash', $pageJsHash);
$ctx->set('feedUrl', $feedUrl); $ctx->set('feedUrl', $feedUrl);
$ctx->set('socialImageUrl', $socialImageUrl);
// Let plugins add template variables // Let plugins add template variables
$templateVars = Hooks::apply(Hook::TEMPLATE_VARS, [ $templateVars = Hooks::apply(Hook::TEMPLATE_VARS, [
@ -279,9 +270,7 @@ switch ($parsedPath['type']) {
'pageJsHash' => $pageJsHash, 'pageJsHash' => $pageJsHash,
'items' => $items, 'items' => $items,
'pageContent' => $pageContent, 'pageContent' => $pageContent,
'feedUrl' => $feedUrl, 'feedUrl' => $feedUrl
'socialImageUrl' => $socialImageUrl,
'metadata' => $metadata
], $ctx); ], $ctx);
extract($templateVars); extract($templateVars);

View file

@ -54,7 +54,6 @@ Returns flat key-value array with a special `_raw` key containing the full parse
| `order` | string | `"descending"` | List sort direction (`ascending`\|`descending`) | | `order` | string | `"descending"` | List sort direction (`ascending`\|`descending`) |
| `redirect` | string | — | External URL (list items can redirect) | | `redirect` | string | — | External URL (list items can redirect) |
| `feed` | bool | `false` | Enable Atom feed on list pages (`feed.xml`) | | `feed` | bool | `false` | Enable Atom feed on list pages (`feed.xml`) |
| `author` | string | title | Atom feed author name (falls back to page title) |
| `plugins` | string | — | Comma-separated page-level plugin names | | `plugins` | string | — | Comma-separated page-level plugin names |
### Settings Section ### Settings Section

View file

@ -57,8 +57,6 @@ Handled in `router.php` before `parseRequestPath()`. When a request path ends wi
Feed piggybacks on the existing Markdown cache — no separate feed cache needed. The `rawDate` field on items provides ISO dates for Atom `<updated>` elements. Content is wrapped in `<![CDATA[...]]>` with `]]>` safely escaped. Feed piggybacks on the existing Markdown cache — no separate feed cache needed. The `rawDate` field on items provides ISO dates for Atom `<updated>` elements. Content is wrapped in `<![CDATA[...]]>` with `]]>` safely escaped.
**Date deduplication:** Atom requires unique `<updated>` timestamps per entry. Items sharing the same date get seconds incremented (`T00:00:00Z`, `T00:00:01Z`, etc.) to ensure uniqueness while preserving sort order.
## Markdown Caching ## Markdown Caching
Defined in `app/cache.php`. File-based cache in `/tmp/folderweb_cache/`. Defined in `app/cache.php`. File-based cache in `/tmp/folderweb_cache/`.
@ -89,9 +87,7 @@ Files not in this list are not served as static assets.
### Custom Assets (router.php) ### Custom Assets (router.php)
Files in `custom/assets/` are served at the document root URL. Example: `custom/assets/favicon.ico``/favicon.ico`. Uses an explicit MIME type map; falls back to `application/octet-stream`. Files in `custom/assets/` are served at the document root URL. Example: `custom/assets/favicon.ico``/favicon.ico`. Uses `mime_content_type()` for MIME detection.
Cache-Control headers: `json` and `geojson` files get `max-age=60` (short TTL for data files); all other asset types get `max-age=31536000` (1 year, immutable).
### Framework Assets (static.php) ### Framework Assets (static.php)