下面創建一個簡單的 Flask-Babel 示例,展示如何在 Flask 應用中實現國際化和本地化功能。這個示例將包括多語言支持(中文和英文)、語言切換功能以及翻譯文本的使用。
項目結構
我們將創建以下文件結構:
1. 首先,創建 requirements.txt 文件
flask==2.3.3
flask-babel==3.1.0
項目構建:
2. 創建配置文件
import osclass Config:# 設置密鑰SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-key-should-be-changed'# Babel 配置LANGUAGES = ['en', 'zh']BABEL_DEFAULT_LOCALE = 'en'BABEL_DEFAULT_TIMEZONE = 'UTC'
3. 創建 Babel 配置文件
[python: **.py]
[jinja2: **/templates/**.html]
4. 創建 HTML 模板
基礎模板
<!DOCTYPE html>
<html lang="{{ g.locale }}">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>{% block title %}{{ _('Flask Babel Example') }}{% endblock %}</title><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"><style>body { padding-top: 20px; }.content { margin-top: 20px; }.language-selector { margin-top: 10px; }</style>
</head>
<body><div class="container"><nav class="navbar navbar-expand-lg navbar-light bg-light"><div class="container-fluid"><a class="navbar-brand" href="{{ url_for('index') }}">{{ _('Flask Babel') }}</a><div class="language-selector"><a href="{{ url_for('set_locale', locale='en') }}" class="btn btn-sm {% if g.locale == 'en' %}btn-primary{% else %}btn-outline-primary{% endif %}">English</a><a href="{{ url_for('set_locale', locale='zh') }}" class="btn btn-sm {% if g.locale == 'zh' %}btn-primary{% else %}btn-outline-primary{% endif %}">中文</a></div></div></nav><div class="content">{% block content %}{% endblock %}</div></div><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
首頁模板
{% extends "base.html" %}{% block title %}{{ _('Home') }} - {{ _('Flask Babel Example') }}{% endblock %}{% block content %}
<div class="jumbotron"><h1 class="display-4">{{ _('Welcome to Flask Babel Example') }}</h1><p class="lead">{{ _('This is a simple demonstration of Flask-Babel for internationalization.') }}</p><hr class="my-4"><p>{{ _('Current language') }}: <strong>{{ g.locale }}</strong></p><p>{{ _('Current time') }}: {{ moment }}</p><p>{{ _('Sample translated text with parameters: Hello, %(name)s!', name='Flask') }}</p><h3>{{ _('Features demonstrated:') }}</h3><ul><li>{{ _('Text translation with gettext') }}</li><li>{{ _('Language switching') }}</li><li>{{ _('Date and time localization') }}</li><li>{{ _('Parameter substitution in translations') }}</li></ul>
</div>
{% endblock %}
5. 創建主應用文件
from flask import Flask, render_template, request, g, session, redirect, url_for
from flask_babel import Babel, gettext, format_datetime
from datetime import datetime
import os
from config import Configapp = Flask(__name__)
app.config.from_object(Config)# 定義選擇器函數
def get_locale():# 如果用戶已經選擇了語言,則使用用戶選擇的語言if 'locale' in session:return session['locale']# 否則,嘗試從請求頭中獲取最佳匹配的語言return request.accept_languages.best_match(app.config['LANGUAGES'])def get_timezone():# 這里可以根據用戶設置返回不同的時區return app.config['BABEL_DEFAULT_TIMEZONE']# 初始化 Babel(使用新版本 API)
babel = Babel(app, locale_selector=get_locale, timezone_selector=get_timezone)@app.before_request
def before_request():g.locale = get_locale()@app.route('/')
def index():# 獲取當前時間并格式化moment = format_datetime(datetime.utcnow())return render_template('index.html', moment=moment)@app.route('/set_locale/<locale>')
def set_locale(locale):# 檢查是否是支持的語言if locale in app.config['LANGUAGES']:session['locale'] = localereturn redirect(url_for('index'))if __name__ == '__main__':# 確保 translations 目錄存在if not os.path.exists('translations'):os.makedirs('translations')app.run(debug=True)
6. 創建翻譯文件
首先,我們需要提取需要翻譯的文本:
pybabel extract -F babel.cfg -o messages.pot .
然后,為每種語言創建翻譯文件:
# 創建英文翻譯文件
pybabel init -i messages.pot -d translations -l en# 創建中文翻譯文件
pybabel init -i messages.pot -d translations -l zh
編輯翻譯文件:
英文翻譯文件 (translations/en/LC_MESSAGES/messages.po)
中文翻譯文件 (translations/zh/LC_MESSAGES/messages.po)
編輯完翻譯文件后,需要編譯它們:
pybabel compile -d translations
運行應用
uv run app.py
應用將在 http://127.0.0.1:5000/ 上運行。
切換英文
功能說明
- 多語言支持:應用支持英文和中文兩種語言。
- 語言切換:用戶可以通過點擊頁面頂部的語言按鈕切換語言。
- 文本翻譯:使用
gettext
函數(在模板中使用_()
簡寫)來標記需要翻譯的文本。 - 日期和時間本地化:使用
format_datetime
函數根據當前語言環境格式化日期和時間。 - 參數替換:在翻譯文本中使用參數,例如
_('Hello, %(name)s!', name='Flask')
。