# i18n Troubleshooting & FAQ Guide

Common issues and solutions for the NexusMart multilingual system.

## 🆘 Troubleshooting

### Problem: Strings showing in English instead of translated language

**Symptoms**:
- Visit `/de/products/` but see English text
- Language selector shows German but site is English
- "Add to Cart" appears instead of "In den Warenkorb"

**Root Causes**:
1. `.mo` files not compiled
2. Server not restarted after compilation
3. Translation strings not marked with `{% trans %}` or `_()`
4. `.po` file not edited (empty translations)

**Solutions**:

✓ **Check .mo files exist**:
```bash
ls -la locale/de/LC_MESSAGES/
# Should see django.mo file
```

✓ **Compile translations**:
```bash
python manage.py compilemessages -v 2
```

✓ **Restart server**:
```bash
# Stop: Ctrl+C
python manage.py runserver
```

✓ **Check translation strings**:
```bash
# Count translated strings
grep -c 'msgstr "' locale/de/LC_MESSAGES/django.po

# Find untranslated strings
grep -B2 'msgstr ""' locale/de/LC_MESSAGES/django.po
```

✓ **Verify string is wrapped**:
```python
# ✅ Good
{% trans "Add to Cart" %}
{{ _("Product added!") }}

# ❌ Bad
{{ "Add to Cart" }}
```

---

### Problem: Language selector not changing language

**Symptoms**:
- Click German in dropdown
- Page stays in English
- URL doesn't change to `/de/`

**Root Causes**:
1. Language view not working
2. Middleware not installed
3. URL routing error
4. Session not saving

**Solutions**:

✓ **Check middleware installed**:
```python
# nexusmart/settings.py
MIDDLEWARE = [
    ...
    'django.middleware.locale.LocaleMiddleware',  # Must be here
    'shop.middleware.LanguageCurrencySyncMiddleware',  # Must be here
    ...
]
```

✓ **Check URL routing**:
```python
# shop/urls.py should have:
path('set-language/<str:language_code>/', 
     views.set_language_with_code, 
     name='set_language_with_code'),
```

✓ **Check view exists**:
```python
# shop/language_views.py or shop/views.py
def set_language_with_code(request, language_code):
    request.session['django_language'] = language_code
    return redirect(request.META.get('HTTP_REFERER', '/'))
```

✓ **Check session middleware**:
```python
# SessionMiddleware must come BEFORE LocaleMiddleware
MIDDLEWARE = [
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',  # Before LocaleMiddleware
    'django.middleware.locale.LocaleMiddleware',
    ...
]
```

✓ **Test manually**:
```bash
curl -c cookies.txt "http://localhost:8000/en/"
curl -b cookies.txt "http://localhost:8000/shop/set-language/de/"
curl -b cookies.txt "http://localhost:8000/de/products/"
# Should show German content in last request
```

---

### Problem: URL not showing language prefix

**Symptoms**:
- Visit `http://localhost:8000/products/`
- Not `http://localhost:8000/en/products/`
- Missing language prefix in URL

**Root Causes**:
1. `i18n_patterns()` not used in urls.py
2. `prefix_default_language=False`
3. URLs not wrapped with `i18n_patterns()`

**Solutions**:

✓ **Check urls.py**:
```python
# nexusmart/urls.py should have:
from django.conf.urls.i18n import i18n_patterns

urlpatterns = i18n_patterns(
    prefix_default_language=True,  # Prefix /en/ too
    path('shop/', include('shop.urls')),
    path('user/', include('users.urls')),
    # ... other patterns
)
```

✓ **Verify pattern works**:
```bash
python manage.py showurls | grep -E "^/(en|de|fr)/"
# Should show language-prefixed routes
```

✓ **Access URLs**:
- `/en/products/` - English version
- `/de/products/` - German version
- If you get 404, check `prefix_default_language=True`

---

### Problem: RTL (Arabic) not working

