{% extends "admin/base.html" %} {% block title %}Translation | Admin {% endblock %} {% block content %}

Multilingual content

Translation Center

Manage pages, listings, shared interface text and AI models from one place. English is always the master source.

{% if job %}

Background translation job

{{ job.content_type or '' }} · {{ job.mode or '' }} · {{ job.model or '' }}

{{ job.status|upper }}
{{ job.completed or 0 }}
Completed
{{ job.total_tasks or 0 }}
Needed
{{ job.skipped_existing or 0 }}
Skipped existing
{{ job.failed or 0 }}
Failed
{% if job.current %}

Current: {{ job.current }}

{% endif %}
{% if job.status == 'running' %}
{% elif job.status == 'pausing' %}
Pausing after current translation… {% elif job.status == 'paused' %}
{% endif %} {% if job.failed and job.status not in ('running','pausing','cancelling') %}
{% endif %}
{% if job.errors %}
Recent errors
{{ job.errors|join('\n') }}
{% endif %}

Refresh this page to update progress. Pause waits for the current API call; Stop terminates the worker immediately. Completed translations are kept.

{% endif %} {% if tab in ('listings','pages','faqs') %}

Target languages

{% for language in languages %}{% if language.code != 'en' %} {% endif %}{% endfor %}

Action

Existing translations are excluded before the task list is built, so they do not consume the workload count.

{% set rows = listings if tab == 'listings' else (pages if tab == 'pages' else faqs) %} {% for item in rows %} {% endfor %}
English sourceCoverage
{{ item.title_en if tab != 'faqs' else item.question_en }}
{% if tab == 'listings' %}{{ item.public_stock_number or item.slug }}{% elif tab == 'pages' %}{{ item.slug }}{% else %}FAQ #{{ item.id }}{% endif %}
{% for language in languages %}{% if language.code != 'en' %} {% if tab == 'listings' %}{% set ok = item['title_' ~ language.code] or item['description_html_' ~ language.code] %}{% elif tab == 'pages' %}{% set ok = item['title_' ~ language.code] and item['translation_status_' ~ language.code] not in ('missing','outdated') %}{% else %}{% set ok = item['question_' ~ language.code] and item['answer_' ~ language.code] %}{% endif %} {{ language_display_code(language.code) }} {{ 'OK' if ok else 'Missing' }} {% endif %}{% endfor %}
{% elif tab == 'interface' %}
{% if fallback_report %}

{{ fallback_report|length }} English fallback{{ 's' if fallback_report|length != 1 else '' }} still visible in {{ interface_lang|upper }}

Show exact sources
{% for issue in fallback_report %}{% endfor %}
SourceItemEnglish fallback
{{ issue.type }}{{ issue.item }}{{ issue.detail }}
{% else %}
No English fallbacks detected for {{ interface_lang|upper }} across interface strings, published pages and active FAQs.
{% endif %}

Shared interface and template text

Compact editor for navigation, buttons, headings, forms, status labels and reusable public text. English remains the source.

AI action for {{ interface_lang|upper }}

No interface strings selected for AI translation.

{% for row in interface_rows %} {% else %}{% endfor %}
Key / areaEnglish source{{ interface_lang|upper }} translation
{{ row.translation_key }}
{{ row.en or '' }}
No interface strings match this filter.

Editing {{ interface_lang|upper }} only. Switch language above to edit another language.

{% elif tab == 'models' %}

AI model assignments

OpenAI image editing stays unchanged. These settings only control Fireworks text workloads.

{% for field,label,help in [('translation_model','Translation model','Quality-first for listings, pages and interface content.'),('content_model','Listing/content model','English listing and page generation.'),('chatbot_model','Chatbot model','Fast user-facing responses.')] %} {% endfor %}
{% endif %} {% endblock %}