Files
personotes/I18N_IMPLEMENTATION.md

6.2 KiB

🌍 Internationalization Implementation - Personotes

Ce qui a été implémenté

1. Infrastructure i18n (TERMINÉ)

Fichiers de traduction:

  • locales/en.json - Traductions anglaises complètes (200+ clés)
  • locales/fr.json - Traductions françaises complètes (200+ clés)
  • locales/README.md - Guide pour contributeurs

Backend Go:

  • internal/i18n/i18n.go - Package i18n avec Translator
  • internal/i18n/i18n_test.go - Tests unitaires
  • Intégration dans cmd/server/main.go
  • Endpoint /api/i18n/{lang} pour servir les traductions JSON
  • Fonctions helper getLanguage() et t() dans handler.go

Frontend JavaScript:

  • frontend/src/i18n.js - Module i18n client avec détection automatique
  • frontend/src/language-manager.js - Gestionnaire UI et rechargement
  • Import dans frontend/src/main.js

Interface utilisateur:

  • Nouvel onglet "Autre" dans les Settings
  • Sélecteur de langue 🇬🇧 English / 🇫🇷 Français
  • Persistance dans localStorage
  • Rechargement automatique de l'interface

📋 Étapes restantes pour finalisation

Étape 1: Build du Frontend

cd frontend
npm install  # Si pas déjà fait
npm run build

Étape 2: Tester le serveur

go run ./cmd/server

Vérifier que:

  • Les traductions se chargent au démarrage (log: traductions chargees: [en fr])
  • L'endpoint /api/i18n/en retourne du JSON
  • L'endpoint /api/i18n/fr retourne du JSON
  • La modal Settings affiche l'onglet "Autre"

Étape 3: Migration des messages d'erreur backend (OPTIONNEL)

Les messages d'erreur français dans le code Go peuvent être migrés progressivement. Pour l'instant, ils restent en français car:

  1. Ils apparaissent surtout dans les logs serveur
  2. L'interface utilisateur peut déjà être traduite
  3. La migration peut se faire progressivement sans casser le code

Exemple de migration (si souhaité):

// Avant
http.Error(w, "methode non supportee", http.StatusMethodNotAllowed)

// Après
http.Error(w, h.t(r, "errors.methodNotAllowed"), http.StatusMethodNotAllowed)

Étape 4: Migration du JavaScript (OPTIONNEL pour l'instant)

Les alert() français dans file-tree.js peuvent être migrés:

// Avant
alert('Veuillez entrer un nom de note');

// Après
import { t } from './i18n.js';
alert(t('fileTree.enterNoteName'));

Étape 5: Migration des Templates HTML (EN COURS)

Les templates HTML contiennent encore du texte français en dur. Deux approches possibles:

Option A: Utiliser data-i18n attributes (Recommandé)

<button data-i18n="editor.save">Sauvegarder</button>
<script>
// Le language-manager.js appelle automatiquement i18n.translatePage()
</script>

Option B: Utiliser les fonctions template Go

<!-- Dans les templates -->
<button>{{ t "editor.save" }}</button>

Nécessite d'ajouter la fonction t aux template funcs:

funcMap := template.FuncMap{
    "t": func(key string) string {
        return h.i18n.T("en", key) // ou détecter la langue
    },
}
templates := template.New("").Funcs(funcMap).ParseGlob("templates/*.html")

🚀 Pour aller plus loin

Ajout d'une nouvelle langue

  1. Créer locales/es.json (exemple: espagnol)
  2. Copier la structure de en.json
  3. Traduire toutes les clés
  4. Ajouter dans la modal Settings:
    <label class="language-option">
        <input type="radio" name="language" value="es">
        <div>🇪🇸 Español</div>
    </label>
    
  5. Redémarrer le serveur

Détection automatique de la langue

Le système détecte automatiquement la langue dans cet ordre:

  1. Cookie language
  2. Header HTTP Accept-Language
  3. Langue du navigateur (JavaScript)
  4. Défaut: Anglais

Persistance

  • Frontend: localStorage (language)
  • Backend: Cookie HTTP (à implémenter si besoin)

📝 Notes techniques

Structure des clés de traduction

app.name                    → "Personotes"
menu.home                   → "Home" / "Accueil"
editor.confirmDelete        → "Are you sure...?" (avec {{filename}})
errors.methodNotAllowed     → "Method not allowed"

Interpolation de variables

// JavaScript
t('editor.confirmDelete', { filename: 'test.md' })
// → "Are you sure you want to delete this note (test.md)?"

// Go
h.t(r, "editor.confirmDelete", map[string]string{"filename": "test.md"})
// → "Êtes-vous sûr de vouloir supprimer cette note (test.md) ?"

Performance

  • Les traductions sont chargées une seule fois au démarrage du serveur
  • Le frontend charge les traductions de manière asynchrone
  • Aucun impact sur les performances après le chargement initial

Checklist de test

  • Le serveur démarre sans erreur
  • /api/i18n/en retourne du JSON valide
  • /api/i18n/fr retourne du JSON valide
  • La modal Settings s'ouvre
  • L'onglet "Autre" est visible
  • On peut changer de langue
  • La sélection persiste après rechargement
  • La console ne montre pas d'erreurs JavaScript
  • Les notes existantes ne sont pas affectées

🐛 Dépannage

Erreur: "traductions not found"

  • Vérifier que le dossier locales/ existe
  • Vérifier que en.json et fr.json sont présents
  • Vérifier les permissions de lecture

Interface ne se traduit pas

  • Ouvrir la console navigateur (F12)
  • Vérifier les erreurs réseau dans l'onglet Network
  • Vérifier que /api/i18n/en retourne du JSON
  • Vérifier que i18n.js est chargé dans main.js

Langue ne persiste pas

  • Vérifier que localStorage fonctionne (pas de navigation privée)
  • Vérifier la console pour les erreurs de localStorage

📚 Documentation

La documentation complète du système i18n est dans:

  • locales/README.md - Guide pour contributeurs
  • Ce fichier - Guide d'implémentation
  • Les commentaires dans le code source

🎉 Résultat final

Une fois tout implémenté, l'application:

  • Détecte automatiquement la langue du navigateur
  • Permet de changer de langue via Settings
  • Persiste le choix de l'utilisateur
  • Recharge l'interface automatiquement
  • Supporte facilement l'ajout de nouvelles langues
  • N'affecte pas le contenu des notes