命令行增强
你可能会同意我的看法,pybabel 命令有点长,难以记忆。 我将利用这个机会向你展示如何创建与 flask
命令集成的自定义命令。 到目前为止,你已经看到我使用 Flask-Migrate 扩展提供的 flask run
、 flask shell
和几个 flask db
子命令。 将应用特定的命令添加到 flask
实际上也很容易。 所以我现在要做的就是创建一些简单的命令,并用这个应用特有的参数触发 pybabel
命令。 我要添加的命令是:
flask translate init LANG
用于添加新语言flask translate update
用于更新所有语言存储库flask translate compile
用于编译所有语言存储库
babel export
步骤不会设置为一个命令,因为生成 messages.pot 文件始终是运行 init
或 update
命令的先决条件,因此这些命令的执行将会生成翻译模板文件作为临时文件。
Flask 依赖 Click 进行所有命令行操作。 像 translate
这样的命令是几个子命令的根,它们是通过 app.cli.group()
装饰器创建的。 我将把这些命令放在一个名为 app/cli.py 的新模块中:
app/cli.py :翻译命令组
from app import app
@app.cli.group()
def translate():
"""Translation and localization commands."""
pass
该命令的名称来自被装饰函数的名称,并且帮助消息来自文档字符串。 由于这是一个父命令,它的存在只为子命令提供基础,函数本身不需要执行任何操作。
update
和 compile
很容易实现,因为它们没有任何参数:
app/cli.py :更新子命令和编译子命令:
import os
# ...
@translate.command()
def update():
"""Update all languages."""
if os.system('pybabel extract -F babel.cfg -k _l -o messages.pot .'):
raise RuntimeError('extract command failed')
if os.system('pybabel update -i messages.pot -d app/translations'):
raise RuntimeError('update command failed')
os.remove('messages.pot')
@translate.command()
def compile():
"""Compile all languages."""
if os.system('pybabel compile -d app/translations'):
raise RuntimeError('compile command failed')
请注意,这些函数的装饰器是如何从 translate
父函数派生的。 这似乎令人困惑,因为 translate()
是一个函数,但它是 Click 构建命令组的标准方式。 与 translate()
函数相同,这些函数的文档字符串在 --help
输出中用作帮助消息。
你可以看到,对于所有命令,运行它们并确保返回值为零(这意味着命令没有返回任何错误)。 如果命令错误,那么我会引发一个 RuntimeError
,这会导致脚本停止。 update()
函数在同一个命令中结合了 extract
和 update
步骤,如果一切都成功的话,它会在更新完成后删除 messages.pot 文件,因为当再次需要这个文件时,可以很容易地重新生成 。
init
命令将新的语言代码作为参数。 这是其执行流程:
app/cli.py :Init 子命令。
import click
@translate.command()
@click.argument('lang')
def init(lang):
"""Initialize a new language."""
if os.system('pybabel extract -F babel.cfg -k _l -o messages.pot .'):
raise RuntimeError('extract command failed')
if os.system(
'pybabel init -i messages.pot -d app/translations -l ' + lang):
raise RuntimeError('init command failed')
os.remove('messages.pot')
该命令使用 @click.argument
装饰器来定义语言代码。 Click 将命令中提供的值作为参数传递给处理函数,然后将该参数并入到 init
命令中。
启用这些命令的最后一步是导入它们,以便注册命令。 我决定在顶级目录的 microblog.py 文件中执行此操作:
microblog.py :注册命令。
from app import cli
这里我唯一需要做的就是导入新的 cli.py 模块,不需要做任何事情,因为导入操作会导致命令装饰器运行并注册命令。
此时,运行 flask --help
将列出 translate
命令作为选项。 flask translate --help
将显示我定义的三个子命令:
(venv) $ flask translate --help
Usage: flask translate [OPTIONS] COMMAND [ARGS]...
Translation and localization commands.
Options:
--help Show this message and exit.
Commands:
compile Compile all languages.
init Initialize a new language.
update Update all languages.
所以现在工作流程就简便多了,而且不需要记住长而复杂的命令。 要添加新的语言,请使用:
(venv) $ flask translate init <language-code>
在更改 _()
和 _l()
语言标记后更新所有语言:
(venv) $ flask translate update
在更新翻译文件后编译所有语言:
(venv) $ flask translate compile
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论