# Language & Currency Translation System - Implementation Guide

## Overview
Your NexusMart project now has a comprehensive language translation system that automatically syncs language selection with currency conversion. When users change the language, the currency automatically switches to match that language's region.

## How It Works

### Language-Currency Mapping
The system includes automatic mapping between languages and currencies:

- **English (en)** ↔ **USD** (United States Dollar)
- **German (de)** ↔ **EUR** (Euro)
- **French (fr)** ↔ **EUR** (Euro)
- **Spanish (es)** ↔ **EUR** (Euro)
- **Chinese (zh)** ↔ **CNY** (Chinese Yuan)
- **Japanese (ja)** ↔ **JPY** (Japanese Yen)
- **Georgian (ka)** ↔ **GEL** (Georgian Lari)
- **Russian (ru)** ↔ **EUR** (Euro)
- **Arabic (ar)** ↔ **USD** (United States Dollar)
- **Portuguese (pt)** ↔ **EUR** (Euro)

## Components Implemented

### 1. **Settings Configuration** (`nexusmart/settings.py`)
```python
LANGUAGES = [
    ('en', 'English'),
    ('de', 'Deutsch'),
    # ... other languages
]

LANGUAGE_CURRENCY_MAPPING = {
    'en': 'USD',
    'de': 'EUR',
    # ... mapping for all languages
}

LOCALE_PATHS = [
    BASE_DIR / 'locale',  # Directory for translation files
]
```

### 2. **Middleware** (`shop/middleware.py`)
- **LanguageCurrencySyncMiddleware**: Automatically syncs language and currency when either is changed
  - When language changes → currency updates to match
  - When currency changes → language updates to match

### 3. **Context Processors** (`shop/context_processors.py`)
- **language()**: Provides language information to all templates
  - `current_language`: Currently active language code
  - `available_languages`: List of all available languages
  - `language_currency_map`: Mapping of languages to currencies
  - `LANGUAGE_BIDI`: Boolean for right-to-left language support

### 4. **Language Views** (`shop/language_views.py`)
Three endpoints for language/currency switching:

```python
# Set language
/set-language/              # POST method, expects 'language' parameter
/set-language/<language>/   # GET method with language code

# Set currency
/set-currency/              # POST method, expects 'currency' parameter  
/set-currency/<currency>/   # GET method with currency code

# Get available languages as JSON
/api/languages/             # Returns all languages and currencies
```

### 5. **Template Filters** (`shop/templatetags/i18n_filters.py`)
Custom template tags and filters:

```django
{# Filter: Get dictionary value #}
{{ my_dict|dict_lookup:key }}

{# Filter: Get currency symbol #}
{{ currency_code|get_currency_symbol }}

{# Filter: Get language name #}
{{ language_code|get_language_name }}

{# Simple tag: Get all currencies #}
{% get_available_currencies as currencies %}

{# Simple tag: Get all languages #}
{% get_available_languages as languages %}

{# Simple tag: Get language-currency mapping #}
{% get_language_currency_mapping as mapping %}
```

### 6. **Translation Utilities** (`shop/translation_utils.py`)
Helper functions for working with translations:

```python
from shop.translation_utils import (
    get_language_currency_pair,
    get_language_name,
    get_currency_symbol,
    get_currency_name,
    is_language_rtl,
    get_language_options_for_template,
)
```

## Using the System in Templates

### Adding Language Selector to Templates

```django
{% load i18n i18n_filters %}

<!-- Language dropdown -->
<div class="dropdown">
  <button class="btn btn-sm dropdown-toggle" type="button" id="languageDropdown" 
    data-bs-toggle="dropdown">
    {{ current_language|upper }}
  </button>
  <ul class="dropdown-menu" aria-labelledby="languageDropdown">
    {% for lang_code, lang_name in available_languages %}
      <li>
        <a class="dropdown-item" href="{% url 'shop:set_language_with_code' lang_code %}">
          {{ lang_name }}
        </a>
      </li>
    {% endfor %}
  </ul>
</div>
```

### Adding Translatable Strings

Use Django's `{% trans %}` and `{% blocktrans %}` tags:

```django
{% load i18n %}

<!-- Simple translation -->
<h1>{% trans "Welcome to BanshiX" %}</h1>

<!-- Translation with variables -->
<p>{% blocktrans %}Hello {{ user.username }}{% endblocktrans %}</p>

<!-- Plural forms -->
{% blocktrans count counter=items|length %}
  You have {{ counter }} item.
{% plural %}
  You have {{ counter }} items.
{% endblocktrans %}
```

## Creating Translation Files

### Step 1: Mark Strings for Translation
Use `{% trans %}` in templates and `_()` or `gettext()` in Python code.

### Step 2: Generate Translation Files
```bash
# Extract all translatable strings
python manage.py makemessages -l de  # For German
python manage.py makemessages -l zh  # For Chinese
python manage.py makemessages -l ja  # For Japanese

# For all languages at once
python manage.py makemessages --all
```

This creates `.po` files in `locale/[language]/LC_MESSAGES/django.po`

### Step 3: Translate the Strings
Open the `.po` file and fill in translations:

```po
#: templates/product_detail.html:15
msgid "Add to Cart"
msgstr "Zum Warenkorb hinzufügen"  # German translation

#: templates/product_detail.html:20
msgid "Price"
msgstr "Preis"
```

### Step 4: Compile Translations
```bash
python manage.py compilemessages
```

This creates `.mo` files that Django uses at runtime.

