From 8a3de6adaa0c1b8a90b3f30c9508cded50f091b2 Mon Sep 17 00:00:00 2001 From: vincent Date: Mon, 7 Jul 2025 23:27:21 +0200 Subject: [PATCH] Introduit l'i18n et la l10n fr/en --- README.md | 9 ++++++++ composer.json | 1 + composer.lock | 26 +++++++++++----------- config/packages/translation.yaml | 4 ++-- src/Controller/BadgeController.php | 13 ++++++++--- src/Controller/HomeController.php | 19 +++++++++++++--- src/EventSubscriber/LocaleSubscriber.php | 38 ++++++++++++++++++++++++++++++++ templates/_header.html.twig | 7 ++++++ templates/home/index.html.twig | 4 ++-- translations/messages.en.yaml | 13 +++++++++++ translations/messages.fr.yaml | 13 +++++++++++ 11 files changed, 124 insertions(+), 23 deletions(-) create mode 100644 src/EventSubscriber/LocaleSubscriber.php create mode 100644 translations/messages.en.yaml create mode 100644 translations/messages.fr.yaml diff --git a/README.md b/README.md index 8b767f6..2b7d3bf 100644 --- a/README.md +++ b/README.md @@ -71,4 +71,13 @@ les variables : l’adresse web de son instance suffixée du chemin `/osm/callback` et comme autorisation, uniquement « Lire les préférences de l’utilisateur ») +# TODO + +* API pour interactions automatisées +* nouveaux outils : + - découpage d'une zone géographique en carrés d'une surface donnée + - depuis un gros GeoJSON faire autant de tâches que de *features* + - faire autant de tâches que d'éléments Osmose d'un certain type sur une emprise donnée + - pouvoir fédérer plusieurs instances (avec de l'ActivityPub ?) + diff --git a/composer.json b/composer.json index decbab2..0f7072e 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,7 @@ "symfony/runtime": "7.3.*", "symfony/security-bundle": "7.3.*", "symfony/stimulus-bundle": "^2.18", + "symfony/translation": "7.3.*", "symfony/twig-bundle": "7.3.*", "symfony/validator": "7.3.*", "symfony/workflow": "7.3.*", diff --git a/composer.lock b/composer.lock index 7da25e1..758d681 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a2a5c548491ca262277ef9a55c872ad1", + "content-hash": "d035db9a327bfae49b87a5a0e08c5198", "packages": [ { "name": "behat/transliterator", @@ -4642,16 +4642,16 @@ }, { "name": "symfony/flex", - "version": "v2.8.0", + "version": "v2.8.1", "source": { "type": "git", "url": "https://github.com/symfony/flex.git", - "reference": "68cdcde0b7e36b008a08bcf3709c07a20e757a29" + "reference": "423c36e369361003dc31ef11c5f15fb589e52c01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/flex/zipball/68cdcde0b7e36b008a08bcf3709c07a20e757a29", - "reference": "68cdcde0b7e36b008a08bcf3709c07a20e757a29", + "url": "https://api.github.com/repos/symfony/flex/zipball/423c36e369361003dc31ef11c5f15fb589e52c01", + "reference": "423c36e369361003dc31ef11c5f15fb589e52c01", "shasum": "" }, "require": { @@ -4690,7 +4690,7 @@ "description": "Composer plugin for Symfony", "support": { "issues": "https://github.com/symfony/flex/issues", - "source": "https://github.com/symfony/flex/tree/v2.8.0" + "source": "https://github.com/symfony/flex/tree/v2.8.1" }, "funding": [ { @@ -4706,7 +4706,7 @@ "type": "tidelift" } ], - "time": "2025-07-04T06:30:46+00:00" + "time": "2025-07-05T07:45:19+00:00" }, { "name": "symfony/form", @@ -8974,16 +8974,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.76.0", + "version": "v3.81.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "0e3c484cef0ae9314b0f85986a36296087432c40" + "reference": "e00a39c729aced6c3771b9530c6e58c2efa87592" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/0e3c484cef0ae9314b0f85986a36296087432c40", - "reference": "0e3c484cef0ae9314b0f85986a36296087432c40", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/e00a39c729aced6c3771b9530c6e58c2efa87592", + "reference": "e00a39c729aced6c3771b9530c6e58c2efa87592", "shasum": "" }, "require": { @@ -9067,7 +9067,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.76.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.81.0" }, "funding": [ { @@ -9075,7 +9075,7 @@ "type": "github" } ], - "time": "2025-06-30T14:15:06+00:00" + "time": "2025-07-07T15:27:54+00:00" }, { "name": "nikic/php-parser", diff --git a/config/packages/translation.yaml b/config/packages/translation.yaml index b3f8f9c..adc599e 100644 --- a/config/packages/translation.yaml +++ b/config/packages/translation.yaml @@ -1,7 +1,7 @@ framework: - default_locale: en + default_locale: fr translator: default_path: '%kernel.project_dir%/translations' fallbacks: - - en + - fr providers: diff --git a/src/Controller/BadgeController.php b/src/Controller/BadgeController.php index 4fa83fc..6f4c03e 100644 --- a/src/Controller/BadgeController.php +++ b/src/Controller/BadgeController.php @@ -10,21 +10,28 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Attribute\Route; +use Symfony\Contracts\Translation\TranslatorInterface; #[Route('/badge')] class BadgeController extends AbstractController { #[Route('/project-status/{projectSlug}/{status}', name: 'app_badge_project_status')] - public function index(EntityManagerInterface $entityManager, TaskLifecycleManager $taskLifecycleManager, string $projectSlug, string $status): Response + public function index( + EntityManagerInterface $entityManager, + TaskLifecycleManager $taskLifecycleManager, + TranslatorInterface $translator, + string $projectSlug, + string $status + ): Response { $project = $entityManager->getRepository(Project::class)->findOneBySlug($projectSlug); if (!$project) { - throw new NotFoundHttpException('Project not found'); + throw new NotFoundHttpException($translator->trans('exception.project_not_found')); } $stats = $taskLifecycleManager->getProjectStats($project); if (empty($stats) || !isset($stats[$status])) { - throw new NotFoundHttpException('Status not found'); + throw new NotFoundHttpException($translator->trans('exception.status_not_found')); } $stats = $stats[$status]; diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php index 1d04bea..fba2103 100644 --- a/src/Controller/HomeController.php +++ b/src/Controller/HomeController.php @@ -10,6 +10,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; +use Symfony\Contracts\Translation\TranslatorInterface; class HomeController extends AbstractController { @@ -24,6 +25,18 @@ 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); + + if ($request->headers->has('Referer')) { + return $this->redirect($request->headers->get('Referer')); + } else { + return $this->redirect('app_home'); + } + } + // Page d’erreur public function error(Request $request, $exception, $logger = null): Response { @@ -57,17 +70,17 @@ class HomeController extends AbstractController // L’oauth OSM aboutit ici #[Route('/osm/callback', name: 'app_osm_callback')] - public function osmCallback(Request $request, ClientRegistry $clientRegistry): Response + public function osmCallback(Request $request, ClientRegistry $clientRegistry, TranslatorInterface $translator): Response { $client = $clientRegistry->getClient('openstreetmap'); if ($request->query->has('error')) { $this->addFlash('danger', sprintf( - 'Échec de l’authentification (%s)', + $translator->trans('alert.auth_failure').' (%s)', $request->query->has('error_description') ? $request->query->get('error_description') : $request->query->get('error') )); } else { - $this->addFlash('success', 'Authentification OSM réussie !'); + $this->addFlash('success', $translator->trans('alert.auth_success')); } $session = $request->getSession(); diff --git a/src/EventSubscriber/LocaleSubscriber.php b/src/EventSubscriber/LocaleSubscriber.php new file mode 100644 index 0000000..0201302 --- /dev/null +++ b/src/EventSubscriber/LocaleSubscriber.php @@ -0,0 +1,38 @@ +getRequest(); + if (!$request->hasPreviousSession()) { + return; + } + + // try to see if the locale has been set as a _locale routing parameter + if ($locale = $request->attributes->get('_locale')) { + $request->getSession()->set('_locale', $locale); + } else { + // if no explicit locale has been set on this request, use one from the session + $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale)); + } + } + + public static function getSubscribedEvents(): array + { + return [ + // must be registered before (i.e. with a higher priority than) the default Locale listener + KernelEvents::REQUEST => [['onKernelRequest', 20]], + ]; + } +} diff --git a/templates/_header.html.twig b/templates/_header.html.twig index 324c429..204d029 100644 --- a/templates/_header.html.twig +++ b/templates/_header.html.twig @@ -55,5 +55,12 @@ +
+
+ {% for locale in ['fr', 'en'] %} + {{ locale }} + {% endfor %} +
+
diff --git a/templates/home/index.html.twig b/templates/home/index.html.twig index d655b56..9a42953 100644 --- a/templates/home/index.html.twig +++ b/templates/home/index.html.twig @@ -4,7 +4,7 @@

