Browse Source

wip i18n l10n

master
vincent 1 day ago
parent
commit
829c8e7388
21 changed files with 224 additions and 99 deletions
  1. +7
    -0
      composer.json
  2. +22
    -7
      config/packages/twig.yaml
  3. +11
    -11
      config/packages/workflow.yaml
  4. +4
    -2
      config/services.yaml
  5. +11
    -10
      src/Controller/BadgeController.php
  6. +3
    -3
      src/Controller/HomeController.php
  7. +1
    -0
      src/EventSubscriber/LocaleSubscriber.php
  8. +4
    -4
      src/Repository/ProjectRepository.php
  9. +8
    -5
      src/Service/VersionGetter.php
  10. +7
    -7
      templates/_header.html.twig
  11. +2
    -2
      templates/base.html.twig
  12. +5
    -1
      templates/comment/start.md.twig
  13. +5
    -5
      templates/home/index.html.twig
  14. +15
    -15
      templates/macro.html.twig
  15. +1
    -1
      templates/partials/_comment-metadata.html.twig
  16. +5
    -5
      templates/partials/_overpass-element-popup.html.twig
  17. +1
    -1
      templates/partials/_project-metadata.html.twig
  18. +1
    -1
      templates/partials/_task-locking.html.twig
  19. +1
    -1
      templates/partials/_task-metadata.html.twig
  20. +54
    -9
      translations/messages.en.yaml
  21. +56
    -9
      translations/messages.fr.yaml

+ 7
- 0
composer.json View File

@ -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": {


+ 22
- 7
config/packages/twig.yaml View File

@ -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: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-folder" viewBox="0 0 16 16"><path d="M.54 3.87.5 3a2 2 0 0 1 2-2h3.672a2 2 0 0 1 1.414.586l.828.828A2 2 0 0 0 9.828 3h3.982a2 2 0 0 1 1.992 2.181l-.637 7A2 2 0 0 1 13.174 14H2.826a2 2 0 0 1-1.991-1.819l-.637-7a2 2 0 0 1 .342-1.31zM2.19 4a1 1 0 0 0-.996 1.09l.637 7a1 1 0 0 0 .995.91h10.348a1 1 0 0 0 .995-.91l.637-7A1 1 0 0 0 13.81 4zm4.69-1.707A1 1 0 0 0 6.172 2H2.5a1 1 0 0 0-1 .981l.006.139q.323-.119.684-.12h5.396z"/></svg>'
- route: 'app_tools'
label: 'Outils'
label:
fr: 'Outils'
en: 'Tools'
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-wrench" viewBox="0 0 16 16"><path d="M.102 2.223A3.004 3.004 0 0 0 3.78 5.897l6.341 6.252A3.003 3.003 0 0 0 13 16a3 3 0 1 0-.851-5.878L5.897 3.781A3.004 3.004 0 0 0 2.223.1l2.141 2.142L4 4l-1.757.364zm13.37 9.019.528.026.287.445.445.287.026.529L15 13l-.242.471-.026.529-.445.287-.287.445-.529.026L13 15l-.471-.242-.529-.026-.287-.445-.445-.287-.026-.529L11 13l.242-.471.026-.529.445-.287.287-.445.529-.026L13 11z"/></svg>'
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'


+ 11
- 11
config/packages/workflow.yaml View File

@ -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


+ 4
- 2
config/services.yaml View File

@ -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


+ 11
- 10
src/Controller/BadgeController.php View File

@ -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']];


+ 3
- 3
src/Controller/HomeController.php View File

@ -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');
}
}


+ 1
- 0
src/EventSubscriber/LocaleSubscriber.php View File

@ -1,4 +1,5 @@
<?php
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;


+ 4
- 4
src/Repository/ProjectRepository.php View File

@ -32,13 +32,13 @@ class ProjectRepository extends ServiceEntityRepository
public function findSomeOrderedByPopularity($limit = 3): array
{
$entityManager = $this->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();


+ 8
- 5
src/Service/VersionGetter.php View File

@ -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 '';
}
}
}

+ 7
- 7
templates/_header.html.twig View File

