如何在刻录文件中加入flask / jinja2代码? [英] How do you include flask/jinja2 code inside a markdown file?

查看:118
本文介绍了如何在刻录文件中加入flask / jinja2代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是由

  post_body = markdown(text_from_markdown_editor)

但是当我渲染html的时候,显示的是实际的jinja2代码

 这是由{{post.author}} 

而不是实际的价值。

解决方案

我已经看到这个问题最近出现在各个不同的地方,与Jinja和Django模板的关系。在一些用户中,似乎存在一个基本的误解,那就是模板系统是如何工作的,以及如何将Markdown文本呈现给HTML并插入到模板中。我会尽力解释清楚。请注意,虽然下面的答案适用于大多数模板系统(包括Jinja和Django),但这些例子使用Jinja作为说明目的(毕竟,原始问题特别提到了Jinja)。简单地调整代码以匹配您所选择的模板系统的API,并且它也可以正常工作。首先,Markdown没有模板语法的知识。事实上,Markdown比Jinja,Django或其他各种流行的模板系统都要长。此外, Markdown语法规则没有提到模板语法。因此,您的模板语法将不会简单地通过Markdown解析器传递一些包含模板语法的Markdown文本来处理。模板语法需要由模板引擎单独处理。例如:

  from jinja2 import Environment 
#设置一个新的模板环境
env = Environment( )
#使用降价源文本创建模板
template = env.from_string(text_from_markdown_editor)
#渲染该模板。一定要在上下文中传递(在这个例子中发布)。
template_processed_markdown = template.render(post = post)
#现在通过Markdown引擎传递Markdown文本:
post_body = markdown(template_processed_markdown)
注意,上面的第一个过程是模板语法,然后解析Markdown。换句话说,模板处理的输出仍然是Markdown文本,标签会被替换为适当的值。只有最后一行是由Markdown解析器转换为HTML的Markdown文本。如果您想要颠倒处理顺序,您需要先切换代码,然后运行Markdown解析器,然后将其输出通过模板处理器。



<我假设一些混淆来自人们通过模板系统传递Markdown文本。不应该导致模板语法得到处理?简而言之,No。

模板系统的核心是模板和上下文。然后在模板中找到各种标签,并用上下文中提供的匹配数据替换这些标签。但是,该模板没有关于上下文中的数据的知识,并且不处理该数据。例如,这个模板:

 您好,{{name}}! 

以及上下文:

pre > output = template(name ='John')

会导致以下输出:

 您好,John! 

然而,如果上下文是这样的话:

  output = template(name ='{(some_template_syntax)}')

那么输出将是:

pre $ Hello,{{some_template_syntax}}!

请注意,虽然上下文中的数据包含模板语法,但模板并未处理该数据。它只是将其视为一个值,并将其原样插入到适当位置的模板中。这是正常的和正确的行为。有时然而,你可能有一个合法的需要模板来做一些额外的处理传递给模板的一些数据。出于这个原因,模板系统提供了过滤器。当在上下文中给定一个变量时,过滤器将处理该变量中包含的数据,然后将处理后的数据插入到模板中。例如,为了确保上例中的名称大写,模板如下所示:

  Hello,{ {name | capatalize}}! 

传入上下文 output = template(name ='john')(注意这个名字是小写的),然后我们得到如下的输出:

  Hello,John! 

请注意,名称变量是通过首字母大写处理的,这是Jinja内置过滤器的功能 利用 。但是,该过滤器不处理模板语法,因此将模板语法传递给该过滤器不会导致处理模板语法。



相同的概念适用于任何 markdown 过滤器。这样的过滤器只会将提供的数据解析为Markdown文本并返回HTML文本,然后将其放入模板中。在这种情况下,不会对模板语法进行处理。事实上,这样做可能会导致一个可能的安全问题,特别是如果Markdown文本由不受信任的用户提供。因此,任何包含模板语法的Markdown文本必须分别处理模板语法。