{{ long_title }}

-

Gère les tâches, même avec des nœuds (ou pas).

+

{{ 'text.home1'|trans }}

L’idée c’est d’avoir un petit outil collaboratif simple et facile à administrer/utiliser pour mapper des trucs de façon coordonnée à un endroit.

Si d’aventure vous souhaitez contacter le développeur, merci d’écrire à v+osm@caboulot.org

@@ -17,7 +17,7 @@
-

Projets populaires

+

{{ 'title.popular_projects'|trans }}

diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml new file mode 100644 index 0000000..b4572b4 --- /dev/null +++ b/translations/messages.en.yaml @@ -0,0 +1,13 @@ +exception: + project_not_found: 'Project not found' + status_not_found: 'Status not found' + +alert: + auth_failure: 'Authentification failed' + auth_success: 'Authentification successfull !' + +title: + popular_projects: 'Popular projects' + +text: + home1: 'Handle tasks, even with nodes (or not).' diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml new file mode 100644 index 0000000..0cab1be --- /dev/null +++ b/translations/messages.fr.yaml @@ -0,0 +1,13 @@ +exception: + project_not_found: 'Projet introuvable' + status_not_found: 'État introuvable' + +alert: + auth_failure: 'Échec de l’authentification' + auth_success: 'Authentification OSM réussie !' + +title: + popular_projects: 'Projets populaires' + +text: + home1: 'Gère les tâches, même avec des nœuds (ou pas).'