为Copier提供的特殊Jinja2扩展,允许使用相对于模板根的文件路径来加载扩展,而不是Python点路径。
项目描述
Copier Templates Extensions
为Copier提供的特殊Jinja2扩展,允许使用相对于模板根的文件路径来加载扩展,而不是Python点路径。
安装
使用 pip
pip install copier-templates-extensions
使用 pipx
pip install --user pipx
pipx install copier
pipx inject copier copier-templates-extensions
使用方法
在模板配置中,首先添加我们的加载器扩展,然后添加使用相对文件路径的模板扩展,并在冒号后添加类名
_jinja_extensions:
- copier_templates_extensions.TemplateExtensionLoader
- extensions/context.py:ContextUpdater
- extensions/slugify.py:SlugifyExtension
在这个例子中,你应该在模板根目录下有一个名为 extensions
的目录,包含两个模块: context.py
和 slugify.py
。
📁 template_root
├── 📄 abc.txt.jinja
├── 📄 copier.yml
└── 📁 extensions
├── 📄 context.py
└── 📄 slugify.py
请参阅 上下文钩子扩展 了解如何编写 ContextUpdater
类。
SlugifyExtension
类可以写成这样
import re
import unicodedata
from jinja2.ext import Extension
# taken from Django
# https://github.com/django/django/blob/main/django/utils/text.py
def slugify(value, allow_unicode=False):
"""
Convert to ASCII if 'allow_unicode' is False. Convert spaces or repeated
dashes to single dashes. Remove characters that aren't alphanumerics,
underscores, or hyphens. Convert to lowercase. Also strip leading and
trailing whitespace, dashes, and underscores.
"""
value = str(value)
if allow_unicode:
value = unicodedata.normalize('NFKC', value)
else:
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii')
value = re.sub(r'[^\w\s-]', '', value.lower())
return re.sub(r'[-\s]+', '-', value).strip('-_')
class SlugifyExtension(Extension):
def __init__(self, environment):
super().__init__(environment)
environment.filters["slugify"] = slugify
上下文钩子扩展
此包还提供了一个方便的扩展类,允许模板编写者更新用于渲染模板的上下文,以添加、修改或删除上下文中的项。
在你的相对路径扩展模块之一中,创建一个继承自 ContextHook
的类,并重写其 hook
方法
from copier_templates_extensions import ContextHook
class ContextUpdater(ContextHook):
def hook(self, context):
new_context = {}
new_context["say"] = "hello " + context["name"]
return new_context
使用上述示例,您的上下文将被方法返回的 new_context
更新。如果您希望就地修改上下文,例如从其中 删除 项目,将 update
类属性设置为 False
from copier_templates_extensions import ContextHook
class ContextUpdater(ContextHook):
update = False
def hook(self, context):
context["say"] = "hello " + context["name"]
del context["name"]
在您的 Jinja 模板中,您现在可以直接访问 {{ say }}
变量。
这对于不想向用户提出太多问题,而是从他们的答案中推断一些值的模板项目来说非常有用。
考虑以下示例:您询问您的用户他们是否想生成 CLI 应用程序或 Web API。根据他们的答案,主 Python 模块应命名为 cli.py
或 app.py
。
没有上下文钩子,您需要在某处编写 Jinja 宏,或在 Jinja 中直接更新上下文,并导入此文件(仍在使用 Jinja)在模块的文件名中
{# using macros #}
{%- macro module_name() %}
{%- if project_type == "webapi" %}app{% else %}cli{% endif %}
{%- endmacro %}
{# or enhancing the context #}
{#- Initiate context with a copy of Copier answers -#}
{%- set ctx = _copier_answers.copy() -%}
{#- Populate our new variables -#}
{%- set _ = ctx.update({"module_name": ("app" if project_type == "webapi" else "cli") -%}
📁 template_root
├── 📄 copier.yml
├── 📄 macros # the macros file
├── 📄 context # the context file
├── 📁 extensions
│ └── 📄 slugify.py
└── 📁 {{project_name|slugify}}
│
│ # using the macros
├── 📄 {% import 'macros' as macros with context %}{{macros.module_name()}}.py.jinja
│
│ # or using the enhanced context
└── 📄 {% from 'context' import ctx with context %}{{ctx.module_name}}.py.jinja
如您所见,两种形式都很难写
- 宏或
context
只能放在根目录,因为文件名中不允许有斜杠/
- 您必须在模板文件名中使用空格和单引号(双引号不是有效的文件名字符,在 Windows 上),这并不干净
- 文件名非常长
使用我们的上下文钩子可以使它变得非常简单和干净!
from copier_templates_extensions import ContextHook
class ContextUpdater(ContextHook):
def hook(self, context):
return {"module_name": "app" if context["project_type"] == "webapi" else "cli"}
📁 template_root
├── 📄 copier.yml
├── 📁 extensions
│ ├── 📄 slugify.py
│ └── 📄 context.py
└── 📁 {{project_name|slugify}}
└── 📄 {{module_name}}.py.jinja
它是如何工作的?
注意丑陋的技巧!当加载特殊的 loader 扩展时,负责使用点路径(字符串)导入 Python 对象的函数在 jinja.environment
模块中被修补,在那里它用于加载扩展。修补后的版本增加了使用相对文件路径加载扩展的支持。Jinja 环境的文件系统加载器和其 searchpaths
属性用于查找模板的本地副本并确定要加载的扩展的绝对路径。
项目详情
下载文件
为您的平台下载文件。如果您不确定选择哪一个,请了解更多关于 安装包 的信息。
源分发
构建分发
哈希 for copier_templates_extensions-0.3.0-py3-none-any.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 733e709536e03768b1201c79525534d7fd153932cf764492a0396692e513f244 |
|
MD5 | 068450be6a57ff5d140a200ce4e70224 |
|
BLAKE2b-256 | 03937ebfcbe54410f2d43c8bb8bda1910f7d921b2d5efc52289718969ab0a63d |