但是,请注意。如果您正在编写包含模板语法示例的文档(如此答案的Markdown源代码),则模板系统不会了解其差异,并将像处理代码中的任何模板语法一样处理这些标记块。如果首先完成Markdown处理,以便将生成的HTML传递给模板系统,那么HTML仍将在模块系统仍然处理的代码块中包含未改变的模板语法。在这两种情况下,这很可能不是所期望的。作为一种解决方法,人们可以设想创建某种Markdown扩展,它将语法处理添加到Markdown处理器本身。然而,这样做的机制会根据所使用的Markdown处理器而有所不同,并且超出了本问题/答案的范围。

I am using a markdown editor which is converted by

post_body = markdown(text_from_markdown_editor)

but when i render the html, the actual jinja2 code is displayed

This is a post by {{ post.author }} 

instead of the actual value.

解决方案

I've been seeing this issue come up a lot lately in various different places, both in relation to Jinja and Django Templates. There seems to be a fundamental misunderstanding (among some users) about how templates systems work and how that relates to Markdown text which is rendered to HTML and inserted into a template. I’ll try to explain this clearly. Note that while the answer below applies to most templating systems (including Jinja and Django), the examples use Jinja for illustrative purposes (after all, the original question specifically asks about Jinja). Simply adapt the code to match the API of your templating system of choice, and it should work just as well.

First of all, Markdown has no knowledge of template syntax. In fact, Markdown has been around longer than Jinja, Django or various other popular templating systems. Additionally, the Markdown Syntax Rules make no mention of template syntax. Therefore, your template syntax will not be processed simply by passing some Markdown text which contains template syntax through a Markdown parser. The template syntax needs to be processed separately by the template engine. For example:

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)

Note that the above first processes the template syntax, then parses the Markdown. In other words, the output of the template processing is still Markdown text with the tags replaced by the appropriate values. Only in the last line is the Markdown text converted to HTML by the Markdown parser. If you want the order of processing to be reversed, you will need to switch the code around to run the Markdown parser first and then pass the output of that through the template processor.

I assume that some of the confusion comes from people passing the Markdown text through a templating system. Shouldn’t that cause the template syntax to get processed? In short, No.

At its core, a templating system takes a template and a context. It then finds the various tags in the template and replaces those tags with the matching data provided in the context. However, the template has no knowledge about the data in the context and does no processing of that data. For example, this template:

Hello, {{ name }}!

And this context:

output = template(name='John')

Would result in the following output:

Hello, John!

However, if the context was this instead:

output = template(name='{(some_template_syntax)}')

then the output would be:

Hello, {{some_template_syntax}}!

Note that while the data in the context contained template syntax, the template did not process that data. It simply considered it a value and inserted it as-is into the template in the appropriate location. This is normal and correct behavior.

Sometimes however, you may have a legitimate need for a template to do some additional processing on some data passed to the template. For that reason, the template system offers filters. When given a variable in the context, the filter will process the data contained in that variable and then insert that processed data in the template. For example, to ensure that the name in our previous example is capitalized, the template would look like the following:

Hello, {{ name|capatalize }}!

Passing in the context output = template(name='john') (note that the name is lowercase), we then get the following output"

Hello, John!

Note, that the data in the name variable was processed by having the first letter capitalized, which is the function of Jinja’s built-in filter capitalize. However, that filter does not process template syntax, and therefore passing template syntax to that filter will not cause the template syntax to be processed.

The same concept applies to any markdown filter. Such a filter only parses the provided data as Markdown text and returns HTML text which is then placed into the template. No processing of template syntax would happen in such a scenario. In fact, doing so could result in a possible security issue, especially if the Markdown text is being provided by untrusted users. Therefore, any Markdown text which contains template syntax must have the template syntax processed separately.

However, there is a note of caution. If you are writing documentation which includes examples of Template syntax in them as code blocks (like the Markdown source for this answer), the templating system is not going to know the difference and will process those tags just like any template syntax not in a code block. If the Markdown processing was done first, so that the resulting HTML was passed to the templating system, that HTML would still contain unaltered template syntax within the code blocks which would still be processed by the templating system. This is most likely not what is desired in either case. As a workaround, one could conceivably create some sort of Markdown Extension which would add syntax processing to the Markdown processor itself. However, the mechanism for doing so would differ depending on which Markdown processor one is using and is beyond the scope of this question/answer.

这篇关于如何在刻录文件中加入flask / jinja2代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