@ -1,15 +1,15 @@
<header>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="{{ path('app_home') }}" title="{{ long_title }} {{ versionGetter.getVersion() }}">{{ title }} </a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<a class="navbar-brand" href="{{ path('app_home') }}" title="{{ long_title[app.request.locale] }} {{ versionGetter.getVersion() }}">{{ title[app.request.locale] }} </a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="{{ 'button.toggle_navigation'|trans }}">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
{% for item in menu.header %}
<li class="nav-item">
<a {% if app.request.attributes.get('_route') == item.route %}class="nav-link active" aria-current="page"{% else %}class="nav-link"{% endif %} href="{{ path(item.route) }}">{{ item.icon|raw }} {{ item.label }}</a>
<a {% if app.request.attributes.get('_route') == item.route %}class="nav-link active" aria-current="page"{% else %}class="nav-link"{% endif %} href="{{ path(item.route) }}">{{ item.icon|raw }} {{ item.label[app.request.locale] }}</a>
</li>
{% endfor %}
{% if is_granted('IS_AUTHENTICATED_FULLY') %}
@ -38,8 +38,8 @@
{{ app.user.username }}
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{{ 'https://osm.org/user/' ~ app.user.username }}" target="_blank">Sur OSM</a></li>
<li><a class="dropdown-item" href="{{ path('app_osm_logout') }}">Déconnexion</a></li>
<li><a class="dropdown-item" href="{{ 'https://osm.org/user/' ~ app.user.username }}" target="_blank">{{ 'menu.on_osm'|trans }}</a></li>
<li><a class="dropdown-item" href="{{ path('app_osm_logout') }}">{{ 'menu.logout'|trans }}</a></li>
</ul>
</li>
{% else %}
@ -48,7 +48,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-person" viewBox="0 0 16 16">
<path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6m2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0m4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4m-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10s-3.516.68-4.168 1.332c-.678.678-.83 1.418-.832 1.664z"/>
</svg>
Connexion
{{ 'menu.login'|trans }}
</a>
</li>
{% endif %}
@ -57,7 +57,7 @@
</div>
<div class="d-flex">
<div class="btn-group me-3">
{% for locale in ['fr', 'en'] %}
{% for locale in locales %}
<a href="{{ path('app_locale', {'locale': locale}) }}" class="btn btn-light{% if app.request.locale == locale %} active{% endif %}">{{ locale }}</a>
{% endfor %}
</div>


+ 2
- 2
templates/base.html.twig View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{% block title %}{{ title }}{% endblock %}</title>
<title>{% block title %}{{ title[app.request.locale] }}{% endblock %}</title>
<link rel="icon" href="data:," />
{% block stylesheets %}
{% endblock %}
@ -36,7 +36,7 @@
{% for message in messages %}
<div class="alert alert-{{ label }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="{{ 'button.close'|trans }}"></button>
</div>
{% endfor %}
{% endfor %}


+ 5
- 1
templates/comment/start.md.twig View File

@ -1,2 +1,6 @@
{% import 'macro.html.twig' as macro %}
{{ macro.osmLinkTo(user.username) }} commence la tâche [{{ task.name }}]({{ path('app_task_show', {'slug': task.slug}) }})
{{ 'comment.start'|trans({
'%username%': macro.osmLinkTo(user.username),
'%task_name%': task.name }},
'%task_url%': path('app_task_show', {'slug': task.slug})
}) }}

+ 5
- 5
templates/home/index.html.twig View File

