Car*_*elo 0 python markdown jinja2 flask
我正在使用一个 Markdown 编辑器,它被转换为
post_body = markdown(text_from_markdown_editor)
Run Code Online (Sandbox Code Playgroud)
但是当我渲染 html 时,会显示实际的 jinja2 代码
This is a post by {{ post.author }}
Run Code Online (Sandbox Code Playgroud)
而不是实际值。
我最近在不同的地方经常看到这个问题出现,都与 Jinja 和 Django 模板有关。对于模板系统如何工作以及它与渲染为 HTML 并插入到模板中的 Markdown 文本的关系,似乎(一些用户)存在根本性的误解。我\xe2\x80\x99会尝试清楚地解释这一点。请注意,虽然下面的答案适用于大多数模板系统(包括 Jinja 和 Django),但示例使用 Jinja 是为了说明目的(毕竟,原始问题专门询问 Jinja)。只需调整代码以匹配您选择的模板系统的 API,它应该也能正常工作。
\n\n首先,Markdown 不了解模板语法。事实上,Markdown 的历史比 Jinja、Django 或其他各种流行的模板系统都要长。此外,Markdown 语法规则没有提及模板语法。因此,您的模板语法不会简单地通过 Markdown 解析器传递一些包含模板语法的 Markdown 文本来处理。模板语法需要由模板引擎单独处理。例如:
\n\nfrom jinja2 import Environment\n# Set up a new template environment\nenv = Environment()\n# Create template with the markdown source text\ntemplate = env.from_string(text_from_markdown_editor)\n# Render that template. Be sure to pass in the context (post in this instance).\ntemplate_processed_markdown = template.render(post=post)\n# Now pass the Markdown text through the Markdown engine:\npost_body = markdown(template_processed_markdown)\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,上面首先处理模板语法,然后解析 Markdown。换句话说,模板处理的输出仍然是 Markdown 文本,其中标签被替换为适当的值。仅在最后一行,Markdown 文本才会被 Markdown 解析器转换为 HTML。如果您希望颠倒处理顺序,则需要切换代码以首先运行 Markdown 解析器,然后通过模板处理器传递其输出。
\n\n我认为一些混乱来自于人们通过模板系统传递 Markdown 文本。\xe2\x80\x99t 是否应该导致模板语法得到处理?简而言之,不。
\n\n模板系统的核心是一个模板和一个上下文。然后,它在模板中查找各种标签,并用上下文中提供的匹配数据替换这些标签。但是,模板不了解上下文中的数据,也不处理该数据。例如这个模板:
\n\nHello, {{ name }}!\nRun Code Online (Sandbox Code Playgroud)\n\n以及这个上下文:
\n\noutput = template(name=\'John\')\nRun Code Online (Sandbox Code Playgroud)\n\n将产生以下输出:
\n\nHello, John!\nRun Code Online (Sandbox Code Playgroud)\n\n但是,如果上下文是这样的:
\n\noutput = template(name=\'{(some_template_syntax)}\')\nRun Code Online (Sandbox Code Playgroud)\n\n那么输出将是:
\n\nHello, {{some_template_syntax}}!\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,虽然上下文中的数据包含模板语法,但模板不会处理该数据。它只是将其视为一个值并将其按原样插入到模板中的适当位置。这是正常且正确的行为。
\n\n然而,有时,您可能确实需要模板对传递到模板的某些数据进行一些额外的处理。因此,模板系统提供了过滤器。当在上下文中给定一个变量时,过滤器将处理该变量中包含的数据,然后将处理后的数据插入模板中。例如,为了确保上一个示例中的名称大写,模板将如下所示:
\n\nHello, {{ name|capatalize }}!\nRun Code Online (Sandbox Code Playgroud)\n\n传入上下文output = template(name=\'john\')(注意名称是小写),然后我们得到以下输出\xe2\x80\x9d
Hello, John!\nRun Code Online (Sandbox Code Playgroud)\n\n注意,变量中的数据name是通过首字母大写来处理的,这是 Jinja\xe2\x80\x99s 内置的 filter 的功能capitalize。但是,该过滤器不处理模板语法,因此将模板语法传递给该过滤器不会导致模板语法被处理。
相同的概念适用于任何markdown过滤器。这样的过滤器仅将提供的数据解析为 Markdown 文本并返回 HTML 文本,然后将其放入模板中。在这种情况下,不会发生模板语法的处理。事实上,这样做可能会导致可能的安全问题,特别是当 Markdown 文本由不受信任的用户提供时。因此,任何包含模板语法的 Markdown 文本都必须单独处理模板语法。
不过,有一点需要注意。如果您正在编写包含模板语法示例作为代码块的文档(例如此答案的 Markdown 源代码),模板系统将不会知道其中的差异,并且会像不在代码中的任何模板语法一样处理这些标签堵塞。如果首先完成 Markdown 处理,以便将生成的 HTML 传递到模板系统,则该 HTML 仍将在代码块中包含未更改的模板语法,而这些代码块仍将由模板系统处理。这很可能不是这两种情况下所期望的。作为一种解决方法,可以想象创建某种 Markdown 扩展,它将语法处理添加到 Markdown 处理器本身。然而,这样做的机制会根据所使用的 Markdown 处理器的不同而有所不同,并且超出了本问题/答案的范围。
\n| 归档时间: |
|
| 查看次数: |
4930 次 |
| 最近记录: |