Как я могу использовать 11ty для создания одной страницы для каждого файла json в подпапках _data?

Я пытаюсь использовать 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: "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 });
    });
};

person centralscru    schedule 09.10.2020    source источник
comment
Работает ли код пагинации, который вы предоставили выше?   -  person Luke Storry    schedule 09.10.2020
comment
Не могли бы вы прислать пример репродукции, чтобы я мог играть на скрипке локально?   -  person Luke Storry    schedule 09.10.2020
comment
Также обычно стоит попытаться зарегистрировать свои данные, прежде чем возиться с разбивкой на страницы, чтобы вам было легче понять, с чем вы работаете. Можете ли вы поместить {{ movie | log}}, а затем {{ movies | log}} в свой шаблон, а затем опубликовать полученные журналы консоли здесь?   -  person Luke Storry    schedule 09.10.2020
comment
Спасибо @LukeStorry - этот код не работает, потому что slug жалуется, что ничего не передается. Приветствую за подсказку в журнале. Это показывает объект с несколькими ключами, каждый из которых является именем файла без расширения (и, следовательно, подходит для имени выходной папки). Так что это дает мне надежду, что я смогу получить то, что хочу, я просто не знаю, как это сделать! Репо добавлено.   -  person centralscru    schedule 09.10.2020


Ответы (2)


Вы используете 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 сможет правильно разбить их на страницы, вам нужно преобразовать их в один большой массив объектов. Функция обратного вызова before из Eleventy, безусловно, является самым простым способом сделать это (также возможно, изменив структуру файла данных или создав собственную коллекцию в config).

Это действительно требует, чтобы ваш фронтматтер был в формате 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>
person Luke Storry    schedule 09.10.2020
comment
Большое спасибо, Люк! Вы здесь это прибили. Мне потребовалось некоторое время, чтобы быть уверенным, потому что (а) у меня была ошибка из-за метода flat () из-за необходимости обновить мою версию локального узла, и (б) с полным набором данных я продолжал получать undefined, возвращаясь в постоянную ссылку когда я помещаю {{movie.Title | slug}}. Оказывается, это произошло из-за того, что некоторые элементы в наборе данных не имеют значений заголовка. Сообщение об ошибке от 11ty не указывает на частичное успешное создание страниц! - person centralscru; 12.10.2020
comment
для отладки вы можете расширить обратный вызов before на более крупную многострочную функцию, а затем несколько раз войти в консоль - это может помочь! - person Luke Storry; 12.10.2020

Другой обходной путь для структуры:

_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>
person Nikita Madeev    schedule 23.03.2021