## Using Translations in Python Code

```python
from django.utils.translation import gettext as _
from django.utils.translation import ngettext

# Simple translation
message = _("Welcome to BanshiX")

# Plural forms
count = 5
message = ngettext(
    'You have %(count)d item',
    'You have %(count)d items',
    count
) % {'count': count}
```

## Session Data

The system stores language/currency preferences in Django sessions:

```python
# Set language
request.session['django_language'] = 'de'

# Set currency
request.session['currency'] = 'EUR'

# Get current language
current_lang = request.session.get('django_language', settings.LANGUAGE_CODE)

# Get current currency
current_currency = request.session.get('currency', settings.DEFAULT_CURRENCY)
```

## Price Updates with Currency Changes

Prices are automatically converted using the `data-price` attribute:

```django
<span class="product-price" data-price="{{ product.price }}">
  {{ currency_symbol }}{{ product.price|convert_currency:currency_rate|floatformat:2 }}
</span>
```

JavaScript automatically updates all prices when currency changes:

```javascript
// Automatically handled by navbar.html script
// No additional code needed - just use the data-price attribute
```

## Right-to-Left (RTL) Language Support

For RTL languages (Arabic, Hebrew), the system automatically detects:

```python
from shop.translation_utils import is_language_rtl

if is_language_rtl(current_language):
    # Apply RTL styling
```

In templates:

```django
<html dir="{% if LANGUAGE_BIDI %}rtl{% else %}ltr{% endif %}">
  <!-- content -->
</html>
```

## API Endpoint for JavaScript

Get language/currency data via JSON:

```javascript
fetch('/api/languages/')
  .then(response => response.json())
  .then(data => {
    console.log(data.languages);      // All languages with currencies
    console.log(data.current_language); // Current language
    console.log(data.current_currency); // Current currency
  });
```

Response format:

```json
{
  "languages": [
    {
      "code": "en",
      "name": "English",
      "currency": "USD"
    },
    {
      "code": "de",
      "name": "Deutsch",
      "currency": "EUR"
    }
  ],
  "current_language": "en",
  "current_currency": "USD"
}
```

## Testing the System

### Test Language Switching
```
1. Go to navbar and click language dropdown
2. Select a different language
3. Verify:
   - Page language changes
   - Currency automatically switches
   - Prices update with new currency rates
```

### Test Currency Switching
```
1. Go to navbar and click currency dropdown
2. Select a different currency
3. Verify:
   - Currency changes
   - Language automatically switches
   - Page content changes to match language
```

## Customization

### Change Language-Currency Mapping
Edit `LANGUAGE_CURRENCY_MAPPING` in `nexusmart/settings.py`:

```python
LANGUAGE_CURRENCY_MAPPING = {
    'en': 'GBP',  # Map English to British Pounds instead
    'fr': 'CHF',  # Map French to Swiss Francs
    # ... custom mappings
}
```

### Add New Language
1. Add to `LANGUAGES` in settings.py
2. Add to `LANGUAGE_CURRENCY_MAPPING` in settings.py
3. Run `python manage.py makemessages -l [lang_code]`
4. Translate strings in `.po` files
5. Run `python manage.py compilemessages`

### Add New Currency
Edit `CURRENCIES` in `nexusmart/settings.py`:

```python
CURRENCIES = {
    'BRL': {'symbol': 'R$', 'rate': 4.97, 'name': 'Brazilian Real'},
    # ... add more currencies
}
```

## Troubleshooting

### Translations not showing
1. Ensure `USE_I18N = True` in settings.py
2. Run `python manage.py compilemessages`
3. Clear browser cache
4. Restart Django server

### Language not switching
1. Check that language code exists in `LANGUAGES`
2. Verify `LANGUAGE_CURRENCY_MAPPING` has the language
3. Check middleware order in settings.py
4. Verify session middleware is enabled

### Prices not updating
1. Ensure elements have `data-price` attribute
2. Check that currency rates are correct in `CURRENCIES`
3. Verify CSS class `product-price` is applied
4. Check browser console for JavaScript errors

## File Structure

```
nexusmart/
├── locale/                           # Translation files (auto-generated)
│   ├── de/LC_MESSAGES/
│   │   ├── django.po
│   │   └── django.mo
│   ├── zh/LC_MESSAGES/
│   │   ├── django.po
│   │   └── django.mo
│   └── ... (other languages)
├── shop/
│   ├── language_views.py             # Language switching views
│   ├── middleware.py                 # Language-currency sync middleware
│   ├── translation_utils.py          # Helper utilities
│   ├── context_processors.py         # Language context processor
│   └── templatetags/
│       └── i18n_filters.py           # Custom translation filters
└── templates/
    ├── navbar.html                   # Updated with language selector
    └── language_selector.html        # Reusable language selector component
```

## Next Steps

1. Create translation files for each language:
   ```bash
   python manage.py makemessages -l de
   python manage.py makemessages -l zh
   python manage.py makemessages -l ja
   ```

2. Translate strings in the `.po` files

3. Compile translations:
   ```bash
   python manage.py compilemessages
   ```

4. Test language/currency switching in production

5. Monitor translation coverage and add missing strings as needed

## Support

For more information on Django i18n, see:
- https://docs.djangoproject.com/en/stable/topics/i18n/
- https://docs.djangoproject.com/en/stable/topics/i18n/translation/

---

**Version**: 1.0  
**Last Updated**: May 4, 2026  
**Status**: Production Ready
