如何使用11ty在_data子文件夹中为每个json文件生成一页



我正在尝试使用11ty为电影评论网站生成页面。我的_data文件夹的结构如下。

_data
movies
2017
title1.json
title2.json
2018
2019

我希望能有这样的产出。

_site
movies
2017
title-1.html
title-2.html
2018

我会满足于这样的输出。

_site
movies
title-1.html
title-2.html

但我不知道如何接近任何东西!有什么想法吗?这是我的nunjucks模板。TitleWithYear是每个.json文件中的一个属性。

---
pagination:
data: movies
size: 1
alias: movie
resolve: keys
permalink: "movies/{{ year??? }}/{{ movie.TitleWithYear | slug }}/index.html"
---
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<h1>{{ movie.TitleWithYear }}</h1>
</body>
</html>

编辑:这是一个显示问题的回购。

https://github.com/edmondbramhall/11ty-test1

如果没有中的permalink行,它确实可以工作,尽管输出中没有我想要的文件夹结构。

编辑:在卢克的帮助下,这是我最终得到的分页属性。

permalink: "movies/{{ movie.ReleaseYear }}/{{ movie.Id }}-{{ movie.Title | slug }}/index.html"

我还为slugify创建了一个全局过滤器,通过在项目的根文件夹中创建一个文件.eleventy.js来提供一些设置,内容如下。

const slugify = require('slugify');
module.exports = function(eleventyConfig) {
eleventyConfig.addFilter("slug", function(value) {
return slugify(value, { strict: true, lower: true });
});
};

您在分页中使用data: movies,但eleventy尝试处理给定的data文件夹结构的方法是,列出每年文件夹的对象列表,然后将每个json文件作为子JS对象,并以文件名为关键字:

> console.log(data.movies)
[
{
'An-American-Tail_1986_4978': {
...
TitleWithYear: 'An American Tail (1986)',
Tagline: 'Meet Fievel. In his search to find his family, he discovered America.',
...
},
'Barbra-Streisand-One-Voice_1986_31683': {
...
TitleWithYear: 'Barbra Streisand: One Voice (1986)',
Tagline: 'Barbra sings in her backyard for charity!',
...
}
},
{
'Alien-Predators_1985_52318': {
...
TitleWithYear: 'Alien Predators (1985)',
...
}
}
]

为了将数据转换为一种格式,以便eleventy能够正确地对其进行分页,您需要将其分解为一个大型对象数组。eleventy的before回调功能是迄今为止最简单的方法(也可以通过更改数据文件结构或在配置中创建自定义集合(。

这确实需要您的frontmatter采用js格式,但允许您映射实际的电影对象,然后展平生成的阵列。

以下是示例repo中movie.njk文件的完整工作示例。

---js
{
pagination:{
data: "movies",
before: (data) => data.map(year => Object.values(year)).flat(),
size: 1,
alias: "movie",
},
permalink: "movies/{{ movie.Id }}/",
}
---
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ movie.TitleWithYear }}</h1>
<p> {{ movie.Tagline}}
</body>
</html>

结构的另一个变通方法:

_data
movies.js
movies
title1.json
title2.json
title3.json
movie.njk

使用javascript数据文件

_data/movies.js:

const fs = require("fs");
const path = require("path");
const moviesFolder = path.resolve(__dirname, "../movies");
const movies = fs
.readdirSync(moviesFolder)
.filter(name => path.extname(name) === ".json")
.map(name => ({
key: path.parse(name).name,
...require(path.join(moviesFolder, name)),
}));
module.exports = movies;

movie.njk:

---
pagination:
data: "movies"
size: 1
alias: "movie"
permalink: "{{ movie.key }}/"
---
<h1>{{ movie.title }}</h1>

最新更新