
Flask i18n: vytvorte viacjazyčnú aplikáciu pomocou Flask-Babel
Od základov gettext po produkčné nasadenie: internacionalizujte svoju aplikáciu Flask pomocou Flask-Babel, súborov PO a automatizovaného prekladu pomocou AI.
Nainštalujte Flask-Babel
Flask-Babel je štandardné rozšírenie na internacionalizáciu pre Flask. Integruje GNU gettext s Flask a šablónami Jinja2 a hneď po inštalácii ponúka prekladové funkcie, výber lokalizácie a podporu časových pásiem.
pip install Flask-BabelNakonfigurujte Babel
Vytvorte súbor babel.cfg, ktorý nástroju pybabel určí, kde má hľadať preložiteľné reťazce, a potom inicializujte Flask-Babel funkciou na výber lokalizácie, ktorá určí jazyk každej požiadavky.
# babel.cfg — tells pybabel where to find translatable strings
[python: **.py]
[jinja2: **/templates/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_from flask import Flask, request
from flask_babel import Babel
app = Flask(__name__)
app.config['BABEL_DEFAULT_LOCALE'] = 'en'
app.config['BABEL_DEFAULT_TIMEZONE'] = 'UTC'
# Directory where translations live (default: "translations")
app.config['BABEL_TRANSLATION_DIRECTORIES'] = 'translations'
def get_locale():
# 1. Check URL parameter or session
# 2. Fall back to browser Accept-Language header
return request.accept_languages.best_match(['en', 'de', 'ja', 'es', 'fr'])
babel = Babel(app, locale_selector=get_locale)Označte reťazce na preklad
Každý reťazec určený používateľom obaľte funkciou gettext() v kóde Python a _() v šablónach Jinja2. lazy_gettext() používajte pre reťazce definované pri načítaní modulu (napríklad štítky formulárov a konfiguráciu), ktoré sa majú preložiť až neskôr pri požiadavke.
from flask_babel import gettext, ngettext, lazy_gettext
# In views — gettext() for immediate translation
@app.route('/')
def index():
flash(gettext('Your profile has been updated.'))
return render_template('index.html',
title=gettext('Home'))
# In forms/config — lazy_gettext() for deferred translation
class LoginForm(FlaskForm):
username = StringField(lazy_gettext('Username'))
password = PasswordField(lazy_gettext('Password'))
submit = SubmitField(lazy_gettext('Sign In')){# In Jinja2 templates, use _() shorthand for gettext #}
<h1>{{ _('Welcome to our app') }}</h1>
<p>{{ _('Hello, %(name)s!', name=user.name) }}</p>
<footer>
{{ _('Copyright %(year)s Example Corp.', year=2026) }}
</footer>Extrahujte správy
Spustením pybabel extract vyhľadajte v zdrojovom kóde a šablónach preložiteľné reťazce. Vytvorí sa súbor .pot (Portable Object Template). Potom inicializujte katalógy pre jednotlivé cieľové jazyky alebo pri zmene zdrojových reťazcov aktualizujte existujúce.
# Extract translatable strings from source code
pybabel extract -F babel.cfg -k lazy_gettext -o messages.pot .
# Initialize a new language (first time only)
pybabel init -i messages.pot -d translations -l de
pybabel init -i messages.pot -d translations -l ja
pybabel init -i messages.pot -d translations -l es
# Update existing catalogs when source strings change
pybabel update -i messages.pot -d translationsPreložte súbory PO
Otvorte vygenerované súbory .po a vyplňte hodnoty msgstr pre každý msgid. Súbory PO sú obyčajný text – môžete ich upravovať priamo, použiť editor PO, ako je Poedit, alebo preklad automatizovať pomocou nástrojov AI.
# translations/de/LC_MESSAGES/messages.po
msgid "Welcome to our app"
msgstr "Willkommen in unserer App"
msgid "Hello, %(name)s!"
msgstr "Hallo, %(name)s!"
msgid "Your profile has been updated."
msgstr "Ihr Profil wurde aktualisiert."
msgid "Username"
msgstr "Benutzername"
msgid "Password"
msgstr "Passwort"
msgid "Sign In"
msgstr "Anmelden"Skompilujte preklady
Pomocou pybabel compile skompilujte svoje súbory .po do binárnych súborov .mo. Flask-Babel za behu číta súbory .mo – súbory .po nedokáže čítať priamo. Po každej aktualizácii prekladov ich musíte znova skompilovať.
# Compile .po files to binary .mo files (required at runtime)
pybabel compile -d translations
# Flask-Babel reads .mo files, not .po files.
# You MUST compile after every translation update.Spracujte tvary množného čísla a premenné
Pre reťazce závislé od množného čísla používajte ngettext(). Prijíma tvar jednotného čísla, tvar množného čísla a počet. Babel automaticky použije správne pravidlo pre každý jazyk – angličtina má 2 tvary, ruština 3, arabčina 6 a japončina 1.
from flask_babel import ngettext
@app.route('/cart')
def cart():
count = len(session.get('cart_items', []))
message = ngettext(
'%(num)d item in your cart', # singular
'%(num)d items in your cart', # plural
count # determines which form
)
return render_template('cart.html', message=message)# English: 2 forms (nplurals=2)
msgid "%(num)d item in your cart"
msgid_plural "%(num)d items in your cart"
msgstr[0] "%(num)d item in your cart"
msgstr[1] "%(num)d items in your cart"
# German: 2 forms (nplurals=2)
msgid "%(num)d item in your cart"
msgid_plural "%(num)d items in your cart"
msgstr[0] "%(num)d Artikel in Ihrem Warenkorb"
msgstr[1] "%(num)d Artikel in Ihrem Warenkorb"
# Japanese: 1 form (nplurals=1)
msgid "%(num)d item in your cart"
msgid_plural "%(num)d items in your cart"
msgstr[0] "カートに%(num)d個の商品があります"
# Russian: 3 forms (nplurals=3)
msgid "%(num)d item in your cart"
msgid_plural "%(num)d items in your cart"
msgstr[0] "%(num)d товар в вашей корзине"
msgstr[1] "%(num)d товара в вашей корзине"
msgstr[2] "%(num)d товаров в вашей корзине"Pridajte prepínanie lokalizácií
Vytvorte výber jazyka, ktorý uloží voľbu používateľa do relácie Flask. Aktualizujte funkciu locale_selector tak, aby najprv skontrolovala reláciu a potom použila rozpoznanie prehliadača.
from flask import session, redirect, url_for, request
from flask_babel import refresh
@app.route('/set-language/<lang>')
def set_language(lang):
session['lang'] = lang
refresh() # Force Flask-Babel to re-read the locale
return redirect(request.referrer or url_for('index'))
# Update get_locale to check session first
def get_locale():
# 1. Explicit user choice (stored in session)
if 'lang' in session:
return session['lang']
# 2. Browser Accept-Language header
return request.accept_languages.best_match(
['en', 'de', 'ja', 'es', 'fr']
){# Language switcher component #}
<nav class="language-switcher">
{% for lang, name in [('en','English'),('de','Deutsch'),
('ja','日本語'),('es','Español'),
('fr','Français')] %}
<a href="{{ url_for('set_language', lang=lang) }}"
class="{{ 'active' if get_locale() == lang }}">
{{ name }}
</a>
{% endfor %}
</nav>Automatizujte preklady
Po dokončení nastavenia Flask-Babel preložte svoje súbory PO pomocou AI. Automatizujte cyklus extrakcie, prekladu a kompilácie vo svojej pipeline CI/CD, aby preklady zostali synchronizované so zdrojovým kódom.
# Translate your PO files with AI directly from your IDE
# or use the CLI in CI/CD:
npx i18n-agent translate translations/de/LC_MESSAGES/messages.po \
--source-lang en --target-lang de
# Bulk translate all languages at once:
npx i18n-agent translate messages.pot --lang de,ja,es,fr
# Then compile:
pybabel compile -d translationsBonus: inteligentná náhradná lokalizácia pomocou flask-babel-locale-chain
Keď preferovaná lokalizácia používateľa nie je dostupná, Flask-Babel predvolene prejde priamo na predvolenú lokalizáciu. Používateľ pt-BR tak pri dostupnosti iba prekladov pt-PT uvidí angličtinu namiesto portugalčiny. flask-babel-locale-chain pridáva konfigurovateľné reťazce náhrad, aby súvisiace lokalizácie prirodzene nadväzovali.
# pip install flask-babel-locale-chain
from flask_babel_locale_chain import LocaleChain
# Define fallback chains: pt-BR falls back to pt before en
locale_chain = LocaleChain({
'pt-BR': ['pt-BR', 'pt', 'en'],
'pt-PT': ['pt-PT', 'pt', 'en'],
'zh-Hant': ['zh-Hant', 'zh-Hans', 'en'],
'en-GB': ['en-GB', 'en', 'en-US'],
})
def get_locale():
requested = request.accept_languages.best_match(
['en', 'pt-BR', 'pt', 'zh-Hant', 'zh-Hans']
)
# Returns the best available locale from the chain
return locale_chain.resolve(requested)Automatizujte kvalitu prekladu
Bežné nástrahy
Zabudnutá kompilácia .po do .mo
Používanie gettext() na úrovni modulu
Extrakcia vynecháva reťazce
Chyby kódovania súborov PO
Odporúčaná štruktúra súborov
my-flask-app/
├── app.py # Flask app with Babel config
├── babel.cfg # Extraction config
├── messages.pot # Template (extracted strings)
├── translations/
│ ├── de/
│ │ └── LC_MESSAGES/
│ │ ├── messages.po # German translations (editable)
│ │ └── messages.mo # Compiled binary (generated)
│ ├── ja/
│ │ └── LC_MESSAGES/
│ │ ├── messages.po
│ │ └── messages.mo
│ └── es/
│ └── LC_MESSAGES/
│ ├── messages.po
│ └── messages.mo
├── templates/
│ ├── base.html
│ ├── index.html
│ └── components/
│ └── language_switcher.html
├── requirements.txt
└── venv/Vyskúšajte i18n Agent teraz
Potiahnite súbor na preklad sem
JSON, YAML, PO, XML, CSV, Markdown, Properties
alebo kliknite a vyberte súbor
Cieľové jazyky