Refactor: snake_case → camelCase dans blueprints, templates et vues

- Blueprints : renommage des champs (member_name, related_articles,
  background_video, play_links, images_gallery, external_links) et
  des noms de sections
- Templates JSON PHP : clés de sortie et appels ->method() en camelCase
- Vues Svelte (Play, Portfolio) : accès aux données alignés

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-03-09 13:40:33 +01:00
parent d8a0fde34c
commit 69859cc60f
19 changed files with 63 additions and 76 deletions

View file

@ -2,7 +2,7 @@ title: Membre de l'équipe
accept: image/*
fields:
member_name:
memberName:
label: Nom
type: text
required: true

View file

@ -78,5 +78,5 @@ tabs:
ratio: 3/5
cover: true
back: '#0e1e43'
text: "{{ file.member_name }}"
text: "{{ file.memberName }}"
info: "{{ file.role }}"

View file

@ -105,7 +105,7 @@ tabs:
related:
type: fields
fields:
related_articles:
relatedArticles:
label: Articles recommandés
type: pages
query: site.find('blog').children.listed

View file

@ -43,7 +43,7 @@ tabs:
cover: true
ratio: 16/9
info: "{{ page.date.toDate('d/m/Y') }}"
articles_list:
articlesList:
label: Articles
type: pages
headline: Liste des articles

View file

@ -67,20 +67,7 @@ columns:
uploads:
template: image
help: Petite image carrée représentant le jeu
background_image:
label: Image d'arrière plan
type: files
layout: cards
max: 1
accept: image/*
translate: false
image:
ratio: 16/9
cover: true
uploads:
template: image
help: Image affichée en arrière-plan quand le jeu est sélectionné
play_links:
playLinks:
label: Lien(s) pour jouer
help: Sans lien renseigner, le jeu aura une étiquette "coming soon" et ne sera pas jouable.
type: structure

View file

@ -15,7 +15,7 @@ tabs:
columns:
- width: 2/3
sections:
hero_content:
heroContent:
type: fields
fields:
subtitle:
@ -40,7 +40,7 @@ tabs:
media:
type: fields
fields:
background_video:
backgroundVideo:
label: Vidéo d'arrière-plan
type: files
layout: cards

View file

@ -12,7 +12,7 @@ tabs:
label: Jeux
icon: grid
sections:
games_list:
gamesList:
type: pages
headline: Liste des jeux
layout: cards
@ -21,5 +21,5 @@ tabs:
query: page.thumbnail.toFile
cover: true
template: game
info: "{{ page.status_label }}"
info: "{{ page.statusLabel }}"
create: game

View file

@ -14,7 +14,7 @@ tabs:
columns:
- width: 1/3
sections:
meta_fields:
metaFields:
type: fields
fields:
backgroundImage:
@ -30,7 +30,7 @@ tabs:
ratio: 15/9
- width: 2/3
sections:
projects_list:
projectsList:
type: pages
headline: Liste des projets
layout: cards

View file

@ -52,7 +52,7 @@ columns:
images:
type: fields
fields:
images_gallery:
imagesGallery:
width: 2/3
label: Galerie d'image
type: files
@ -123,7 +123,7 @@ columns:
links:
type: fields
fields:
external_links:
externalLinks:
label: Liens externes
type: structure
fields:

View file

@ -2,20 +2,20 @@
$specificData = [
'intro' => [
'title' => $page->intro_title()->value(),
'text' => $page->intro_text()->value()
'title' => $page->introTitle()->value(),
'text' => $page->introText()->value()
],
'mission' => [
'title' => $page->mission_title()->value(),
'text' => $page->mission_text()->toBlocks()
'title' => $page->missionTitle()->value(),
'text' => $page->missionText()->toBlocks()
],
'manifesto' => [
'title' => $page->manifesto_title()->value(),
'text' => $page->manifesto_text()->toBlocks()
'title' => $page->manifestoTitle()->value(),
'text' => $page->manifestoText()->toBlocks()
],
'team' => [
'title' => $page->team_title()->value(),
'members' => $page->team_members()->toStructure()->map(function($member) {
'title' => $page->teamTitle()->value(),
'members' => $page->teamMembers()->toStructure()->map(function($member) {
return [
'name' => $member->name()->value(),
'role' => $member->role()->value(),

View file

@ -1,21 +1,21 @@
<?php
$related = $page->related_articles()->toPages();
$related = $page->relatedArticles()->toPages();
if ($related->isEmpty()) {
$related = $page->siblings()->listed()->not($page)->shuffle()->limit(3);
}
$specificData = [
'date' => $page->date()->toDate('Y-m-d'),
'date_formatted' => $page->date()->toDate('d/m/Y'),
'dateFormatted' => $page->date()->toDate('d/m/Y'),
'intro' => $page->intro()->value(),
'author' => [
'name' => $page->author_name()->value(),
'role' => $page->author_role()->value(),
'photo' => $page->author_photo()->toFile()?->url()
'name' => $page->authorName()->value(),
'role' => $page->authorRole()->value(),
'photo' => $page->authorPhoto()->toFile()?->url()
],
'cover' => $page->cover()->toFile()?->url(),
'content' => $page->article_content()->toBlocks(),
'content' => $page->articleContent()->toBlocks(),
'tags' => $page->tags()->split(),
'related' => $related->map(function($rec) {
return [
@ -25,7 +25,7 @@ $specificData = [
'cover' => $rec->cover()->toFile()?->thumb(['width' => 400])->url()
];
})->values(),
'parent_url' => $page->parent()->url()
'parentUrl' => $page->parent()->url()
];
$pageData = array_merge($genericData, $specificData);

View file

@ -2,8 +2,8 @@
$specificData = [
'intro' => [
'title' => $page->intro_title()->value(),
'text' => $page->intro_text()->value()
'title' => $page->introTitle()->value(),
'text' => $page->introText()->value()
],
'articles' => $page->children()->listed()->sortBy('date', 'desc')->map(function($article) {
return [
@ -11,11 +11,11 @@ $specificData = [
'slug' => $article->slug(),
'url' => $article->url(),
'date' => $article->date()->toDate('Y-m-d'),
'date_formatted' => $article->date()->toDate('d/m/Y'),
'dateFormatted' => $article->date()->toDate('d/m/Y'),
'intro' => $article->intro()->excerpt(200),
'cover' => $article->cover()->toFile()?->url(),
'author_name' => $article->author_name()->value(),
'author_photo' => $article->author_photo()->toFile()?->url()
'authorName' => $article->authorName()->value(),
'authorPhoto' => $article->authorPhoto()->toFile()?->url()
];
})->values()
];

View file

@ -3,11 +3,11 @@
$specificData = [
'description' => $page->description()->value(),
'rules' => $page->rules()->toBlocks(),
'game_status' => $page->game_status()->value(),
'is_embedded' => $page->is_embedded()->toBool(),
'play_link' => $page->play_link()->value(),
'gameStatus' => $page->gameStatus()->value(),
'isEmbedded' => $page->isEmbedded()->toBool(),
'playLink' => $page->playLink()->value(),
'cover' => $page->cover()->toFile()?->url(),
'parent_url' => $page->parent()->url()
'parentUrl' => $page->parent()->url()
];
$pageData = array_merge($genericData, $specificData);

View file

@ -2,15 +2,15 @@
$specificData = [
'hero' => [
'title' => $page->hero_title()->value(),
'title_highlight' => $page->hero_title_highlight()->value(),
'subtitle' => $page->hero_subtitle()->value(),
'title' => $page->heroTitle()->value(),
'titleHighlight' => $page->heroTitleHighlight()->value(),
'subtitle' => $page->heroSubtitle()->value(),
'ctaText' => $page->ctaText()->value(),
'ctaPath' => $page->ctaLink()->toPage()?->id() ?? '#',
'image' => $page->hero_image()->toFile()?->url()
'image' => $page->heroImage()->toFile()?->url()
],
'background_video' => $page->background_video()->toFile()?->url(),
'floating_bubbles' => $page->floating_bubbles()->toStructure()->map(function($bubble) {
'backgroundVideo' => $page->backgroundVideo()->toFile()?->url(),
'floatingBubbles' => $page->floatingBubbles()->toStructure()->map(function($bubble) {
return [
'text' => $bubble->text()->value(),
'position' => $bubble->position()->value()

View file

@ -8,8 +8,8 @@ $specificData = [
'lettering' => $game->lettering()->toFile()?->url(),
'description' => $game->description()->value(),
'thumbnail' => $game->thumbnail()->toFile()?->url(),
'background_image' => $game->background_image()->toFile()?->url(),
'play_links' => $game->play_links()->toStructure()->map(fn($l) => [
'backgroundImage' => $game->backgroundImage()->toFile()?->url(),
'playLinks' => $game->playLinks()->toStructure()->map(fn($l) => [
'label' => $l->label()->value(),
'url' => $l->url()->value(),
])->values(),

View file

@ -1,26 +1,26 @@
<?php
$specificData = [
'background_image' => $page->backgroundImage()->toFile()?->url(),
'backgroundImage' => $page->backgroundImage()->toFile()?->url(),
'projects' => $page->children()->listed()->map(function($project) {
return [
'title' => $project->title()->value(),
'slug' => $project->slug(),
'catchphrase' => $project->catchphrase()->value(),
'catchPhrase' => $project->catchPhrase()->value(),
'description' => $project->description()->value(),
'thumbnail' => $project->thumbnail()->toFile()?->url(),
'images_gallery' => $project->images_gallery()->toFiles()->map(fn($f) => [
'imagesGallery' => $project->imagesGallery()->toFiles()->map(fn($f) => [
'src' => $f->url(),
'srcset' => $f->srcset('gallery'),
'webp' => $f->srcset('gallery-webp'),
])->values(),
'mockup' => $project->mockup()->toFile()?->url(),
'gallery_background_color' => $project->galleryBackgroundColor()->value(),
'galleryBackgroundColor' => $project->galleryBackgroundColor()->value(),
'keywords' => $project->keywords()->toStructure()->map(fn($i) => [
'label' => $i->label()->value(),
'text' => $i->text()->value(),
])->values(),
'external_links' => $project->external_links()->toStructure()->map(fn($i) => [
'externalLinks' => $project->externalLinks()->toStructure()->map(fn($i) => [
'label' => $i->label()->value(),
'url' => $i->url()->value(),
])->values(),

View file

@ -10,10 +10,10 @@ $specificData = [
'impact' => $page->impact()->split(','),
'category' => $page->category()->value(),
'platforms' => $page->platforms()->split(','),
'client_name' => $page->client_name()->value(),
'apple_link' => $page->apple_link()->value(),
'android_link' => $page->android_link()->value(),
'web_link' => $page->web_link()->value(),
'clientName' => $page->clientName()->value(),
'appleLink' => $page->appleLink()->value(),
'androidLink' => $page->androidLink()->value(),
'webLink' => $page->webLink()->value(),
'prev' => $page->prev() ? [
'title' => $page->prev()->title()->value(),
'url' => $page->prev()->url()
@ -22,7 +22,7 @@ $specificData = [
'title' => $page->next()->title()->value(),
'url' => $page->next()->url()
] : null,
'parent_url' => $page->parent()->url()
'parentUrl' => $page->parent()->url()
];
$pageData = array_merge($genericData, $specificData);

View file

@ -65,8 +65,8 @@
<!-- Fond : image + overlay, crossfade au changement de jeu -->
<div class="play-bg" class:is-out={isOut} aria-hidden="true">
{#if displayedGame?.background_image}
<img class="play-bg-img" src={displayedGame.background_image} alt="" />
{#if displayedGame?.backgroundImage}
<img class="play-bg-img" src={displayedGame.backgroundImage} alt="" />
{/if}
<div class="play-bg-overlay"></div>
</div>
@ -99,8 +99,8 @@
{/if}
<div class="play-actions">
{#if displayedGame.play_links?.length}
{#each displayedGame.play_links as link}
{#if displayedGame.playLinks?.length}
{#each displayedGame.playLinks as link}
<a
href={link.url}
target="_blank"

View file

@ -13,7 +13,7 @@
// --- Derived ---
const isActive = $derived(slides.active?.id === 'portfolio')
const projects = $derived(data?.projects ?? [])
const backgroundImage = $derived(data?.background_image ?? null)
const backgroundImage = $derived(data?.backgroundImage ?? null)
const currentProject = $derived(projects[currentIndex] ?? null)
// Capture du hash synchrone avant que tout effect puisse le modifier
@ -96,7 +96,7 @@
{#if currentProject}
<!-- Galerie animation (gauche) -->
<div class="portfolio-gallery" aria-hidden="true">
<GalleryAnimation images={currentProject.images_gallery} backgroundColor={currentProject.gallery_background_color} />
<GalleryAnimation images={currentProject.imagesGallery} backgroundColor={currentProject.galleryBackgroundColor} />
</div>
<!-- Mockup device (centre) -->
@ -107,7 +107,7 @@
<!-- Infos projet (droite) -->
<div class="portfolio-text" aria-live="polite">
<h2>{currentProject.title}</h2>
<h3 class="portfolio-catchphrase gradient-blue">{@html currentProject.catchphrase}</h3>
<h3 class="portfolio-catchphrase gradient-blue">{@html currentProject.catchPhrase}</h3>
<div class="portfolio-description">{@html currentProject.description}</div>
<div class="portfolio-keywords">
{#each currentProject.keywords as kw}
@ -115,7 +115,7 @@
{/each}
</div>
<div class="portfolio-links">
{#each currentProject.external_links as link}
{#each currentProject.externalLinks as link}
<a href={link.url} target="_blank" rel="noopener noreferrer" class="button earth-icon">{link.label}</a>
{/each}
</div>