**Symptoms**:
- Visit `/ar/` but text is still LTR
- Buttons on right side instead of left
- HTML `dir` attribute not "rtl"

**Root Causes**:
1. `LANGUAGE_BIDI` not in context
2. RTL CSS not in base.html
3. Context processor not returning `LANGUAGE_BIDI`

**Solutions**:

✓ **Check context processor**:
```python
# shop/context_processors.py should have:
def language_context(request):
    ...
    return {
        ...
        'LANGUAGE_BIDI': is_rtl,  # Must return this
    }
```

✓ **Check template**:
```html
<!-- templates/base.html -->
<html lang="{{ LANGUAGE_CODE }}" 
      dir="{% if LANGUAGE_BIDI %}rtl{% else %}ltr{% endif %}">
```

✓ **Check RTL CSS**:
```css
/* templates/base.html should have: */
html[dir="rtl"] {
    direction: rtl;
    text-align: right;
}
```

✓ **Test in browser**:
```javascript
// Browser console when viewing /ar/
document.documentElement.dir     // Should be "rtl"
document.documentElement.lang    // Should be "ar"
```

---

### Problem: Currency not syncing with language

**Symptoms**:
- Switch to German but currency stays USD
- Should be EUR instead
- Price format not changing

**Root Causes**:
1. `LanguageCurrencySyncMiddleware` not working
2. `LANGUAGE_CURRENCY_MAPPING` not configured
3. Middleware not in correct position

**Solutions**:

✓ **Check middleware**:
```python
# nexusmart/settings.py MIDDLEWARE
'shop.middleware.LanguageCurrencySyncMiddleware',  # Must be included
```

✓ **Check currency mapping**:
```python
# nexusmart/settings.py
LANGUAGE_CURRENCY_MAPPING = {
    'en': 'USD',
    'de': 'EUR',
    'fr': 'EUR',
    'zh': 'CNY',
    # ... etc
}
```

✓ **Check middleware code**:
```python
# shop/middleware.py should have:
def __call__(self, request):
    language = get_language()
    if language in settings.LANGUAGE_CURRENCY_MAPPING:
        currency = settings.LANGUAGE_CURRENCY_MAPPING[language]
        request.session['django_currency'] = currency
    return self.get_response(request)
```

✓ **Test manually**:
```python
# In Django shell
from shop.middleware import LanguageCurrencySyncMiddleware
from django.test import RequestFactory
factory = RequestFactory()
request = factory.get('/de/')
middleware = LanguageCurrencySyncMiddleware(lambda r: None)
middleware(request)
print(request.session.get('django_currency'))  # Should be EUR
```

---

### Problem: Fuzzy translations showing

**Symptoms**:
- English strings still appear with `[fuzzy]` in `.po` file
- `.mo` file compiled but fuzzy strings ignored
- Partial translations not used

**Solutions**:

✓ **Remove fuzzy markers**:
```
# ❌ Before (fuzzy)
#, fuzzy
msgid "Product added"
msgstr "Produit ajouté"

# ✅ After (not fuzzy)
msgid "Product added"
msgstr "Produit ajouté"
```

✓ **In Poedit**:
- Open Poedit
- Fuzzy strings show with warning icon
- Edit them and icon disappears
- Save file

✓ **Recompile after removing fuzzy**:
```bash
python manage.py compilemessages
```

---

### Problem: Cache not clearing translations

**Symptoms**:
- Edit `.po` file and recompile
- Changes don't appear on website
- Old translations still showing

**Root Causes**:
1. Django template caching
2. Browser caching
3. `.mo` file not recompiled

**Solutions**:

✓ **Clear Django cache**:
```python
# In Django shell
from django.core.cache import cache
cache.clear()
```

✓ **Clear browser cache**:
- Chrome: Ctrl+Shift+Delete → "Cached images and files"
- Firefox: Ctrl+Shift+Delete → "Cache"
- Or: Dev Tools → Network → Disable cache

