#!/bin/bash # Translation Update Script # Automatically extracts and updates translation strings set -e echo "🌍 Translation Update Utility" echo "=============================" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration LOCALES_DIR="../locales" TEMPLATES_DIR="../templates" ASSETS_DIR="../assets" SRC_DIR="../src" # Create locales directory if it doesn't exist mkdir -p "$LOCALES_DIR" echo -e "${BLUE}📁 Scanning for untranslated strings...${NC}" # Find all HTML files and extract data-i18n attributes echo -e "${YELLOW}🔍 Scanning HTML templates...${NC}" find $TEMPLATES_DIR -name "*.html" -exec grep -oE 'data-i18n="[^"]*"' {} \; | \ sed 's/data-i18n="//g' | sed 's/"//g' | sort | uniq > /tmp/html_keys.txt find $TEMPLATES_DIR -name "*.html" -exec grep -oE 'data-i18n-placeholder="[^"]*"' {} \; | \ sed 's/data-i18n-placeholder="//g' | sed 's/"//g' | sort | uniq >> /tmp/html_keys.txt find $TEMPLATES_DIR -name "*.html" -exec grep -oE 'data-i18n-title="[^"]*"' {} \; | \ sed 's/data-i18n-title="//g' | sed 's/"//g' | sort | uniq >> /tmp/html_keys.txt # Find all PHP files and extract data-i18n attributes echo -e "${YELLOW}🔍 Scanning PHP templates...${NC}" find $SRC_DIR -name "*.php" -exec grep -oE 'data-i18n="[^"]*"' {} \; | \ sed 's/data-i18n="//g' | sed 's/"//g' | sort | uniq > /tmp/php_keys.txt find $SRC_DIR -name "*.php" -exec grep -oE 'data-i18n-placeholder="[^"]*"' {} \; | \ sed 's/data-i18n-placeholder="//g' | sed 's/"//g' | sort | uniq >> /tmp/php_keys.txt find $SRC_DIR -name "*.php" -exec grep -oE 'data-i18n-title="[^"]*"' {} \; | \ sed 's/data-i18n-title="//g' | sed 's/"//g' | sort | uniq >> /tmp/php_keys.txt # Find JavaScript files and extract this.t() calls echo -e "${YELLOW}🔍 Scanning JavaScript files...${NC}" find $ASSETS_DIR -name "*.js" -exec grep -oE "this\.t\('[^']*'\)" {} \; | \ sed "s/this\.t('//g" | sed "s/')//g" | sort | uniq > /tmp/js_keys.txt find $ASSETS_DIR -name "*.js" -exec grep -oE 'this\.t\("[^"]*"\)' {} \; | \ sed 's/this\.t("//g' | sed 's/")//g' | sort | uniq >> /tmp/js_keys.txt # Combine all keys cat /tmp/html_keys.txt /tmp/js_keys.txt /tmp/php_keys.txt | sort | uniq > /tmp/all_keys.txt echo -e "${BLUE}📊 Found $(cat /tmp/all_keys.txt | wc -l) unique translation keys${NC}" # Function to create/update language file update_language_file() { local lang=$1 local file="$LOCALES_DIR/$lang.json" echo -e "${YELLOW}📝 Updating $lang.json...${NC}" # Load existing translations or create empty object if [ -f "$file" ]; then cp "$file" "/tmp/${lang}_backup.json" existing_keys=$(cat "$file" | jq -r 'keys[]' 2>/dev/null || echo "") else echo "{}" > "$file" existing_keys="" fi # Create temporary file with all required keys echo "{" > "/tmp/${lang}_new.json" first=true while IFS= read -r key; do if [ ! -z "$key" ]; then # Check if key already exists existing_value=$(cat "$file" | jq -r ".[\"$key\"] // empty" 2>/dev/null) if [ ! -z "$existing_value" ] && [ "$existing_value" != "null" ]; then # Keep existing translation value="$existing_value" else # Add new key with placeholder or translation case $lang in "en") # Convert snake_case to human readable value=$(echo "$key" | sed 's/_/ /g' | sed 's/\b\(.\)/\u\1/g') ;; "de") case $key in "generate") value="Generieren" ;; "copy") value="Kopieren" ;; "language") value="Sprache" ;; "options") value="Optionen" ;; "password_generator") value="Passwort-Generator" ;; "api_documentation") value="API-Dokumentation" ;; "loading") value="Wird geladen..." ;; "error") value="Fehler" ;; "success") value="Erfolgreich" ;; "download") value="Herunterladen" ;; "back") value="Zurück" ;; "home") value="Startseite" ;; "settings") value="Einstellungen" ;; *) value="$(echo "$key" | sed 's/_/ /g' | sed 's/\b\(.\)/\u\1/g') (DE)" ;; esac ;; "fr") case $key in "generate") value="Générer" ;; "copy") value="Copier" ;; "language") value="Langue" ;; "options") value="Options" ;; "password_generator") value="Générateur de mots de passe" ;; "api_documentation") value="Documentation API" ;; "loading") value="Chargement..." ;; "error") value="Erreur" ;; "success") value="Succès" ;; "download") value="Télécharger" ;; "back") value="Retour" ;; "home") value="Accueil" ;; "settings") value="Paramètres" ;; *) value="$(echo "$key" | sed 's/_/ /g' | sed 's/\b\(.\)/\u\1/g') (FR)" ;; esac ;; *) value="$(echo "$key" | sed 's/_/ /g' | sed 's/\b\(.\)/\u\1/g') (TODO: $lang)" ;; esac fi # Add to JSON if [ "$first" = true ]; then first=false else echo "," >> "/tmp/${lang}_new.json" fi # Escape quotes in value escaped_value=$(echo "$value" | sed 's/"/\\"/g') echo " \"$key\": \"$escaped_value\"" >> "/tmp/${lang}_new.json" fi done < /tmp/all_keys.txt echo "" >> "/tmp/${lang}_new.json" echo "}" >> "/tmp/${lang}_new.json" # Format JSON nicely cat "/tmp/${lang}_new.json" | jq '.' > "$file" # Count translations total_keys=$(cat /tmp/all_keys.txt | wc -l) translated_keys=$(cat "$file" | jq -r 'to_entries[] | select(.value | test("\\(TODO:|\\(DE\\)|\\(FR\\)|\\(IT\\)|\\(ES\\)|\\(JA\\)|\\(ZH\\))") | not) | .key' | wc -l) echo -e "${GREEN}✅ Updated $lang.json: $translated_keys/$total_keys translated${NC}" } # Update all language files languages=("en" "de" "fr" "it" "es" "ja" "zh") for lang in "${languages[@]}"; do update_language_file "$lang" done # Generate report echo "" echo -e "${BLUE}📊 Translation Status Report${NC}" echo "============================" for lang in "${languages[@]}"; do file="$LOCALES_DIR/$lang.json" if [ -f "$file" ]; then total=$(cat /tmp/all_keys.txt | wc -l) translated=$(cat "$file" | jq -r 'to_entries[] | select(.value | test("\\(TODO:|\\(DE\\)|\\(FR\\)|\\(IT\\)|\\(ES\\)|\\(JA\\)|\\(ZH\\))") | not) | .key' | wc -l 2>/dev/null || echo "0") percentage=$((translated * 100 / total)) echo -e "$lang: $translated/$total ($percentage%) translated" fi done # Find hardcoded strings that need data-i18n attributes echo "" echo -e "${YELLOW}🔍 Finding hardcoded strings that need localization...${NC}" # Check HTML files for hardcoded text echo -e "${BLUE}HTML files with potential hardcoded text:${NC}" find $TEMPLATES_DIR -name "*.html" -exec grep -l '[>][A-Z][^<]*[a-z][^<]*[<]' {} \; | while read file; do echo " 📄 $file" grep -oE '>[A-Z][^<]*[a-z][^<]*<' "$file" | sed 's/^>//; s/<$//' | head -5 | while read text; do if [[ ! "$text" =~ ^(GET|POST|PUT|DELETE|HTTP|JSON|API|URL|ID|OK|CSS|JS|HTML)$ ]]; then echo " → \"$text\" (needs data-i18n)" fi done done # Check JavaScript files for hardcoded strings echo -e "${BLUE}JavaScript files with potential hardcoded text:${NC}" find $ASSETS_DIR -name "*.js" -exec grep -l "'[A-Z][^']*[a-z][^']*'" {} \; | while read file; do echo " 📄 $file" grep -oE "'[A-Z][^']*[a-z][^']*'" "$file" | sed "s/^'//; s/'$//" | head -5 | while read text; do if [[ ! "$text" =~ ^(GET|POST|PUT|DELETE|HTTP|JSON|API|URL|ID|OK|CSS|JS|HTML|Content-Type|application/json)$ ]]; then echo " → \"$text\" (needs this.t())" fi done done # Generate migration instructions echo "" echo -e "${GREEN}📋 Next Steps:${NC}" echo "1. Review the generated translation files in $LOCALES_DIR/" echo "2. Replace placeholder translations (TODO: lang) with proper translations" echo "3. Add data-i18n attributes to hardcoded HTML strings" echo "4. Replace hardcoded JavaScript strings with this.t() calls" echo "5. Test the application in different languages" # Clean up temporary files rm -f /tmp/html_keys.txt /tmp/js_keys.txt /tmp/all_keys.txt /tmp/*_new.json echo "" echo -e "${GREEN}✅ Translation update completed!${NC}"