跳转到主要内容

用于抽象模板引擎并提供通用API的库

项目描述

关于

[Latest Version] [Python versions] [Github Actions: Test status] [Azure Pipelines Status] [Coverage Status] [Code Health]

这是一个Python库,作为各种Python模板引擎和渲染库的抽象层,并提供一些非常简单且易于理解的API来渲染模板。

还提供了一个名为anytemplate_cli的CLI工具,用于渲染用这些模板语言编写的模板。

目前支持以下模板引擎

名称

备注

string.Template

始终可用,因为它包含在Python标准库中。

jinja2

将给予最高优先级,如果找到,则成为默认值

mako

Cheetah

需要Cheetah3才能在Python 3.x中使用

pystache

功能

  • 为各种模板引擎提供非常简单且统一的API

    • anytemplate.renders() 用于渲染给定的模板字符串

    • anytemplate.render() 用于渲染给定的模板文件

  • 支持处理模板引擎特定选项

    • anytemplate.render{s,} 允许传递特定于每个模板渲染函数的选项参数

    • anytemplate.find_engine() 返回一个‘engine’对象,允许通过传递选项参数进行更精细的模板引擎特定定制

  • 提供名为 anytemplate_cli 的 CLI 工具,用于在命令行中处理模板

API 使用

API 示例

调用 ‘anytemplate.renders’ 来渲染给定的模板字符串,如下所示

result = anytemplate.renders("{{ x|default('aaa') }}", {'x': 'bbb'},
                             at_engine="jinja2")

第一个参数是模板字符串本身。第二个参数是一个字典或类似字典的对象,通常称为“上下文”对象,用于实例化模板。第三个参数,关键字参数‘at_engine’,用于找到渲染给定模板字符串的适当模板引擎。这个关键字参数是必要的,因为仅通过给定的模板字符串本身来检测正确的模板引擎是非常困难且几乎不可能的。

如果省略‘at_engine’,则选择最高优先级的模板引擎。anytemplate 自动启用仅有的模板引擎和库,因此该引擎将与您的环境相对应。例如,在我的开发环境中,‘jinja2’是最高优先级的引擎,并且已安装所有支持的模板引擎和库。

In [6]: import anytemplate

In [7]: anytemplate.find_engine()   # It will return the highest priority one.
Out[7]: anytemplate.engines.jinja2.Engine

In [8]: anytemplate.find_engine().name()
Out[8]: 'jinja2'

也可以使用关键字参数选择特定于模板引擎的选项参数,如下所示

# 'strict_undefined' is a parameter for mako.template.Template.__init__().
result = anytemplate.renders("${x}", {'x': 'bbb'},
                             at_engine="mako",
                             strict_undefined=False)

有关‘anytemplate.renders’的通用选项参数列表等详细信息,请参阅其帮助信息

In [20]: help(anytemplate.renders)
Help on function renders in module anytemplate.api:

renders(template_content, context=None, at_paths=None, at_encoding='UTF-8', at_engine=None, at_ask_missing=False, at_cls_args=None, **kwargs)
    Compile and render given template content and return the result string.

    :param template_content: Template content
    :param context: A dict or dict-like object to instantiate given
        template file
    :param at_paths: Template search paths
    :param at_encoding: Template encoding
    :param at_engine: Specify the name of template engine to use explicitly or
        None to find it automatically anyhow.
    :param at_cls_args: Arguments passed to instantiate template engine class
    :param kwargs: Keyword arguments passed to the template engine to
        render templates with specific features enabled.

    :return: Rendered string

In [21]:

调用‘anytemplate.render’来渲染给定的模板文件,如下所示

result1 = anytemplate.render("/path/to/a_template.tmpl", {'x': 'bbb'},
                             at_engine="mako")

参数与前面的示例类似,除了第一个参数

第一个参数不是模板字符串,而是模板文件的路径,可以是相对路径或绝对路径,也可以是带模板搜索路径(at_paths=[PATH_0, PATH_1, …])的基本名。

某些模块封装了 anytemplate 中的实际模板引擎,并支持通过模板文件的文件扩展名自动检测引擎。例如,Jinja2 模板文件预期文件扩展名为‘.j2’或‘.jinja2’。因此,我使这些文件自动检测为 Jinja2 模板文件,您不需要通过‘at_engine’参数指定引擎,如下所示

# 'jinaj2' template engine is automatically choosen because the extension
# of template file is '.j2'.
result = anytemplate.render("/path/to/a_template.j2", {'x': 'bbb'})

有关‘anytemplate.render’的选项参数列表等详细信息,请参阅其帮助信息

In [21]: help(anytemplate.render)
Help on function render in module anytemplate.api:

render(filepath, context=None, at_paths=None, at_encoding='UTF-8', at_engine=None, at_ask_missing=False, at_cls_args=None, **kwargs)
    Compile and render given template file and return the result string.

    :param template: Template file path
    :param context: A dict or dict-like object to instantiate given
        template file
    :param at_paths: Template search paths
    :param at_encoding: Template encoding
    :param at_engine: Specify the name of template engine to use explicitly or
        None to find it automatically anyhow.
    :param at_cls_args: Arguments passed to instantiate template engine class
    :param kwargs: Keyword arguments passed to the template engine to
        render templates with specific features enabled.

    :return: Rendered string

