gpt4 book ai didi

python - 如何为 Jinja2 编写 "joiner"扩展?

转载 作者:太空宇宙 更新时间:2023-11-04 11:02:55 27 4
gpt4 key购买 nike

您好,我一直在尝试为 jinja2 创建一个扩展,它将使用分隔符连接多个项目,同时跳过评估为空白的项目(模板片段)。

有几个这样的片段,你永远不会事先知道哪些是非空的,哪些是非空的。

听起来像是一项微不足道的任务,但我真的很难让它在 jinja2 中工作。也许部分原因是 jinja 不允许定义自定义模板节点。

您有什么建议吗?下面是一个将完成解析工作的片段,但它缺少评估部分。

class JoinerExtension(Extension):
"""Template tag that joins non-whitespace (string) items
with a specified separator

Usage syntax:

{% joinitems separator='|' %}
....
{% separator %}
....
{% separator %}
....
{% endjoinitems %}

where value of "separator" within the joinitems tag
can be an expression, not necessarily a sting
"""

tags = set(['joinitems'])

def parse(self, parser):
"""parse function for the
joinitems template tag
"""
lineno = next(parser.stream).lineno

#1) read separator
separator = None
while parser.stream.current.type != 'block_end':
name = parser.stream.expect('name')
if name.value != 'separator':
parser.fail('found %r, "separator" expected' %
name.value, name.lineno,
exc=TemplateAssertionError)

# expressions
if parser.stream.current.type == 'assign':
next(parser.stream)
separator = parser.parse_expression()
else:
var = parser.stream.current
parser.fail('assignment expected after the separator' %
var.value, var.lineno,
exc=TemplateAssertionError)

#2) read the items
items = list()
end_tags = ['name:separator', 'name:endjoinitems']
while True:
item = parser.parse_statements(end_tags)
items.append(item)
if parser.stream.current.test('name:separator'):
next(parser.stream)
else:
next(parser.stream)
break

最佳答案

请问内置joiner类可能工作?这是文档中的一个简单示例。

{% set pipe = joiner("|") %}
{% if categories %} {{ pipe() }}
Categories: {{ categories|join(", ") }}
{% endif %}
{% if author %} {{ pipe() }}
Author: {{ author() }}
{% endif %}
{% if can_edit %} {{ pipe() }}
<a href="?action=edit">Edit</a>
{% endif %}

您提到过无法提前知道哪些片段将是空的;也许可以在“显示”之前将每个片段的值存储在一个变量中,这样您就可以确定哪些片段确实是空的。例如:

{% set pipe = joiner("|") %}
{% set fragment = gen_fragment1() %}
{% if fragment|trim is not "" %}
{{ pipe() }} {{ fragment }}
{% endif %}
...

您甚至可以将上述模式封装在宏中以减少重复:

{% set pipe = joiner("|") %}
{{ print_if_notblank(pipe, gen_fragment1()) }}
{{ print_if_notblank(pipe, gen_fragment2()) }}
...

其中 print_if_notblank 是定义为的宏:

{% macro print_if_notblank(separator, content) %}
{% if content|trim is not "" %}
{{ separator() }} {{ content }}
{% endif %}
{% endmacro %}

关于python - 如何为 Jinja2 编写 "joiner"扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3836770/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com