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

How can I use 11ty to generate one page per json file in _data subfolders?

我正在尝试使用 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

没有永久链接行,它确实可以工作,尽管输出中没有我想要的文件夹结构。

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

  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,但是 110 将尝试处理您给定的 data 文件夹结构的方式是制作一个每年文件夹的对象列表,然后每个 json 文件作为子JS对象,以文件名为key:

> 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 可以正确分页的格式,您需要将其合并为一个大型对象数组。 before eleventy 的回调功能是迄今为止最简单的方法(也可以通过更改数据文件结构或在配置中创建自定义集合来实现)。

这确实要求您的 frontmatter 改为 js 格式,但允许您映射实际的电影对象,然后展平结果数组。

下面是示例存储库中 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 files

_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>