如何在 wagtail cms 字段中包含上下文变量?
How to include context variable in a wagtail cms field?
我正在寻找一种方法来呈现一个变量,该变量将在将呈现 cms 页面的页面的上下文中可用。
例如:
我在上下文中有登录用户,我也有他在网站上进行的最后一笔交易。
我希望 Wagtail 的富文本字段中的文本是这样的,以便营销团队可以调整副本。
Hello ||firstname|| thanks for your purchase. ||productname|| will be
shipped to you soon. The expected delivery date is
||expected_delivery_date||
为了减少混淆,我用双管道替换了双括号,以表明模板系统不需要是那些模板的 django 模板。简单的模板就足够了,也许使用 https://docs.python.org/3.4/library/string.html#template-strings
我想我可以通过这样做来实现:
- 一个包含富文本字段块的流字段和一个带有他们可以使用的可能上下文变量的自定义块
- 一个自定义呈现函数,可以使用上下文值对富文本块中的合并标签进行正则表达式和替换
- 为简单的模板创建一个新过滤器。例如:{{ page.body|richtext|simpletemplate }}
是否有任何更明显的方法或开箱即用的方法来在富文本字段中进行模板制作?
为每个插入的上下文变量使用单独的流域块会很笨拙。您必须覆盖将元素包装在 div
标记中的默认呈现。但是我喜欢它对编辑来说更简单。
我以前做过类似自定义呈现的事情,但使用简单的 TextFields 来格式化特价代码消息。 Wagtail 编辑得到以下 help_text
说明:
valid_placeholders = ['offer_code', 'month_price']
template_text = models.TextField(
_('text'),
help_text="Valid placeholder values are: {all_valid}. Write as {{{example}}}".format(
all_valid=", ".join(valid_placeholders),
example=valid_placeholders[0],
)
)
呈现为 有效的占位符值为:offer_code、month_price。写成 {{offer_code}}.
然后在视图中:
template_keys = [i[1] for i in Formatter().parse(template_text)]
...并从那里继续渲染。请记住也要使用上述 Formatter().parse()
函数适当地验证该字段。
我使用了 Django 的模板格式化而不是 Python 的 string.format() 因为它默默地失败了,但如果充分清理你可以使用 string.format()。
自定义模板过滤器对我来说最简单,所以我会从这种方法开始,如果我 运行 遇到障碍,我会切换到自定义渲染函数。
我找到了一种更简单的方法。我希望我的编辑能够为单个用户创建具有动态定制的页面。有了这个,我的编辑们实际上能够将模板变量作为 {{ var }} 放入任何类型的内容块中,就像 Django 模板语言一样工作。对于我的用例,我允许我的编辑在 CMS 中创建电子邮件内容,然后将其提取以发送电子邮件:
这是要调用的函数:
def re_render_html_template(email_body, context):
"""
This function takes already rendered HTML anbd re-renders it as a template
this is necessary because variables added via the CMS are not caught by the
first rendering because the first rendering is rendering the containing block,
so instead they are rendered as plaintext in content the first render, e.g., {{ var }}
Example:
input: <p>Hey {{ user_account.first_name }}, welcome!</p>
output: <p>Hey Brett, welcome!</p>
@param email_body: html string
@type email_body: str
@param context: context dictionary
@type context: dict
@return: html string
@rtype: str
"""
from django.template import Context
from django.template import Template
template = Template(email_body)
context = Context(context)
email_body = template.render(context)
return email_body
然后我这样称呼它:
email_body = render_to_string(template, context)
# need to re-render to substitute tags added via CMS
email_body = re_render_html_template(email_body, context)
我正在寻找一种方法来呈现一个变量,该变量将在将呈现 cms 页面的页面的上下文中可用。
例如: 我在上下文中有登录用户,我也有他在网站上进行的最后一笔交易。
我希望 Wagtail 的富文本字段中的文本是这样的,以便营销团队可以调整副本。
Hello ||firstname|| thanks for your purchase. ||productname|| will be shipped to you soon. The expected delivery date is ||expected_delivery_date||
为了减少混淆,我用双管道替换了双括号,以表明模板系统不需要是那些模板的 django 模板。简单的模板就足够了,也许使用 https://docs.python.org/3.4/library/string.html#template-strings 我想我可以通过这样做来实现:
- 一个包含富文本字段块的流字段和一个带有他们可以使用的可能上下文变量的自定义块
- 一个自定义呈现函数,可以使用上下文值对富文本块中的合并标签进行正则表达式和替换
- 为简单的模板创建一个新过滤器。例如:{{ page.body|richtext|simpletemplate }}
是否有任何更明显的方法或开箱即用的方法来在富文本字段中进行模板制作?
为每个插入的上下文变量使用单独的流域块会很笨拙。您必须覆盖将元素包装在 div
标记中的默认呈现。但是我喜欢它对编辑来说更简单。
我以前做过类似自定义呈现的事情,但使用简单的 TextFields 来格式化特价代码消息。 Wagtail 编辑得到以下 help_text
说明:
valid_placeholders = ['offer_code', 'month_price']
template_text = models.TextField(
_('text'),
help_text="Valid placeholder values are: {all_valid}. Write as {{{example}}}".format(
all_valid=", ".join(valid_placeholders),
example=valid_placeholders[0],
)
)
呈现为 有效的占位符值为:offer_code、month_price。写成 {{offer_code}}.
然后在视图中:
template_keys = [i[1] for i in Formatter().parse(template_text)]
...并从那里继续渲染。请记住也要使用上述 Formatter().parse()
函数适当地验证该字段。
我使用了 Django 的模板格式化而不是 Python 的 string.format() 因为它默默地失败了,但如果充分清理你可以使用 string.format()。
自定义模板过滤器对我来说最简单,所以我会从这种方法开始,如果我 运行 遇到障碍,我会切换到自定义渲染函数。
我找到了一种更简单的方法。我希望我的编辑能够为单个用户创建具有动态定制的页面。有了这个,我的编辑们实际上能够将模板变量作为 {{ var }} 放入任何类型的内容块中,就像 Django 模板语言一样工作。对于我的用例,我允许我的编辑在 CMS 中创建电子邮件内容,然后将其提取以发送电子邮件:
这是要调用的函数:
def re_render_html_template(email_body, context):
"""
This function takes already rendered HTML anbd re-renders it as a template
this is necessary because variables added via the CMS are not caught by the
first rendering because the first rendering is rendering the containing block,
so instead they are rendered as plaintext in content the first render, e.g., {{ var }}
Example:
input: <p>Hey {{ user_account.first_name }}, welcome!</p>
output: <p>Hey Brett, welcome!</p>
@param email_body: html string
@type email_body: str
@param context: context dictionary
@type context: dict
@return: html string
@rtype: str
"""
from django.template import Context
from django.template import Template
template = Template(email_body)
context = Context(context)
email_body = template.render(context)
return email_body
然后我这样称呼它:
email_body = render_to_string(template, context)
# need to re-render to substitute tags added via CMS
email_body = re_render_html_template(email_body, context)