# NebuleAir i18n System Lightweight internationalization (i18n) system for NebuleAir web interface. ## Features - **Offline-first**: Works completely offline with local JSON translation files - **Database-backed**: Language preference stored in SQLite `config_table` - **Automatic**: Translations apply on page load and when language changes - **Simple API**: Easy-to-use data attributes and JavaScript API ## Quick Start ### 1. Include i18n.js in your HTML page ```html ``` The i18n system will automatically initialize when the page loads. ### 2. Add translation keys to HTML elements Use the `data-i18n` attribute to mark elements for translation: ```html

Titre en français

Description en français

``` The text content serves as a fallback if translations aren't loaded. ### 3. Add translations to JSON files Edit `lang/fr.json` and `lang/en.json`: ```json { "page": { "title": "Mon Titre", "description": "Ma description" }, "common": { "submit": "Soumettre" } } ``` Translation keys use dot notation for nested objects. ## Translation Files - **`fr.json`**: French translations (default) - **`en.json`**: English translations ### File Structure Example ```json { "common": { "save": "Enregistrer", "cancel": "Annuler", "delete": "Supprimer" }, "navigation": { "home": "Accueil", "settings": "Paramètres" }, "sensors": { "title": "Capteurs", "description": "Liste des capteurs" } } ``` ## JavaScript API ### Get Current Language ```javascript const currentLang = i18n.currentLang; // 'fr' or 'en' ``` ### Change Language Programmatically ```javascript await i18n.setLanguage('en'); // Switch to English ``` ### Get Translation in JavaScript ```javascript const translation = i18n.get('sensors.title'); // Returns translated string ``` ### Manual Translation Application If you dynamically create HTML elements, call `applyTranslations()` after adding them to the DOM: ```javascript // Create new element const div = document.createElement('div'); div.setAttribute('data-i18n', 'mypage.newElement'); div.textContent = 'Fallback text'; document.body.appendChild(div); // Apply translations i18n.applyTranslations(); ``` ### Listen for Language Changes ```javascript document.addEventListener('languageChanged', (event) => { console.log('Language changed to:', event.detail.language); // Reload dynamic content, update charts, etc. }); ``` ## Special Cases ### Input Placeholders For input fields, the translation applies to the `placeholder` attribute: ```html ``` ### Button Values For input buttons, the translation applies to the `value` attribute: ```html ``` ### Dynamic Content For content created with JavaScript (like sensor cards), add `data-i18n` attributes to your template strings and call `i18n.applyTranslations()` after inserting into the DOM. ## Example: Migrating an Existing Page ### Before (French only): ```html Capteurs

Liste des capteurs

``` ### After (Multilingual): ```html Capteurs

Liste des capteurs

``` **Add to `lang/fr.json`:** ```json { "sensors": { "pageTitle": "Capteurs", "title": "Liste des capteurs" }, "common": { "getData": "Obtenir les données" } } ``` **Add to `lang/en.json`:** ```json { "sensors": { "pageTitle": "Sensors", "title": "Sensor List" }, "common": { "getData": "Get Data" } } ``` ## Backend Integration ### Get Language Preference ```javascript const response = await fetch('launcher.php?type=get_language'); const data = await response.json(); console.log(data.language); // 'fr' or 'en' ``` ### Set Language Preference ```javascript const response = await fetch('launcher.php?type=set_language&language=en'); const data = await response.json(); console.log(data.success); // true ``` Language preference is stored in SQLite `config_table` with key `language`. ## Completed Pages - ✅ **sensors.html** - Fully translated with French/English support ## TODO: Pages to Migrate - ⏳ index.html - ⏳ admin.html - ⏳ wifi.html - ⏳ saraR4.html - ⏳ map.html ## Tips 1. **Reuse common translations**: Put frequently used strings (buttons, actions, status messages) in the `common` section 2. **Keep keys descriptive**: Use `sensors.bme280.title` instead of `s1` for maintainability 3. **Test both languages**: Always verify that both French and English translations display correctly 4. **Fallback text**: Always provide fallback text in HTML for graceful degradation ## Support For issues or questions about the i18n system, refer to the implementation in: - `/html/assets/js/i18n.js` - Core translation library - `/html/lang/fr.json` - French translations - `/html/lang/en.json` - English translations - `/html/sensors.html` - Example implementation