@ -2,13 +2,13 @@
{% block page_content %}
<div class="px-4 py-5 my-5 text-center">
<h1 class="display-5 fw-bold text-body-emphasis">{{ long_title }}</h1>
<h1 class="display-5 fw-bold text-body-emphasis">{{ long_title[app.request.locale] }}</h1>
<div class="col-lg-6 mx-auto">
<p class="lead mb-4">{{ 'text.home1'|trans }}</p>
<p class="lead mb-4">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.</p>
<p class="text-muted mb-4">Si d’aventure vous souhaitez contacter le développeur, merci d’écrire à <a href="mailto:v+osm@caboulot.org?subject={{ short_title }}">v+osm@caboulot.org</a></p>
<p class="lead mb-4">{{ 'text.home2'|trans }}</p>
<p class="text-muted mb-4">{{ 'text.home3'|trans({'%mailto_link%': '<a href="mailto:v+osm@caboulot.org?subject='~short_title[app.request.locale]~'">v+osm@caboulot.org</a>'})|raw }}</p>
<div class="d-grid gap-2 d-sm-flex justify-content-sm-center">
<a class="btn btn-primary btn-lg px-4 gap-3" href="{{ path('app_project') }}">Voir les projets</a>
<a class="btn btn-primary btn-lg px-4 gap-3" href="{{ path('app_project') }}">{{ 'button.goto_projects'|trans }}</a>
</div>
</div>
</div>
@ -33,7 +33,7 @@
</h3>
<p class="card-subtitle mb-2 text-muted">{% include 'partials/_project-metadata.html.twig' %}</p>
{% if project.description %}<p class="card-text">{{ project.description|markdown_to_html }}</p>{% endif %}
<a href="{{ path('app_project_show', {'slug': project.slug}) }}" class="btn btn-primary">En savoir plus</a>
<a href="{{ path('app_project_show', {'slug': project.slug}) }}" class="btn btn-primary">{{ 'button.more'|trans }}</a>
</div>
</div>
</div>


+ 15
- 15
templates/macro.html.twig View File

@ -45,25 +45,25 @@ Où :
class="img-fluid img-thumbnail min-vh-50"
></div>
<details>
<summary>Légende</summary>
<span class="badge bg-info">Overpass</span>
<summary>{{ 'map.legend'|trans }}</summary>
<span class="badge bg-info">{{ 'map.overpass'|trans }}</span>
{% set stats = taskLifecycleManager.getProjectStats(entity) %}
{% for place, data in stats %}
<span class="badge {{ 'bg-' ~ data.color }}">{{ data.title }}</span>
<span class="badge {{ 'bg-' ~ data.color }}">{{ data.title|trans }}</span>
{% endfor %}
</details>
<p>
<a href="#" target="_blank" data-map-target="openLink">Ouvrir ailleurs</a> ou voir sur
<button class="btn btn-sm btn-link" data-action="map#openInOsm">OSM</button>
<button class="btn btn-sm btn-link" data-action="map#openInPanoramax">Panoramax</button>
<button class="btn btn-sm btn-link" data-action="map#openInPifomap">Pifomap</button>
<button class="btn btn-sm btn-link" data-action="map#openInPifometre">Pifomètre</button>
<button class="btn btn-sm btn-link" data-action="map#openInGeohack">GeoHack</button>
<button class="btn btn-sm btn-link" data-action="map#openInGeoportail">GéoPortail</button>
<button class="btn btn-sm btn-link" data-action="map#openInF4Map">F4Map</button>
<button class="btn btn-sm btn-link ça-pue-c’est-pas-libre" data-action="map#openInMapillary">Mapillary</button>
<button class="btn btn-sm btn-link ça-pue-c’est-pas-libre" data-action="map#openInGoogleMaps">Google Maps</button>
<button class="btn btn-sm btn-link ça-pue-c’est-pas-libre" data-action="map#openInBing">Bing</button>
<a href="#" target="_blank" data-map-target="openLink">{{ 'map.open_with'|trans }}</a> {{ 'map.or'|trans }}
<button class="btn btn-sm btn-link" data-action="map#openInOsm">{{ 'map.osm'|trans }}</button>
<button class="btn btn-sm btn-link" data-action="map#openInPanoramax">{{ 'map.panoramax'|trans }}</button>
<button class="btn btn-sm btn-link" data-action="map#openInPifomap">{{ 'map.pifomap'|trans }}</button>
<button class="btn btn-sm btn-link" data-action="map#openInPifometre">{{ 'map.pifometre'|trans }}</button>
<button class="btn btn-sm btn-link" data-action="map#openInGeohack">{{ 'map.geohack'|trans }}</button>
<button class="btn btn-sm btn-link" data-action="map#openInGeoportail">{{ 'map.geoportail'|trans }}</button>
<button class="btn btn-sm btn-link" data-action="map#openInF4Map">{{ 'map.f4map'|trans }}</button>
<button class="btn btn-sm btn-link ça-pue-c’est-pas-libre" data-action="map#openInMapillary">{{ 'map.mapillary'|trans }}</button>
<button class="btn btn-sm btn-link ça-pue-c’est-pas-libre" data-action="map#openInGoogleMaps">{{ 'map.googlemaps'|trans }}</button>
<button class="btn btn-sm btn-link ça-pue-c’est-pas-libre" data-action="map#openInBing">{{ 'map.bing'|trans }}</button>
</p>
</div>
{% endmacro %}
@ -82,7 +82,7 @@ serait pas du luxe…
{% macro clipboard(text) %}
<div class="input-group" data-controller="clipboard">
<input type="text" readonly class="form-control" value="{{ text }}" data-clipboard-target="source" />
<button class="btn btn-outline-secondary" type="button" data-action="clipboard#copy" title="Copier dans le presse-papier">
<button class="btn btn-outline-secondary" type="button" data-action="clipboard#copy" title="{{ 'clipboard.copy'|trans }}">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clipboard" viewBox="0 0 16 16">
<path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1z"/>
<path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0z"/>


