¿Cómo incluir el código flask / jinja2 dentro de un archivo de rebajas?

Estoy usando un editor de rebajas que es convertido por

post_body = markdown(text_from_markdown_editor) 

pero cuando renderizo el html, se muestra el código jinja2 real

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

en lugar del valor real.

Últimamente, he visto cómo este problema aparece mucho en diferentes lugares, tanto en relación con Jinja como con las Plantillas Django. Parece que hay un malentendido fundamental (entre algunos usuarios) sobre cómo funcionan los sistemas de plantillas y cómo se relaciona con el texto de Markdown que se procesa en HTML y se inserta en una plantilla. Intentaré explicar esto claramente. Tenga en cuenta que si bien la respuesta a continuación se aplica a la mayoría de los sistemas de plantillas (incluidos Jinja y Django), los ejemplos utilizan Jinja con fines ilustrativos (después de todo, la pregunta original se refiere específicamente a Jinja). Simplemente adapte el código para que coincida con la API de su sistema de plantillas de elección, y debería funcionar igual de bien.

En primer lugar, Markdown no tiene conocimiento de la syntax de la plantilla. De hecho, Markdown ha existido por más tiempo que Jinja, Django o varios otros sistemas populares de plantillas. Además, las Reglas de Sintaxis de Markdown no hacen mención de la syntax de la plantilla. Por lo tanto, la syntax de su plantilla no se procesará simplemente pasando un texto de Markdown que contenga la syntax de la plantilla a través de un analizador de Markdown. La syntax de la plantilla debe ser procesada por separado por el motor de la plantilla. Por ejemplo:

 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) 

Tenga en cuenta que lo anterior primero procesa la syntax de la plantilla y luego analiza el Markdown. En otras palabras, la salida del procesamiento de la plantilla sigue siendo un texto de Markdown con las tags reemplazadas por los valores apropiados. Solo en la última línea está el texto de Markdown convertido a HTML por el analizador de Markdown. Si desea que se invierta el orden de procesamiento, deberá cambiar el código para ejecutar primero el analizador de Markdown y luego pasar la salida a través del procesador de plantillas.

Supongo que parte de la confusión proviene de personas que pasan el texto de Markdown a través de un sistema de plantillas. ¿No debería eso hacer que la syntax de la plantilla se procese? En resumen, No.

En su núcleo, un sistema de plantillas toma una plantilla y un contexto. Luego encuentra las distintas tags en la plantilla y reemplaza esas tags con los datos coincidentes proporcionados en el contexto. Sin embargo, la plantilla no tiene conocimiento sobre los datos en el contexto y no procesa esos datos. Por ejemplo, esta plantilla:

 Hello, {{ name }}! 

Y este contexto:

 output = template(name='John') 

Resultaría en el siguiente resultado:

 Hello, John! 

Sin embargo, si el contexto era este en su lugar:

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

entonces la salida sería:

 Hello, {{some_template_syntax}}! 

Tenga en cuenta que, si bien los datos en el contexto contenían la syntax de la plantilla, la plantilla no procesó esos datos. Simplemente lo consideró un valor y lo insertó como está en la plantilla en la ubicación apropiada. Este es un comportamiento normal y correcto.

A veces, sin embargo, es posible que tenga una necesidad legítima de que una plantilla realice un procesamiento adicional en algunos datos que se le pasan a la plantilla. Por esa razón, el sistema de plantillas ofrece filtros. Cuando se le da una variable en el contexto, el filtro procesará los datos contenidos en esa variable y luego insertará los datos procesados ​​en la plantilla. Por ejemplo, para garantizar que el nombre en nuestro ejemplo anterior esté en mayúscula, la plantilla se vería como la siguiente:

 Hello, {{ name|capatalize }}! 

Al pasar en la output = template(name='john') contexto output = template(name='john') (tenga en cuenta que el nombre es en minúsculas), obtenemos la siguiente salida ”

 Hello, John! 

Tenga en cuenta que los datos en la variable de name se procesaron con la primera letra en mayúscula, que es la función del capitalize incorporado en el filtro de Jinja. Sin embargo, ese filtro no procesa la syntax de la plantilla y, por lo tanto, pasar la syntax de la plantilla a ese filtro no hará que se procese la syntax de la plantilla.

El mismo concepto se aplica a cualquier filtro de markdown . Dicho filtro solo analiza los datos proporcionados como texto de Markdown y devuelve el texto HTML que luego se coloca en la plantilla. Ningún procesamiento de la syntax de la plantilla ocurriría en tal escenario. De hecho, hacerlo podría provocar un posible problema de seguridad, especialmente si el texto de Markdown está siendo proporcionado por usuarios que no son de confianza. Por lo tanto, cualquier texto de Markdown que contenga la syntax de la plantilla debe tener la syntax de la plantilla procesada por separado.

Sin embargo, hay una nota de precaución. Si está escribiendo documentación que incluye ejemplos de syntax de plantilla en ellos como bloques de código (como el origen de Markdown para esta respuesta), el sistema de plantillas no sabrá la diferencia y procesará esas tags como cualquier syntax de plantilla que no esté en un código bloquear. Si el procesamiento de Markdown se realizó primero, de modo que el HTML resultante se pasara al sistema de plantillas, ese HTML aún contendría una syntax de plantilla sin alterar dentro de los bloques de código que aún serían procesados ​​por el sistema de plantillas. Es muy probable que esto no sea lo que se desea en ninguno de los dos casos. Como solución temporal, uno podría crear algún tipo de Markdown Extension que agregaría el procesamiento de syntax al procesador Markdown. Sin embargo, el mecanismo para hacerlo diferiría dependiendo del procesador Markdown que esté usando y esté fuera del scope de esta pregunta / respuesta.