Initial commit: Complete multilingual website with translation system

This commit is contained in:
2025-06-30 16:19:03 +02:00
commit 98ad79899e
28 changed files with 8850 additions and 0 deletions

180
translation_manager.py Normal file
View File

@@ -0,0 +1,180 @@
#!/usr/bin/env python3
"""
Simple JSON-based Translation Manager for Kobelly Web Solutions
No compilation needed - just edit JSON files directly!
"""
import os
import json
import glob
from flask import request, session, url_for
from functools import wraps
# Supported languages
SUPPORTED_LANGUAGES = ['en', 'de', 'fr', 'nl']
# Default language
DEFAULT_LANGUAGE = 'en'
# Translation cache
_translations = {}
def load_translations():
"""Load all translation files into memory."""
global _translations
if not os.path.exists('translations'):
os.makedirs('translations')
for lang in SUPPORTED_LANGUAGES:
lang_file = f'translations/{lang}.json'
if os.path.exists(lang_file):
try:
with open(lang_file, 'r', encoding='utf-8') as f:
_translations[lang] = json.load(f)
print(f"✓ Loaded {lang} translations ({len(_translations[lang])} keys)")
except Exception as e:
print(f"✗ Error loading {lang} translations: {e}")
_translations[lang] = {}
else:
print(f"{lang} translation file not found, creating empty one")
_translations[lang] = {}
save_translations(lang, {})
def save_translations(lang, translations):
"""Save translations for a specific language."""
if not os.path.exists('translations'):
os.makedirs('translations')
lang_file = f'translations/{lang}.json'
try:
with open(lang_file, 'w', encoding='utf-8') as f:
json.dump(translations, f, indent=2, ensure_ascii=False)
_translations[lang] = translations
print(f"✓ Saved {lang} translations")
return True
except Exception as e:
print(f"✗ Error saving {lang} translations: {e}")
return False
def get_current_language():
"""Get the current language from session or request."""
# Check session first
if 'language' in session:
return session['language']
# Check request parameter
if request.args.get('lang') in SUPPORTED_LANGUAGES:
return request.args.get('lang')
# Check Accept-Language header
if request.accept_languages:
for lang in request.accept_languages:
if lang[0] in SUPPORTED_LANGUAGES:
return lang[0]
return DEFAULT_LANGUAGE
def set_language(lang):
"""Set the current language in session."""
if lang in SUPPORTED_LANGUAGES:
session['language'] = lang
print(f"✓ Language set to {lang}")
return True
print(f"✗ Invalid language: {lang}")
return False
def translate(key, lang=None, **kwargs):
"""Translate a key to the specified language."""
if lang is None:
lang = get_current_language()
# Get translation
translation = _translations.get(lang, {}).get(key, key)
# Format with kwargs if provided
if kwargs:
try:
translation = translation.format(**kwargs)
except (KeyError, ValueError):
# If formatting fails, return the key
translation = key
return translation
def extract_strings():
"""Extract all translatable strings from templates and create translation files."""
print("📤 Extracting translatable strings...")
# Find all template files
template_files = glob.glob('templates/**/*.html', recursive=True)
# Extract strings (this is a simplified version)
# In practice, you'd want to parse the templates more thoroughly
extracted_strings = set()
for template_file in template_files:
try:
with open(template_file, 'r', encoding='utf-8') as f:
content = f.read()
# Look for common patterns (this is simplified)
# You might want to use a proper template parser
lines = content.split('\n')
for line in lines:
line = line.strip()
if line and not line.startswith('{') and not line.startswith('<!--'):
# Simple extraction - you might want to improve this
if len(line) > 3 and not line.startswith('<'):
extracted_strings.add(line)
except Exception as e:
print(f"Error reading {template_file}: {e}")
# Create translation structure
translations = {}
for string in sorted(extracted_strings):
translations[string] = string
# Save for each language
for lang in SUPPORTED_LANGUAGES:
save_translations(lang, translations)
print(f"✓ Extracted {len(extracted_strings)} strings")
return translations
def create_language_selector():
"""Create HTML for language selector."""
current_lang = get_current_language()
html = '<div class="language-selector">'
for lang in SUPPORTED_LANGUAGES:
lang_name = {
'en': 'English',
'de': 'Deutsch',
'fr': 'Français',
'nl': 'Nederlands'
}.get(lang, lang.upper())
active_class = 'active' if lang == current_lang else ''
html += f'<a href="?lang={lang}" class="lang-link {active_class}">{lang_name}</a>'
html += '</div>'
return html
# Flask integration
def init_app(app):
"""Initialize the translation system with Flask app."""
load_translations()
@app.context_processor
def inject_translations():
return {
'translate': translate,
'get_current_language': get_current_language,
'create_language_selector': create_language_selector
}
# Convenience function for templates
def t(key, **kwargs):
"""Short alias for translate function."""
return translate(key, **kwargs)