Flask-Babel 使用示例

发布于:2025-06-06 ⋅ 阅读:(23) ⋅ 点赞:(0)

下面创建一个简单的 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)

# English translations for PROJECT.
# Copyright (C) 2025 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-06-05 22:01+0800\n"
"PO-Revision-Date: 2025-06-05 22:02+0800\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"

#: templates/base.html:6 templates/index.html:3
msgid "Flask Babel Example"
msgstr "Flask Babel Example"

#: templates/base.html:18
msgid "Flask Babel"
msgstr "Flask Babel"

#: templates/index.html:3
msgid "Home"
msgstr "Home"

#: templates/index.html:7
msgid "Welcome to Flask Babel Example"
msgstr "Welcome to Flask Babel Example"

#: templates/index.html:8
msgid "This is a simple demonstration of Flask-Babel for internationalization."
msgstr "This is a simple demonstration of Flask-Babel for internationalization."

#: templates/index.html:10
msgid "Current language"
msgstr "Current language"

#: templates/index.html:11
msgid "Current time"
msgstr "Current time"

#: templates/index.html:12
#, python-format
msgid "Sample translated text with parameters: Hello, %(name)s!"
msgstr "Sample translated text with parameters: Hello, %(name)s!"

#: templates/index.html:14
msgid "Features demonstrated:"
msgstr "Features demonstrated:"

#: templates/index.html:16
msgid "Text translation with gettext"
msgstr "Text translation with gettext"

#: templates/index.html:17
msgid "Language switching"
msgstr "Language switching"

#: templates/index.html:18
msgid "Date and time localization"
msgstr "Date and time localization"

#: templates/index.html:19
msgid "Parameter substitution in translations"
msgstr "Parameter substitution in translations"

中文翻译文件 (translations/zh/LC_MESSAGES/messages.po)

# Chinese translations for PROJECT.
# Copyright (C) 2025 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-06-05 22:01+0800\n"
"PO-Revision-Date: 2025-06-05 22:02+0800\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: zh\n"
"Language-Team: zh <LL@li.org>\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"

#: templates/base.html:6 templates/index.html:3
msgid "Flask Babel Example"
msgstr "Flask Babel 示例"

#: templates/base.html:18
msgid "Flask Babel"
msgstr "Flask Babel"

#: templates/index.html:3
msgid "Home"
msgstr "首页"

#: templates/index.html:7
msgid "Welcome to Flask Babel Example"
msgstr "欢迎使用 Flask Babel 示例"

#: templates/index.html:8
msgid "This is a simple demonstration of Flask-Babel for internationalization."
msgstr "这是一个简单的 Flask-Babel 国际化演示。"

#: templates/index.html:10
msgid "Current language"
msgstr "当前语言"

#: templates/index.html:11
msgid "Current time"
msgstr "当前时间"

#: templates/index.html:12
#, python-format
msgid "Sample translated text with parameters: Hello, %(name)s!"
msgstr "带参数的示例翻译文本:你好,%(name)s!"

#: templates/index.html:14
msgid "Features demonstrated:"
msgstr "演示的功能:"

#: templates/index.html:16
msgid "Text translation with gettext"
msgstr "使用 gettext 进行文本翻译"

#: templates/index.html:17
msgid "Language switching"
msgstr "语言切换"

#: templates/index.html:18
msgid "Date and time localization"
msgstr "日期和时间本地化"

#: templates/index.html:19
msgid "Parameter substitution in translations"
msgstr "翻译中的参数替换"

编辑完翻译文件后,需要编译它们:

pybabel compile -d translations

运行应用

uv run app.py

应用将在 http://127.0.0.1:5000/ 上运行。
在这里插入图片描述
切换英文
在这里插入图片描述

功能说明

  1. 多语言支持:应用支持英文和中文两种语言。
  2. 语言切换:用户可以通过点击页面顶部的语言按钮切换语言。
  3. 文本翻译:使用 gettext 函数(在模板中使用 _() 简写)来标记需要翻译的文本。
  4. 日期和时间本地化:使用 format_datetime 函数根据当前语言环境格式化日期和时间。
  5. 参数替换:在翻译文本中使用参数,例如 _('Hello, %(name)s!', name='Flask')

网站公告

今日签到

点亮在社区的每一天
去签到