{data?.title || 'Article'}
-Article view - To be implemented
+diff --git a/site/templates/article.json.php b/site/templates/article.json.php index 20a8f29..b247fe9 100644 --- a/site/templates/article.json.php +++ b/site/templates/article.json.php @@ -6,26 +6,19 @@ if ($related->isEmpty()) { } $specificData = [ - 'date' => $page->date()->toDate('Y-m-d'), - 'dateFormatted' => $page->date()->toDate('d/m/Y'), - 'intro' => $page->intro()->value(), - 'author' => [ - 'name' => $page->authorName()->value(), - 'role' => $page->authorRole()->value(), - 'photo' => $page->authorPhoto()->toFile()?->url() - ], - 'cover' => $page->cover()->toFile()?->url(), - 'content' => $page->articleContent()->toBlocks(), - 'tags' => $page->tags()->split(), - 'related' => $related->map(function($rec) { + 'date' => $page->date()->toDate('d/m/Y'), + 'intro' => $page->intro()->value(), + 'cover' => $page->cover()->toFile()?->url(), + 'body' => (string) $page->body()->toBlocks(), + 'related' => $related->map(function($rec) { return [ 'title' => $rec->title()->value(), - 'url' => $rec->url(), - 'category' => $rec->category()->value(), - 'cover' => $rec->cover()->toFile()?->thumb(['width' => 400])->url() + 'slug' => $rec->slug(), + 'date' => $rec->date()->toDate('d/m/Y'), + 'cover' => $rec->cover()->toFile()?->url(), ]; })->values(), - 'parentUrl' => $page->parent()->url() + 'parentUrl' => $page->parent()->url(), ]; $pageData = array_merge($genericData, $specificData); diff --git a/src/router/index.js b/src/router/index.js index edf64d0..6e931f9 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -8,16 +8,39 @@ function normalizePath(path) { return path === "/" ? "/home" : path; } +/** + * Trouve l'index de la slide correspondant au path. + * Si le path exact n'existe pas, essaie le chemin parent + * (ex: /blog/article-slug → /blog). + */ +function findSlideIndex(path) { + let idx = slides.getIndexByPath(path); + if (idx !== -1) return idx; + const parentPath = path.replace(/\/[^/]+$/, ""); + if (parentPath) return slides.getIndexByPath(parentPath); + return -1; +} + async function loadSlide(path) { - const idx = slides.getIndexByPath(path); + let slidePath = path; + let idx = slides.getIndexByPath(slidePath); + + // Sub-page: resolve to parent slide (ex: /blog/slug → /blog) + if (idx === -1) { + const parentPath = path.replace(/\/[^/]+$/, ""); + idx = slides.getIndexByPath(parentPath); + if (idx !== -1) slidePath = parentPath; + } + if (idx !== -1) { const slide = slides.all[idx]; if (slide.loaded || slide.loading) return; - slides.setLoading(path, true); + slides.setLoading(slidePath, true); } try { - const response = await fetch(`${path}.json`); + // Fetch the actual slide path (parent), not the sub-page + const response = await fetch(`${slidePath}.json`); if (!response.ok) throw new Error(`HTTP ${response.status}`); const data = await response.json(); @@ -28,10 +51,10 @@ async function loadSlide(path) { siteInitialized = true; } - slides.setData(path, data); + slides.setData(slidePath, data); } catch (error) { - console.error(`[router] Failed to load slide ${path}:`, error); - slides.setLoading(path, false); + console.error(`[router] Failed to load slide ${slidePath}:`, error); + slides.setLoading(slidePath, false); } } @@ -48,15 +71,17 @@ export function slideTo(path, { skipHistory = false } = {}) { history.pushState({}, "", path === "/home" ? "/" : path); } - const idx = slides.getIndexByPath(path); + const idx = findSlideIndex(path); + const slidePath = idx !== -1 ? slides.all[idx].path : path; + if (idx !== -1 && slides.all[idx].title) { document.title = `${slides.all[idx].title} — World Game`; } - slides.slideTo(path); + slides.slideTo(slidePath); if (idx !== -1 && !slides.all[idx].loaded) { - loadSlide(path); + loadSlide(slidePath); } } @@ -65,12 +90,14 @@ export async function initRouter() { await loadSlide(initialPath); - const idx = slides.getIndexByPath(initialPath); + const idx = findSlideIndex(initialPath); if (idx !== -1) { slides.setActiveIndex(idx); } - loadAllSlidesInBackground(initialPath); + loadAllSlidesInBackground( + idx !== -1 ? slides.all[idx].path : initialPath + ); window.addEventListener("popstate", () => { const path = normalizePath(window.location.pathname); diff --git a/src/views/Article.svelte b/src/views/Article.svelte index 7e356f7..46cdc8d 100644 --- a/src/views/Article.svelte +++ b/src/views/Article.svelte @@ -1,24 +1,262 @@ -
Article view - To be implemented
+{featured.intro}
+ {#if featured} +Chargement…
+ {/if} + +