
Flask i18n: Flask-Babel ile çok dilli bir uygulama geliştirin
gettext temellerinden üretim ortamına dağıtıma kadar Flask uygulamanızı Flask-Babel, PO dosyaları ve otomatik yapay zeka çevirisiyle uluslararasılaştırın.
Flask-Babel'i kurun
Flask-Babel, Flask için standart uluslararasılaştırma uzantısıdır. GNU gettext'i Flask ve Jinja2 şablonlarıyla bütünleştirerek kullanıma hazır çeviri işlevleri, yerel ayar seçimi ve saat dilimi desteği sağlar.
pip install Flask-BabelBabel'i yapılandırın
pybabel'e çevrilebilir dizeleri nerede tarayacağını bildirmek için bir babel.cfg dosyası oluşturun. Ardından her istekte hangi dilin sunulacağını belirleyen bir yerel ayar seçici işleviyle Flask-Babel'i başlatın.
# 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)Dizeleri çeviri için işaretleyin
Kullanıcıya gösterilen her dizeyi Python kodunda gettext(), Jinja2 şablonlarında ise _() ile sarmalayın. Modül yüklenirken tanımlanan ve daha sonra istek sırasında çevrilmesi gereken dizeler (form etiketleri ve yapılandırma gibi) için lazy_gettext() kullanın.
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>İletileri ayıklayın
Kaynak kodunuzu ve şablonlarınızı çevrilebilir dizeler için taramak üzere pybabel extract komutunu çalıştırın. Bu işlem bir .pot (Portable Object Template) dosyası oluşturur. Ardından her hedef dil için katalogları başlatın veya kaynak dizeler değiştiğinde mevcut katalogları güncelleyin.
# 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 translationsPO dosyalarını çevirin
Oluşturulan .po dosyalarını açın ve her msgid için msgstr değerlerini doldurun. PO dosyaları düz metindir; bunları doğrudan düzenleyebilir, Poedit gibi bir PO düzenleyicisi kullanabilir veya çeviriyi yapay zeka araçlarıyla otomatikleştirebilirsiniz.
# 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"Çevirileri derleyin
pybabel compile kullanarak .po dosyalarınızı ikili .mo dosyalarına derleyin. Flask-Babel çalışma zamanında .mo dosyalarını okur; .po dosyalarını doğrudan okuyamaz. Her çeviri güncellemesinden sonra yeniden derlemeniz gerekir.
# 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.Çoğulları ve değişkenleri yönetin
Çoğul biçimine duyarlı dizeler için ngettext() kullanın. Bu işlev tekil biçimi, çoğul biçimi ve sayıyı alır. Babel her dil için doğru çoğul kuralını otomatik olarak kullanır; İngilizcede 2, Rusçada 3, Arapçada 6 ve Japoncada 1 biçim vardır.
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 товаров в вашей корзине"Yerel ayar değiştirme özelliği ekleyin
Kullanıcının seçimini Flask oturumunda saklayan bir dil seçici geliştirin. locale_selector işlevinizi önce oturumu denetleyecek, ardından tarayıcı algılamasına geçecek şekilde güncelleyin.
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>Çevirileri otomatikleştirin
Flask-Babel kurulumunuz tamamlandıktan sonra PO dosyalarınızı yapay zeka kullanarak çevirin. Çevirileri kaynak kodunuzla eş zamanlı tutmak için ayıklama-çeviri-derleme döngüsünü CI/CD işlem hattınızda otomatikleştirin.
# 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 translationsEk özellik: flask-babel-locale-chain ile akıllı yerel ayar yedeklemesi
Flask-Babel, kullanıcının tercih ettiği yerel ayar kullanılamadığında varsayılan olarak doğrudan varsayılan yerel ayara geçer. Yalnızca pt-PT çevirileri bulunan bir pt-BR kullanıcısı Portekizce yerine İngilizce görür. flask-babel-locale-chain, ilişkili yerel ayarların doğal biçimde birbirine geçmesini sağlayan yapılandırılabilir yedekleme zincirleri ekler.
# 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)Çeviri kalitesini otomatikleştirin
Yaygın hatalar
.po dosyasını .mo biçimine derlemeyi unutmak
Modül düzeyinde gettext() kullanmak
Ayıklama sırasında dizelerin atlanması
PO dosyası kodlama hataları
Önerilen dosya yapısı
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/i18n Agent'ı şimdi deneyin
Çeviri dosyanızı buraya bırakın
JSON, YAML, PO, XML, CSV, Markdown, Properties
veya göz atmak için tıklayın
Hedef diller