下面创建一个简单的 Flask-Babel 示例,展示如何在 Flask 应用中实现国际化和本地化功能。这个示例将包括多语言支持(中文和英文)、语言切换功能以及翻译文本的使用。
项目结构
我们将创建以下文件结构:
1. 首先,创建 requirements.txt 文件
flask==2.3.3
flask-babel==3.1.0
项目构建:
2. 创建配置文件
import os
class 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 Config
app = 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'] = locale
return 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')
。