From 829c8e738839dedf36cee9677b84c076b61001eb Mon Sep 17 00:00:00 2001 From: vincent Date: Tue, 8 Jul 2025 16:57:44 +0200 Subject: [PATCH] wip i18n l10n --- composer.json | 7 +++ config/packages/twig.yaml | 29 +++++++--- config/packages/workflow.yaml | 22 ++++---- config/services.yaml | 6 +- src/Controller/BadgeController.php | 21 +++---- src/Controller/HomeController.php | 6 +- src/EventSubscriber/LocaleSubscriber.php | 1 + src/Repository/ProjectRepository.php | 8 +-- src/Service/VersionGetter.php | 13 +++-- templates/_header.html.twig | 14 ++--- templates/base.html.twig | 4 +- templates/comment/start.md.twig | 6 +- templates/home/index.html.twig | 10 ++-- templates/macro.html.twig | 30 +++++----- templates/partials/_comment-metadata.html.twig | 2 +- .../partials/_overpass-element-popup.html.twig | 10 ++-- templates/partials/_project-metadata.html.twig | 2 +- templates/partials/_task-locking.html.twig | 2 +- templates/partials/_task-metadata.html.twig | 2 +- translations/messages.en.yaml | 63 ++++++++++++++++++--- translations/messages.fr.yaml | 65 +++++++++++++++++++--- 21 files changed, 224 insertions(+), 99 deletions(-) diff --git a/composer.json b/composer.json index 0f7072e..fdc81d9 100644 --- a/composer.json +++ b/composer.json @@ -92,6 +92,13 @@ ], "post-update-cmd": [ "@auto-scripts" + ], + "update-translations": [ + "bin/console translation:extract --force --format=yaml --as-tree=3 --domain messages fr", + "bin/console translation:extract --force --format=yaml --as-tree=3 --domain messages en" + ], + "php-cs-fixer": [ + "./vendor/bin/php-cs-fixer fix src" ] }, "conflict": { diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index ec3ea3c..f8233c3 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -2,24 +2,39 @@ twig: file_name_pattern: '*.twig' form_themes: ['bootstrap_5_layout.html.twig'] globals: - title: '%short_title%' + locales: ['fr', 'en'] + title: + fr: '%short_title_fr%' + en: '%short_title_en%' menu: header: - route: 'app_project' - label: 'Projets' + label: + fr: 'Projets' + en: 'Projects' icon: '' - route: 'app_tools' - label: 'Outils' + label: + fr: 'Outils' + en: 'Tools' icon: '' taskLifecycleManager: '@App\Service\TaskLifecycleManager' geoJsonManager: '@App\Service\GeoJsonManager' sourceGenerator: '@App\Service\SourceGenerator' - short_title: '%short_title%' - long_title: '%long_title%' + short_title: + fr: '%short_title_fr%' + en: '%short_title_en%' + long_title: + fr: '%long_title_fr%' + en: '%long_title_en%' tools: - - label: 'Communes' + - label: + fr: 'Communes' + en: 'Cities' route: 'app_tools_city' - - label: 'Osmose' + - label: + fr: 'Osmose' + en: 'Osmose' route: 'app_tools_osmose' versionGetter: '@App\Service\VersionGetter' diff --git a/config/packages/workflow.yaml b/config/packages/workflow.yaml index 39cf70e..7eed4a7 100644 --- a/config/packages/workflow.yaml +++ b/config/packages/workflow.yaml @@ -13,17 +13,17 @@ framework: places: !php/const App\Entity\Task::STATUS_TODO: metadata: - title: 'À faire' + title: 'workflow.place.todo' # À faire' color: danger locking: false !php/const App\Entity\Task::STATUS_DOING: metadata: - title: 'En cours' + title: 'workflow.place.doing' # En cours' color: warning locking: true !php/const App\Entity\Task::STATUS_DONE: metadata: - title: 'Terminé' + title: 'workflow.place.done' # Terminé' color: success locking: false transitions: @@ -31,8 +31,8 @@ framework: from: !php/const App\Entity\Task::STATUS_TODO to: !php/const App\Entity\Task::STATUS_DOING metadata: - title: 'Commencer la tâche' - short: 'Commencer' + title: 'workflow.transition.start_task' # 'Commencer la tâche' + short: 'workflow.transition.start' # 'Commencer' accesskey: 'S' route: 'app_task_start' lock: true @@ -41,8 +41,8 @@ framework: from: !php/const App\Entity\Task::STATUS_DOING to: !php/const App\Entity\Task::STATUS_DONE metadata: - title: 'Terminer la tâche' - short: 'Terminer' + title: 'workflow.transition.finish_task' # 'Terminer la tâche' + short: 'workflow.transition.finish' # 'Terminer' accesskey: 'F' route: 'app_task_finish' lock: false @@ -51,8 +51,8 @@ framework: from: !php/const App\Entity\Task::STATUS_DOING to: !php/const App\Entity\Task::STATUS_TODO metadata: - title: 'Abandonner la tâche' - short: 'Abandonner' + title: 'workflow.transition.cancel_task' # 'Abandonner la tâche' + short: 'workflow.transition.cancel' #'Abandonner' accesskey: 'S' route: 'app_task_cancel' lock: false @@ -61,8 +61,8 @@ framework: from: !php/const App\Entity\Task::STATUS_DONE to: !php/const App\Entity\Task::STATUS_TODO metadata: - title: 'Recommencer la tâche' - short: 'Recommencer' + title: 'workflow.transition.reset_task' #'Recommencer la tâche' + short: 'workflow.transition.reset' #'Recommencer' accesskey: 'S' route: 'app_task_reset' lock: false diff --git a/config/services.yaml b/config/services.yaml index 81f8d9d..e5c0017 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -5,8 +5,10 @@ # https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration parameters: timezone: '%env(APP_TIMEZONE)%' - short_title: 'OMO' - long_title: 'Outil de Manipulation et d’Organisation' + short_title_fr: 'OMO' + short_title_en: 'OMG' + long_title_fr: 'Outil de Manipulation et d’Organisation' + long_title_en: 'Organizing and Managing thinGs' services: # default configuration for services in *this* file diff --git a/src/Controller/BadgeController.php b/src/Controller/BadgeController.php index 6f4c03e..79c253c 100644 --- a/src/Controller/BadgeController.php +++ b/src/Controller/BadgeController.php @@ -6,6 +6,7 @@ use App\Entity\Project; use App\Service\TaskLifecycleManager; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -16,14 +17,14 @@ use Symfony\Contracts\Translation\TranslatorInterface; class BadgeController extends AbstractController { #[Route('/project-status/{projectSlug}/{status}', name: 'app_badge_project_status')] - public function index( - EntityManagerInterface $entityManager, - TaskLifecycleManager $taskLifecycleManager, - TranslatorInterface $translator, - string $projectSlug, - string $status - ): Response - { + public function index( + EntityManagerInterface $entityManager, + TaskLifecycleManager $taskLifecycleManager, + Request $request, + TranslatorInterface $translator, + string $projectSlug, + string $status, + ): Response { $project = $entityManager->getRepository(Project::class)->findOneBySlug($projectSlug); if (!$project) { throw new NotFoundHttpException($translator->trans('exception.project_not_found')); @@ -41,7 +42,7 @@ class BadgeController extends AbstractController $response->headers->set('Content-Type', 'image/svg+xml'); $response->headers->set('Cache-Control', 'public, max-age=300'); - $response->setCallback(function () use ($stats): void { + $response->setCallback(function () use ($stats, $translator, $request): void { $colors = [ 'primary' => '#0d6efd', // $blue; 'secondary' => '#6c757d', // $gray-600; @@ -53,7 +54,7 @@ class BadgeController extends AbstractController $xml = new \DOMDocument(); - $left = $stats['title']; + $left = $translator->trans($stats['title']).' ('.$request->getLocale().')'; $leftColor = $colors['secondary']; $right = sprintf(' % 3.0f%%', $stats['percentage']); $rightColor = $colors[$stats['color']]; diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php index fba2103..553fbd5 100644 --- a/src/Controller/HomeController.php +++ b/src/Controller/HomeController.php @@ -28,12 +28,12 @@ class HomeController extends AbstractController #[Route('/{locale}', name: 'app_locale', requirements: ['locale' => '(fr|en)'])] public function changeLocale(Request $request, $locale): Response { - $request->getSession()->set('_locale', $locale); + $request->getSession()->set('_locale', $locale); if ($request->headers->has('Referer')) { return $this->redirect($request->headers->get('Referer')); - } else { - return $this->redirect('app_home'); + } else { + return $this->redirectToRoute('app_home'); } } diff --git a/src/EventSubscriber/LocaleSubscriber.php b/src/EventSubscriber/LocaleSubscriber.php index 0201302..3f96555 100644 --- a/src/EventSubscriber/LocaleSubscriber.php +++ b/src/EventSubscriber/LocaleSubscriber.php @@ -1,4 +1,5 @@ getEntityManager(); - $query = $entityManager->createQuery(" + $query = $entityManager->createQuery(' SELECT p -FROM ".Project::class." p -JOIN ".Task::class." t +FROM '.Project::class.' p +JOIN '.Task::class.' t GROUP BY p.id ORDER BY MAX(t.finishAt) -") +') ->setMaxResults($limit); return $query->getResult(); diff --git a/src/Service/VersionGetter.php b/src/Service/VersionGetter.php index 8d8130c..c9c6038 100644 --- a/src/Service/VersionGetter.php +++ b/src/Service/VersionGetter.php @@ -2,17 +2,20 @@ namespace App\Service; -class VersionGetter { - - public function __construct(private $projectDir) {} +class VersionGetter +{ + public function __construct(private $projectDir) + { + } - public function getVersion($defaultVersion = null): ?string { + public function getVersion($defaultVersion = null): ?string + { try { $data = json_decode(file_get_contents($this->projectDir.'/composer.json'), true); + return isset($data['version']) ? $data['version'] : $defaultVersion; } catch (\Exception $exception) { return ''; } } - } diff --git a/templates/_header.html.twig b/templates/_header.html.twig index 204d029..141c4be 100644 --- a/templates/_header.html.twig +++ b/templates/_header.html.twig @@ -1,15 +1,15 @@