Tornado 如何增加网页操作(下)

书接上回,上一篇我们讲解了 Tornado 模板基础配置、语法以及 XSS 安全相关知识点,本篇继续讲解国际化UI 模块

二、国际化

当前用户的语言区域(无论用户是否登录),在 Handler 中通过self.locale访问;模板内直接使用locale

locale.name可以拿到语言标识,例如en_US。调用Locale.translate()做文本翻译。模板内置全局翻译函数_()

翻译函数两种用法

  1. 普通翻译 根据当前区域直接翻译字符串。
  2. 单复数翻译 第三个参数为数字;等于 1 取第一条字符串,大于 1 取第二条字符串。推荐使用命名占位符%(num)d,翻译的时候占位符顺序可以调整。

国际化模板示例

bash 复制代码
<html>
<head>
    <title>FriendFeed - {{ _("Sign in") }}</title>
</head>
<body>
<form action="{{ request.path }}" method="post">
    <div>{{ _("Username") }} <input type="text" name="username"/></div>
    <div>{{ _("Password") }} <input type="password" name="password"/></div>
    <div><input type="submit" value="{{ _("Sign in") }}"/></div>
    {% module xsrf_form_html() %}
</form>
</body>
</html>

默认读取浏览器请求头Accept‑Language自动识别语言;匹配不到则回退en_US

如果你希望用户可以手动选择语言,可以重写RequestHandler.get_user_locale()

bash 复制代码
class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        user_id = self.get_signed_cookie("user")
        if not user_id:
            return None
        return self.backend.get_user_by_id(user_id)

    def get_user_locale(self):
        if "locale" not in self.current_user.prefs:
            # 使用浏览器Accept‑Language头
            return None
        return self.current_user.prefs["locale"]

如果get_user_locale返回None,系统回退读取Accept‑Language请求头。

tornado.locale模块支持两种翻译文件格式:gettext 标准.mo,以及简单的.csv。 程序启动时调用 tornado.locale.load_translations 或者 tornado.locale.load_gettext_translations加载翻译资源。

调用tornado.locale.get_supported_locales()获取程序支持的语言列表。系统会自动匹配最接近用户的语言。

举例:用户语言es_GT,程序支持es,则最终使用es;完全匹配不到就回退en_US

三、UI 模块

UI 模块用来封装可复用页面组件,跨页面复用 UI 小组件,组件可以附带自己的 CSS、JS。

场景举例:博客项目,博客条目组件需要在首页、详情页两处渲染。可以封装EntryUI模块。新建uimodules.py

1. 注册 UI 模块

在应用配置里面注册 UI 模块文件:

bash 复制代码
from . import uimodules

class HomeHandler(tornado.web.RequestHandler):
    def get(self):
        entries = self.db.query("SELECT * FROM entries ORDER BY date DESC")
        self.render("home.html", entries=entries)

class EntryHandler(tornado.web.RequestHandler):
    def get(self, entry_id):
        entry = self.db.get("SELECT * FROM entries WHERE id = %s", entry_id)
        if not entry:
            raise tornado.web.HTTPError(404)
        self.render("entry.html", entry=entry)

settings = {
    "ui_modules": uimodules,
}

application = tornado.web.Application([
    (r"/", HomeHandler),
    (r"/entry/([0-9]+)", EntryHandler),
],** settings)

2. 模板中调用模块

模板中使用{% module %}调用封装好的组件:

home.html

bash 复制代码
{% for entry in entries %}
    {% module Entry(entry) %}
{% end %}

entry.html

bash 复制代码
{% module Entry(entry) %}

模块类可以重写下面方法来嵌入样式脚本: embedded_cssembedded_javascriptjavascript_filescss_files

特性:不管页面中该模块被调用多少次,CSS、JS 只会输出一次。CSS 放在页面<head>,JS 放在</body>结束标签之前。

纯 HTML 模板作为模块

如果不需要写 Python 逻辑,可以直接把 html 模板文件当做模块。

文件 module-entry.html

bash 复制代码
<div class="entry">
    <h2>{{ entry.title }}</h2>
    <div>{{ entry.content }}</div>
</div>

调用方式:

bash 复制代码
{% module Template("module-entry.html", entry=entry) %}

set_resources函数仅在{% module Template(...) %}模式下可用。

和 {% include %} 的区别

UI模块拥有独立命名空间,只能访问全局模板变量 + 传入的参数,无法继承父模板局部变量 ; 而{% include %}是直接把文件内容原地展开,可以直接使用父模板的局部变量。


系列文章:

  • Tornado 如何增加网页操作(上)
  • Tornado 如何增加网页操作(下)

参考文档: tornado 官方文档

博主持续分享量化、Python、Tornado 开发相关内容,欢迎点赞收藏关注。

相关推荐
zhangzeyuaaa2 小时前
深入理解 pip install .:安装当前目录项目的正确姿势
人工智能·python·pip
Jazz_z2 小时前
纯 Python 环境下 Excel 文件的读取与导入详解
python
Thomas.Sir3 小时前
第38课:TensorFlow|可视化工具TensorBoard全用法【日志写入、指标监控、网络可视化】
人工智能·python·tensorflow
SEO_juper3 小时前
外贸多语言站最隐蔽的流量杀手:hreflang 错了,谷歌把德语页推给美国人(附审计脚本)
开发语言·前端·python·seo·独立站·谷歌优化
Metaphor6923 小时前
快速合并 Word 文档【Python 指南】
python·word
JAVA老架构AI智能化3 小时前
如何高质量分块
人工智能·python
泡海椒4 小时前
告别反射低效:JQuick-Java ASM动态调用链性能优化实战
java·python·性能优化
2601_956319884 小时前
用示例和练习,把量化规则先练清楚
人工智能·python
满怀冰雪4 小时前
25-迁移学习入门:加载预训练模型并微调
人工智能·python·机器学习·迁移学习·paddle