In [22]:

CLI 使用

CLI 帮助

ssato@localhost% PYTHONPATH=. python anytemplate/cli.py -h
Usage: anytemplate/cli.py [OPTION ...] TEMPLATE_FILE

Options:
  -h, --help            show this help message and exit
  -T TEMPLATE_PATHS, --template-path=TEMPLATE_PATHS
                        Template search path can be specified multiple times.
                        Note: Dir in which given template exists is always
                        included in the search paths (at the end of the path
                        list) regardless of this option.
  -C CONTEXTS, --context=CONTEXTS
                        Specify file path and optionally its filetype, to
                        provides context data to instantiate templates.  The
                        option argument's format is
                        [type:]<file_name_or_path_or_glob_pattern> ex. -C
                        json:common.json -C ./specific.yaml -C yaml:test.dat,
                        -C yaml:/etc/foo.d/*.conf
  -E ENGINE, --engine=ENGINE
                        Specify template engine name such as 'jinja2'
  -L, --list-engines    List supported template engines in your environment
  -o OUTPUT, --output=OUTPUT
                        Output filename [stdout]
  -v, --verbose         Verbose mode
  -q, --quiet           Quiet mode
ssato@localhost% cat examples/ctx.yml
xs:
  - name: Alice
  - name: Bob
  - name: John

ssato@localhost% cat examples/jinja2.j2
{% include "jinja2-incl.j2" %}
ssato@localhost% cat examples/jinja2-incl.j2
{# jinja2 example: #}
{% for x in xs if x.name -%}
{{ x.name }}
{% endfor %}
ssato@localhost% PYTHONPATH=. python anytemplate/cli.py -E jinja2 \
> -C examples/ctx.yml examples/jinja2.j2

Alice
Bob
John

ssato@localhost%

CLI 特性

支持多个上下文文件定义模板参数

CLI 工具(anytemplate_cli)支持通过 -C|–context 选项加载多个 YAML 或 JSON 或其他上下文文件,以提供模板参数。

如果已安装并可在您的系统上使用,上下文文件的加载和组合将由我的另一个 Python 库 anyconfig(python-anyconfig)处理。

如果您的系统上未找到 anyconfig,则仅支持 JSON 上下文文件格式,由 Python 标准的 json 或 simplejson 库提供支持。

模板搜索路径

模板搜索路径通过 CLI 工具(anytemplate_cli)的 -T|–template-path 选项指定。这对于在模板中使用‘include’指令非常有用;例如,-T .:templates/。

注意:如果没有指定 -T 选项,默认搜索路径将是 [‘.’, templatedir],其中 templatedir 是给定模板文件存在的目录。即使使用了 -T 选项,也会将 templatedir 添加到搜索路径的末尾。

构建 & 安装

如果您是 Fedora 或 Red Hat Enterprise Linux 用户,您可以自己构建和安装 [s]rpm

$ python setup.py srpm && mock dist/python-anytemplate-<ver_dist>.src.rpm

或者

$ python setup.py rpm

或者您可以从我的 copr 仓库中安装预构建的 RPM,https://copr.fedorainfracloud.org/coprs/ssato/python-anyconfig/

# Fedora
$ sudo dnf copr enable ssato/python-anyconfig
$ sudo dnf install -y python-anytemplate   # or python3-anytemplate (python3 version)
# RHEL, CentOS
$ (cd /etc/yum.repos.d; sudo curl -O https://copr.fedorainfracloud.org/coprs/ssato/python-anyconfig/repo/epel-7/ssato-python-anyconfig-epel-7.repo)
$ sudo dnf install -y python-anytemplate   # or python3-anytemplate (python3 version)

否则,尝试通常的构建和/或安装 Python 模块的方式,例如‘pip install git+https://github.com/ssato/python-anytemplate’和‘python setup.py bdist’,等等。

黑客攻击

如何测试

我选择使用tox进行手动测试和CI。例如,尝试运行‘tox [-e py27]’。

待办事项 & 问题

  • 添加模板引擎和特定库选项的描述(doctext):工作中

  • 添加关于anytemplate如何包装每个模板引擎和库的描述(doctext):工作中

  • 完成单元测试

    • 添加每个模板引擎特定选项的测试用例:工作中

  • 稳定公共和私有(内部)API

    • 私有API仍需要大量工作,特别是。每个模板引擎都有自己的概念和设计,我不确定如何抽象它们。

    • 我认为公共API没有重大问题,但它们多少会受到私有API更改的影响;例如,我在考虑弃用关键字参数‘at_cls_args’。

杂项

替代方案

有几个库与此类似

这些看起来功能更丰富,更全面,但我更喜欢一个更轻量级和更薄的包装库以及CLI工具(模板渲染器),因此我创建了anytemplate。

并且

Anytemplate是python-jinja2-cli的后继产品。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解更多关于安装包的信息。

源分发

anytemplate-0.1.8.tar.gz (37.7 kB 查看散列)

上传时间

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面