✓ **Hard reload in browser**:
- Windows: `Ctrl+Shift+R` or `Ctrl+F5`
- Mac: `Cmd+Shift+R`

✓ **Restart server**:
```bash
# Stop: Ctrl+C
python manage.py runserver
```

---

## ❓ FAQ

### Q: How many languages can I support?

**A**: Technically unlimited, but practically:
- **5-10 languages**: Easiest to manage
- **10-20 languages**: Manageable with tools
- **20+ languages**: Requires automated translation tools

Current NexusMart: **10 languages** (optimal for e-commerce)

---

### Q: How much effort is translation?

**A**: Depends on content volume:
- **Small site (100 strings)**: 2-4 hours per language
- **Medium site (500 strings)**: 8-16 hours per language
- **Large site (1000+ strings)**: 20-40 hours per language

**NexusMart estimate**: ~500-800 strings = 6-10 hours per language

---

### Q: Can I auto-translate with Google Translate?

**A**: Yes, but with caveats:
- ✓ Fast and cheap
- ✗ Often low quality
- ✗ Needs manual review
- ✗ Context misses

**Better approach**: Manual translation for main languages, auto-translate secondary ones

---

### Q: Do I need a translator?

**A**: Depends on quality requirements:
- **Budget**: Use Google Translate (automated)
- **Quality**: Hire professional translator ($20-50/hour)
- **Hybrid**: Auto-translate + professional review

**Recommendation**: Professional for German, French, Spanish; automated for others

---

### Q: How often should I update translations?

**A**: When you add new features:
1. Developer adds `{% trans "new string" %}`
2. Run `python manage.py makemessages -a --update`
3. Translator updates `.po` files
4. Compile: `python manage.py compilemessages`

**Typical workflow**: Each major release (quarterly/annually)

---

### Q: Can I translate product descriptions?

**A**: Yes, but requires database translation:

**Option 1: Simple** (Manual per language)
- Create separate products in each language
- Simple but duplicates data

**Option 2: Recommended** (Use django-modeltranslation)
```bash
pip install django-modeltranslation
```
- One product, multiple language versions
- Cleaner, industry standard

**Option 3: Advanced** (Use django-parler)
```bash
pip install django-parler
```
- More flexible, supports custom fields

---

### Q: What about customer emails?

**A**: Email templates can use i18n:

```django
{# shop/templates/email/order_confirmation.html #}
{% load i18n %}
<h1>{% trans "Order Confirmation" %}</h1>
<p>{% trans "Thank you for your order!" %}</p>
<p>{% blocktrans %}Order #{{ order_id }} has been received.{% endblocktrans %}</p>
```

Add to makemessages:
```bash
python manage.py makemessages -a -e html --add-comments
```

---

### Q: How do I handle number/date formatting?

**A**: Django handles automatically:

```django
{{ order_date|date:"DATE_FORMAT" }}
{{ total_price|floatformat:2 }}
```

Format changes per language (set in settings):
```python
# nexusmart/settings.py
DATE_FORMAT = 'd/m/Y'  # Changed per LANGUAGE_CODE
```

---

### Q: Can I have fallback languages?

**A**: Yes, configure language fallback:

```python
# nexusmart/settings.py
from django.conf.locale.pt_BR import formats
LANGUAGE_CODE = 'en'
LANGUAGES = [
    ('en', 'English'),
    ('pt', 'Português'),
    ('pt-br', 'Português (Brasil)'),  # Falls back to 'pt'
]
```

---

### Q: What's the performance impact?

**A**: Minimal overhead:
- **Compilation**: .po → .mo takes ~100ms
- **Loading**: .mo file loaded once at startup
- **Runtime**: <1ms per template translation
- **Overall**: Negligible impact (~5ms per request)

---

### Q: How do I monitor translation completion?

**A**: Use Django management command:

