# Système de traduction FR/EN

## Objectif
Mettre en place un système de traduction bilingue (français/anglais) pour l'ensemble du site.

## Principe de fonctionnement

**L'URL est la seule source de vérité** :
- `/about` → cherche dans la colonne `slug` (FR)
- `/en/about` → cherche dans la colonne `slugEn` (EN)

Pas de session, pas de cookie, pas de détection automatique. Simple et prévisible.

## Décisions techniques

### Langues
- **Français** : Langue par défaut (pas de prefix dans l'URL)
- **Anglais** : Prefix `/en/` dans l'URL

### Gestion des slugs
- Chaque page a deux slugs en base :
  - `slug` : slug français (obligatoire)
  - `slugEn` : slug anglais (nullable)
- URLs générées :
  - FR : `/{slug}` (ex: `/a-propos`)
  - EN : `/en/{slugEn}` (ex: `/en/about`)

### Contenu traduit
- Colonnes séparées pour chaque langue : `content` / `contentEn`, `title` / `titleEn`, etc.
- Fallback automatique sur le contenu français si la traduction anglaise est vide (via `TranslationHelper`)
- Tous les contenus sont traduisibles : pages, projets, formulaires

---

## Architecture

### Routes
Chaque route est déclarée deux fois avec l'attribut `locale` :

```php
#[Route('/{slug}', name: 'page_show', locale: 'fr')]
#[Route('/en/{slug}', name: 'page_show_en', locale: 'en')]
public function page(string $slug, Request $request): Response
{
    $locale = $request->getLocale(); // 'fr' ou 'en' depuis l'attribut
    // ...
}
```

### Repository
Recherche dans la bonne colonne selon la locale :

```php
public function findBySlugAndLocale(string $slug, string $locale): ?Page
{
    $field = $locale === 'en' ? 'slugEn' : 'slug';
    return $this->findOneBy([$field => $slug]);
}
```

### TranslationHelper
Service qui récupère le bon contenu avec fallback automatique :

```php
public function getLocalizedContent(Page $page, string $locale): array
{
    if ($locale === 'en' && $page->getContentEn()) {
        return $page->getContentEn();
    }
    return $page->getContent();
}
```

---

## Plan d'implémentation

### Phase 1 : Base de données
- [x] Ajouter colonnes à l'entité Page :
  - `slug_en` (string, nullable)
  - `title_en` (string, nullable)
  - `content_en` (json, nullable)
  - `metaTitle_en` (string, nullable)
  - `metaDescription_en` (string, nullable)
- [x] Créer et exécuter la migration

### Phase 2 : Configuration Symfony
- [x] Configurer les locales dans `config/packages/framework.yaml`
- [x] Installer symfony/translation

### Phase 3 : Routing & Controllers
- [x] Modifier FrontController pour gérer les deux locales
- [x] Adapter les routes pour supporter le prefix `/en/`
- [x] Implémenter la logique de fallback (EN → FR)
- [x] Créer TranslationHelper pour gérer le contenu localisé
- [x] Simplifier PageRepository pour chercher dans le bon champ

### Phase 4 : Frontend
- [x] Ajouter un switch de langue dans le header
- [x] Adapter les templates pour afficher le contenu selon la locale
- [x] Gérer les liens de navigation avec la locale courante
- [x] Créer les fonctions Twig pour URLs et titres localisés

### Phase 5 : Édition inline
- [x] Détecter la locale depuis l'URL en mode édition
- [x] Sauvegarder dans les bonnes colonnes selon la locale
- [x] Ajouter un indicateur visuel de la langue en cours d'édition
- [x] Permettre de basculer entre FR et EN en mode édition
- [x] Adapter PageDataEnricher pour charger le bon contenu selon la locale

### Phase 6 : Administration
- [x] Ajouter les champs de traduction dans le formulaire de création/édition
- [x] Afficher le statut de traduction dans la liste des pages
- [x] Permettre l'édition des deux versions depuis l'admin

### Phase 7 : Traductions système
- [x] Créer les fichiers de traduction :
  - `translations/messages.fr.yaml`
  - `translations/messages.en.yaml`
- [x] Traduire le formulaire de contact
- [x] Traduire les messages système (erreurs, succès, etc.)
- [x] Traduire les labels de l'interface

### Phase 8 : SEO
- [x] Générer les balises `hreflang` pour chaque page
- [x] Mettre à jour le sitemap.xml avec les URLs traduites
- [x] Gérer les meta tags traduits

### Phase 9 : Tests & Validation
- [ ] Tester la navigation entre les langues
- [ ] Tester l'édition inline dans les deux langues
- [ ] Tester le fallback FR quand EN est vide
- [ ] Vérifier le SEO (hreflang, sitemap)

---

## Exemples d'URLs

### Pages classiques
- Accueil FR : `/`
- Accueil EN : `/en/`
- À propos FR : `/a-propos`
- À propos EN : `/en/about` (si `slug_en` = "about")
- Contact FR : `/contact`
- Contact EN : `/en/contact`

### Projets
- Liste FR : `/projets`
- Liste EN : `/en/projects` (si `slug_en` = "projects")
- Projet FR : `/projets/mon-projet`
- Projet EN : `/en/projects/my-project`

### Mode édition
- Édition FR : `/a-propos?edit=1`
- Édition EN : `/en/about?edit=1`

---

## Notes techniques

### Fallback automatique
Si `content_en` est vide, le système affiche automatiquement `content` (FR).

### Session locale
La locale est stockée en session pour :
- Maintenir la langue lors de la navigation
- Faciliter l'édition dans la bonne langue

### Compatibilité
- Les pages existantes continuent de fonctionner (FR par défaut)
- Pas de rupture de compatibilité avec l'existant