+ 1
- 1
templates/partials/_comment-metadata.html.twig View File

@ -9,5 +9,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-calendar" viewBox="0 0 16 16">
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"/>
</svg>
{{ comment.createdAt|format_datetime('short', 'short', locale='fr') }}
{{ comment.createdAt|format_datetime('short', 'short', locale=app.request.locale) }}
</span>

+ 5
- 5
templates/partials/_overpass-element-popup.html.twig View File

@ -1,15 +1,15 @@
<h6>{{ element.type|capitalize }} {{ element.id }}</h6>
<p>Voir sur <a href="https://www.openstreetmap.org/{{ element.type }}/{{ element.id }}" target="_blank">OSM</a>
<br/>sur <a href="https://api.panoramax.xyz/#focus=map&map={{ element.map.zoom }}/{{ element.map.center.lat }}/{{ element.map.center.lng }}" target="_blank">Panoramax<a>
<p>{{ 'popup.see_also'|trans }} <a href="https://www.openstreetmap.org/{{ element.type }}/{{ element.id }}" target="_blank">{{ 'popup.osm'|trans }}</a>
<br/><a href="https://api.panoramax.xyz/#focus=map&map={{ element.map.zoom }}/{{ element.map.center.lat }}/{{ element.map.center.lng }}" target="_blank">{{ 'popup.panoramax'|trans }}<a>
{% if element.type == 'relation' and element.tags and element.tags.route and element.tags.route == 'hiking' %}
<br/>sur <a href="https://hiking.waymarkedtrails.org/#route?id={{ element.id }}&type=relation" target="_blank">WayMarkedTrails</a>
<br/><a href="https://hiking.waymarkedtrails.org/#route?id={{ element.id }}&type=relation" target="_blank">{{ 'popup.waymarkedtrails'|trans }}</a>
{% endif %}
<br/>dans <button class="btn btn-link" style="--bs-btn-padding-x:0;--bs-btn-padding-y:0;"
<br/><button class="btn btn-link" style="--bs-btn-padding-x:0;--bs-btn-padding-y:0;"
type="button"
data-controller="josm"
data-action="click->josm#remoteControl"
data-josm-commands-value="{{ josmCommands|escape('html_attr') }}"
>JOSM</button>
>{{ 'popup.josm'|trans }}</button>
<table><tbody>
{% for key, value in element.tags %}
<tr><th>{{ key }}</th><td>{{ value }}</td></tr>


+ 1
- 1
templates/partials/_project-metadata.html.twig View File

@ -9,7 +9,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-calendar" viewBox="0 0 16 16">
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"/>
</svg>
{{ project.createdAt|format_datetime('short', 'short', locale='fr') }}
{{ project.createdAt|format_datetime('short', 'short', locale=app.request.locale) }}
</span>
<span class="me-2">
<img src="{{ path('app_badge_project_status', {'projectSlug': project.slug, 'status': 'done'}) }}" />


+ 1
- 1
templates/partials/_task-locking.html.twig View File

@ -11,7 +11,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-calendar" viewBox="0 0 16 16">
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"/>
</svg>
{{ task.createdAt|format_datetime('short', 'short', locale='fr') }}
{{ task.createdAt|format_datetime('short', 'short', locale=app.request.locale) }}
</span>
{% else %}
<span class="me-2">


+ 1
- 1
templates/partials/_task-metadata.html.twig View File

