我正在使用Markdown编辑器,该编辑器由
post_body = markdown(text_from_markdown_editor)
但是当我渲染html时,会显示实际的jinja2代码
This is a post by {{ post.author }}
而不是实际值。
最近,我一直在各个地方看到这个问题,涉及到Jinja和Django模板。在某些用户中,似乎存在一个基本的误解,即模板系统如何工作以及与Markdown文本(呈现为HTML并插入到模板中)之间的关系。我会尽力解释清楚。请注意,尽管以下答案适用于大多数模板系统(包括Jinja和Django),但示例使用Jinja只是出于说明目的(毕竟,原始问题专门询问有关Jinja的问题)。只需修改代码以使其与您选择的模板系统的API相匹配,它就可以正常工作。
首先,Markdown不了解模板语法。实际上,Markdown比Jinja,Django或其他各种流行的模板系统更长。此外,降价语法规则未提及模板语法。因此,仅通过Markdown解析器传递一些包含模板语法的Markdown文本就不会处理您的模板语法。模板语法需要由模板引擎单独处理。例如:
from jinja2 import Environment # Set up a new template environment env = Environment() # Create template with the markdown source text template = env.from_string(text_from_markdown_editor) # Render that template. Be sure to pass in the context (post in this instance). template_processed_markdown = template.render(post=post) # Now pass the Markdown text through the Markdown engine: post_body = markdown(template_processed_markdown)
请注意,以上内容首先处理模板语法,然后解析Markdown。换句话说,模板处理的输出仍然是Markdown文本,其中标记被适当的值替换。Markdown解析器仅将最后一行的Markdown文本转换为HTML。如果您希望颠倒处理顺序,则需要切换代码以首先运行Markdown解析器,然后将其输出传递给模板处理器。
我认为有些困惑来自人们通过模板系统传递Markdown文本。那不应该引起模板语法的处理吗?简而言之,不。
模板系统的核心是模板和上下文。然后,它在模板中找到各种标签,并将这些标签替换为上下文中提供的匹配数据。但是,模板不了解上下文中的数据,也不处理该数据。例如,此模板:
Hello, {{ name }}!
和这个上下文:
output = template(name='John')
将导致以下输出:
Hello, John!
但是,如果上下文是这样:
output = template(name='{(some_template_syntax)}')
那么输出将是:
Hello, {{some_template_syntax}}!
请注意,尽管上下文中的数据包含模板语法,但模板并未处理该数据。它只是简单地将其视为一个值,然后将其按原样插入模板中的适当位置。这是正常且正确的行为。
但是,有时您可能确实需要模板来对传递给模板的某些数据进行一些额外的处理。因此,模板系统提供了过滤器。当在上下文中给定变量时,过滤器将处理该变量中包含的数据,然后将处理后的数据插入模板中。例如,为了确保我们前面的示例中的名称大写,该模板将如下所示:
Hello, {{ name|capatalize }}!
传递上下文output = template(name='john')(注意名称是小写),然后得到以下输出”
output = template(name='john')
注意,name变量中的数据是通过首字母大写来处理的,这是Jinja内置过滤器的功能capitalize。但是,该过滤器不会处理模板语法,因此将模板语法传递给该过滤器将不会导致处理模板语法。
name
capitalize
相同的概念适用于任何markdown过滤器。这样的过滤器仅将提供的数据解析为Markdown文本,并返回HTML文本,然后将其放入模板中。在这种情况下,不会对模板语法进行处理。实际上,这样做可能会导致可能的安全问题,尤其是当Markdown文本是由不受信任的用户提供时。因此,任何包含模板语法的Markdown文本都必须分别处理模板语法。
markdown
但是,请注意。如果您要编写包含作为模板的模板语法示例作为代码块的文档(例如此答案的Markdown源),则模板系统将不会知道它们之间的区别,并将像处理代码中未包含的任何模板语法一样处理这些标记。块。如果先进行Markdown处理,然后将生成的HTML传递到模板系统,则该HTML仍将在代码块内包含未更改的模板语法,该模板模板仍将对其进行处理。在两种情况下,这极有可能不是所希望的。作为一种解决方法,可以想到创建一种Markdown扩展,该扩展将在Markdown处理器本身中添加语法处理。然而,