Jinja2 输出 Markdown Frontmatter 到列表

Jinja2 Output Markdown Frontmatter to List

我有一个 Markdown 文件文件夹。每个文件都包含一个 YAML frontmatter 块。我正在尝试将每个文件的标题输出到 Jinja2 模板中,并将它们全部列在 HTML 文件中。

我在没有 Jinja2 的情况下显示标题没有问题,但是当我尝试输出到我的 Jinja2 模板时,一切都崩溃了。

这是我正在使用的 Markdown 文件的示例,以及我要列出的 title: 项目:

---
title: Test
date: 2020-03-26
---

## Test Markdown

这是我正在使用的 Python 代码。我正在使用 python-frontmatter 模块从每个 Markdown post.

中提取前言

使用 frontmatter 模块 select 标题并将其显示在终端上真的很容易,但我无法使用 Jinja2 模板。 content.metadata 是一个字典。

import frontmatter
import jinja2
import glob

# Initialise Jinja2:
jinja2_env = jinja2.Environment(
    loader=jinja2.FileSystemLoader("templates"),
)

# Get list of posts:
posts = glob.glob("posts/*.md")

def build():

    with open("test.html", "w", encoding="utf-8") as index_file:
        for post in posts:
            content = frontmatter.load(post)

            # Prints titles to the terminal the way I want to output them in the Jinja template:
            print(content.metadata["title"])

            # Jinja output:
            template = jinja2_env.get_template("test.html.j2")
            rendered = template.render(frontmatter=content.metadata)
            index_file.write(rendered)

build()

我的 Jinja2 模板如下所示:

<ul>
{% for key, value in frontmatter.items() %}
    <li><a href="">{{ value.title() }}</a></li>
{% endfor %}
</ul>

这根本不起作用,我得到一个错误 jinja2.exceptions.UndefinedError: 'datetime.datetime object' has no attribute 'title'。如果我删除 .title() 那么创建的 HTML 文件最终会循环遍历字典,但会为每个字典输出完整的模板:

<ul>

    <li><a href="">Test Title 1</a></li>

    <li><a href="">2020-10-21 10:00:20</a></li>

</ul><ul>

    <li><a href="">Test Title 2</a></li>

    <li><a href="">2019-06-09 17:42:12</a></li>

</ul><ul>

    <li><a href="">Test Title 3</a></li>

    <li><a href="">2019-06-09 17:42:12</a></li>

</ul>

我的 Python 知识有限,所以如果能提供解决此问题的任何帮助都将非常有用。最后我想要的是一个 HTML 文件,它输出每个文件的标题,如下所示:

<ul>
    <li><a href="">Test Title 1</a></li>
    <li><a href="">Test Title 2</a></li>
    <li><a href="">Test Title 3</a></li>
</ul>
<ul>
{% for key, value in frontmatter.items() %}
    <li><a href="">{{ value.title() }}</a></li>
{% endfor %}
</ul>

这是错误的。正如错误消息所说,您在日期时间 object 上调用 title()(您的 date 前言)。

您的循环遍历前面的每个 key(标题,然后是日期),以及 value.

<ul>
    <li><a href="">{{ frontmatter.title }}</a></li>
    <li>{{ frontmatter.date }}</li>
</ul>

当然,这只会向您显示一个源文件的标题,因为您要遍历每个 post 并将它们呈现为完全独立的模板:

for post in posts:

你想呈现 1 模板,所以移除你对 render() 的调用周围的 for 循环并将它传递给你的所有 posts:

rendered = template.render(
    posts=posts,
    posts_meta=[frontmatter.load(post).metadata for post in posts]
)

... 并在您的模板中遍历它们:

<ul>
{% post_meta in posts_meta %}
    <li><a href="">{{ post_meta.title }}</a></li>
{% endfor %}
</ul>