@ -9,5 +9,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-calendar" viewBox="0 0 16 16">
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"/>
</svg>
{{ task.createdAt|format_datetime('short', 'short', locale='fr') }}
{{ task.createdAt|format_datetime('short', 'short', locale=app.request.locale) }}
</span>

+ 54
- 9
translations/messages.en.yaml View File

@ -1,13 +1,58 @@
exception:
project_not_found: 'Project not found'
status_not_found: 'Status not found'
project_not_found: 'Project not found'
status_not_found: 'Status not found'
alert:
auth_failure: 'Authentification failed'
auth_success: 'Authentification successfull !'
auth_failure: 'Authentification failed'
auth_success: 'Authentification successfull !'
title:
popular_projects: 'Popular projects'
popular_projects: 'Popular projects'
text:
home1: 'Handle tasks, even with nodes (or not).'
home1: 'Handle tasks, even with nodes (or not).'
home2: __text.home2
home3: 'In order to contact the developer, please send an email to %mailto_link%'
button:
close: Close
toggle_navigation: 'Toggle navigation'
more: __button.more
goto_projects: __button.goto_projects
menu:
on_osm: 'OSM Profile'
logout: Logout
login: Login
map:
legend: __map.legend
overpass: __map.overpass
open_with: __map.open_with
or: __map.or
osm: __map.osm
panoramax: __map.panoramax
pifomap: __map.pifomap
pifometre: __map.pifometre
geohack: __map.geohack
geoportail: __map.geoportail
f4map: __map.f4map
mapillary: __map.mapillary
googlemaps: __map.googlemaps
bing: __map.bing
clipboard:
copy: __clipboard.copy
popup:
see_also: __popup.see_also
osm: __popup.osm
panoramax: __popup.panoramax
waymarkedtrails: __popup.waymarkedtrails
josm: __popup.josm
workflow:
place:
todo: 'To do'
doing: Doing
done: Done
transition:
start_task: 'Start task'
start: Start
finish_task: 'Finish task'
finish: Finish
cancel_task: 'Cancel task'
cancel: Cancel
reset_task: 'Reset task'
reset: Reset

+ 56
- 9
translations/messages.fr.yaml View File

@ -1,13 +1,60 @@
exception:
project_not_found: 'Projet introuvable'
status_not_found: 'État introuvable'
project_not_found: 'Projet introuvable'
status_not_found: 'État introuvable'
alert:
auth_failure: 'Échec de l’authentification'
auth_success: 'Authentification OSM réussie !'
auth_failure: 'Échec de l’authentification'
auth_success: 'Authentification OSM réussie !'
title:
popular_projects: 'Projets populaires'
popular_projects: 'Projets populaires'
text:
home1: 'Gère les tâches, même avec des nœuds (ou pas).'
home1: 'Gère les tâches, même avec des nœuds (ou pas).'
home2: '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.'
home3: 'Si d’aventure vous souhaitez contacter le développeur, merci d’écrire à %mailto_link%'
button:
close: Fermer
toggle_navigation: 'Basculer le menu'
more: 'En savoir plus'
goto_projects: 'Voir les projets'
menu:
on_osm: 'Profil OSM'
logout: Déconnexion
login: Connexion
map:
legend: Légende
overpass: Overpass
open_with: 'Ouvrir avec…'
or: ou
osm: OSM
panoramax: Panoramax
pifomap: Pifomap
pifometre: Pifomètre
geohack: GeoHack
geoportail: GéoPortail
f4map: F4Map
mapillary: Mapillary
googlemaps: Google
bing: Bing
clipboard:
copy: 'Copier dans le presse-papier'
popup:
see_also: 'Voir aussi'
osm: OSM
panoramax: Panoramax
waymarkedtrails: WayMarkedTrails
josm: JOSM
comment:
start: '%username% commence la tâche [%task_name%](%task_url%)'
workflow:
place:
todo: 'À faire'
doing: 'En cours'
done: Terminé
transition:
start_task: 'Commencer la tâche'
start: Commencer
finish_task: 'Terminer la tâche'
finish: Terminer
cancel_task: 'Abandonner la tâche'
cancel: Abandonner
reset_task: 'Recommencer la tâche'
reset: Recommencer

Loading…
Cancel
Save