Implémentation complète du multilingue FR/EN

- Installation vue-i18n v11 et création des fichiers de traduction (fr.json, en.json)
- Création store locale avec détection hiérarchique (URL > localStorage > navigator)
- Modification des routes avec préfixe /:locale? optionnel
- Toggle FR/EN dans Menu.vue avec synchronisation immédiate
- Traduction de ~200 textes dans 27 composants Vue
- Suppression des labels hardcodés en français côté backend
- Ajout route Kirby catch-all en/(:all?) pour /en/ URLs
- Helper addLocalePrefix() pour préserver locale dans liens dialogs
- Traduction pseudo-élément CSS via data attribute

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-02-02 18:21:11 +01:00
parent 3af95b1d20
commit 82eb8d88cc
49 changed files with 1079 additions and 295 deletions

View file

@ -28,6 +28,7 @@ return [
'install' => 'true'
],
'routes' => [
require(__DIR__ . '/routes/en-locale.php'),
require(__DIR__ . '/routes/logout.php'),
require(__DIR__ . '/routes/login.php'),
require(__DIR__ . '/routes/toggle-favorite.php'),

View file

@ -0,0 +1,44 @@
<?php
/**
* Route catch-all pour le préfixe /en/
* Permet d'accéder aux pages avec /en/... pour la version anglaise
*/
return [
'pattern' => 'en/(:all?)',
'action' => function ($uri = '') {
// Si l'URI se termine par .json, chercher la page et retourner le JSON
if (str_ends_with($uri, '.json')) {
$uri = str_replace('.json', '', $uri);
$page = page($uri);
if (!$page) {
// Si pas de page trouvée, essayer avec 'home'
if ($uri === '' || $uri === '/') {
$page = page('home');
} else {
return false; // 404
}
}
// Retourner la page pour que Kirby serve le template .json.php
return $page;
}
// Pour les URLs normales (sans .json), chercher la page
$page = page($uri);
if (!$page) {
// Si pas de page trouvée, essayer avec 'home'
if ($uri === '' || $uri === '/') {
$page = page('home');
} else {
return false; // 404
}
}
// Retourner la page pour que Kirby serve le template .php
return $page;
}
];

View file

@ -32,7 +32,7 @@ return function ($page, $kirby, $site) {
return [
"title" => (string) $project->title(),
"uri" => (string) $project->uri(),
"step" => (string) $project->getStepLabel(),
"step" => (string) $project->currentStep(),
"uuid" => (string) $project->uuid(),
];
})->data;

View file

@ -99,7 +99,6 @@ class ProjectPage extends NotificationsPage {
}
return [
'label' => $child->title()->value(),
'id' => $child->stepName()->value(),
'slug' => $child->slug(),
'index' => intval($child->stepIndex()->value()),
@ -217,18 +216,6 @@ class ProjectPage extends NotificationsPage {
}
}
public function getStepLabel() {
$stepsLabel = [
"clientBrief" => "brief",
"proposal" => "offre commerciale",
"extendedBrief" => "brief enrichi",
"industrialIdeation" => "idéation industrielle",
"virtualSample" => "échantillon virtuel",
"physicalSample" => "échantillon physique",
];
return $stepsLabel[$this->currentStep()->value()];
}
// public function printManagers() {
// return A::implode($this->managers()->toUsers()->pluck('name'), ', ');

View file

@ -94,7 +94,6 @@ function processDTLProposals($page) {
],
"path" => "/projects/" . $page->slug() . "?dialog=proposal&fileIndex=" . $index,
"date" => $proposalFile->modified("d/MM/Y"),
"stepLabel" => "Proposition commerciale",
];
}
break;
@ -112,7 +111,6 @@ function processDTLProposals($page) {
],
"path" => "/projects/" . $page->slug() . "?dialog=industrial-ideation",
"date" => $proposalFile->modified("d/MM/Y"),
"stepLabel" => "Idéation industrielle",
];
}
break;
@ -129,7 +127,6 @@ function processDTLProposals($page) {
],
"path" => "/projects/" . $page->slug() . "?dialog=virtual-sample",
"date" => $proposalPage->modified("d/MM/Y"),
"stepLabel" => "Échantillon virtuel - piste dynamique",
];
}
break;
@ -147,7 +144,6 @@ function processDTLProposals($page) {
],
"path" => "/projects/" . $page->slug() . "?dialog=virtual-sample",
"date" => $proposalFile->modified("d/MM/Y"),
"stepLabel" => "Échantillon virtuel - piste statique",
];
}
break;