```bash
# Count strings per language
for lang in de fr es zh ja ka ru ar pt; do
  count=$(grep -c 'msgstr "' locale/$lang/LC_MESSAGES/django.po)
  echo "$lang: $count translated"
done
```

Or in Python:
```python
import os
from pathlib import Path

locale_path = Path('locale')
for lang_dir in locale_path.glob('*/LC_MESSAGES'):
    po_file = lang_dir / 'django.po'
    translated = len([line for line in po_file.read_text().split('\n') if line.startswith('msgstr "') and line != 'msgstr ""'])
    print(f"{lang_dir.parent.name}: {translated} translated")
```

---

### Q: Should I commit `.po` and `.mo` files to git?

**A**: Yes, both should be committed:

```
.gitignore:
# DON'T ignore translation files
# locale/  ← Remove if you have this

# DO ignore other generated files
*.pyc
__pycache__/
staticfiles/
```

Why:
- `.po`: Source for translations (for translators)
- `.mo`: Compiled for deployment (needed for production)

---

### Q: How do I handle context-specific translations?

**A**: Use context hints:

```django
{# Order as noun vs verb #}
{% trans "Order" context "ecommerce_noun" %}
{% trans "Order" context "ecommerce_verb" %}
```

In `.po` file:
```
#: templates/order.html:5
msgctxt "ecommerce_noun"
msgid "Order"
msgstr "Bestellung"

#: templates/order.html:10
msgctxt "ecommerce_verb"
msgid "Order"
msgstr "Bestellen"
```

---

### Q: Can I use pluralization in templates?

**A**: Yes, use blocktrans:

```django
{% blocktrans count counter=items.count %}
  You have {{ counter }} item in your cart.
{% plural %}
  You have {{ counter }} items in your cart.
{% endblocktrans %}
```

Some languages have complex plural rules (Czech, Polish):
- Django handles automatically

---

### Q: What about RTL-specific CSS?

**A**: Already added! Check base.html:

```css
html[dir="rtl"] {
    direction: rtl;
    text-align: right;
}

html[dir="rtl"] .cart-drawer {
    right: auto;
    left: -380px;
}
```

For custom components:
```css
.my-component {
    margin-left: 10px;       /* LTR */
}

html[dir="rtl"] .my-component {
    margin-left: 0;
    margin-right: 10px;      /* RTL */
}
```

---

### Q: How do I test all languages?

**A**: Use browser workflow:

```bash
# Start server
python manage.py runserver

# Test each language
for lang in en de fr es zh ja ka ru ar pt; do
  echo "Testing: $lang"
  # Visit http://localhost:8000/$lang/products/
done
```

Or automated:
```python
# test_languages.py
from django.test import Client

client = Client()
languages = ['en', 'de', 'fr', 'es', 'zh', 'ja', 'ka', 'ru', 'ar', 'pt']

for lang in languages:
    response = client.get(f'/{lang}/products/')
    assert response.status_code == 200
    print(f"✓ {lang}")
```

---

## 🔗 Resources

- **Django i18n Docs**: https://docs.djangoproject.com/en/5.1/topics/i18n/
- **GNU Gettext**: https://www.gnu.org/software/gettext/
- **Poedit**: https://poedit.net
- **django-modeltranslation**: https://django-modeltranslation.readthedocs.io/
- **django-parler**: https://django-parler.readthedocs.io/

---

## 📞 When to Seek Help

- **Django Issues**: Django documentation + Stack Overflow
- **Translation Issues**: Ask linguist or professional translator
- **Poedit Issues**: Poedit documentation + support
- **Custom i18n**: Hire Django developer

---

**Status**: ✅ Infrastructure Ready | ⏳ Awaiting Translations

For more help, see:
- `I18N_SETUP.md` - Complete overview
- `TRANSLATION_QUICKSTART.md` - 5-minute guide
- `I18N_VERIFICATION_CHECKLIST.md` - Verify setup
- `I18N_ARCHITECTURE.md` - System architecture
