Open markboulton opened 4 years ago
@markboulton I've done something similar before.
Here's a minimal project to get you started. Also, check out the docs for JavaScript Data Files and Create Pages From Data.
// package.json
{
"name": "the-website",
"version": "0.1.0",
"description": "A business website 👌",
"private": true,
"scripts": {
"start": "npm run dev",
"dev": "npm run clean eleventy:dev",
"build": "run-s clean eleventy:prod",
"eleventy:dev": "cross-env NODE_ENV=development eleventy --serve",
"eleventy:prod": "cross-env NODE_ENV=production eleventy",
"clean": "shx rm -rf ./dist/*",
"format": "prettier --write \"src/**/*.{css,html,js,json,md}\"",
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"@11ty/eleventy": "^0.11.0",
"@11ty/eleventy-plugin-rss": "^1.0.7",
"cross-env": "^7.0.2",
"npm-run-all": "^4.1.5",
"prettier": "^2.0.5",
"shx": "^0.3.2"
}
}
// .eleventy.js
const isProduction = process.env.NODE_ENV === `production`;
module.exports = function (config) {
// Plugins
config.addPlugin(require(`@11ty/eleventy-plugin-rss`));
// More config...
// Base Config
return {
dir: {
input: `src`,
output: `dist`,
includes: `_includes`,
layouts: `_layouts`,
data: `_data`,
},
templateFormats: [`njk`, `md`, `11ty.js`],
htmlTemplateEngine: `njk`,
markdownTemplateEngine: `njk`,
};
};
// src/page.11ty.js
exports.data = () => ({
title: `Default Title`,
layout: `base.njk`,
pagination: {
data: `pages`,
size: 1,
alias: `page`,
addAllPagesToCollections: true,
},
permalink: ({ page }) => `/${page.language}/${page.id}/index.html`,
});
exports.render = ({ page }) => `
<div>
<div>${page.content}</div>
<div>${page.source}</div>
<div>${page.notes}</div>
</div>`;
{# src/_layouts/base.njk #}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ page.title if page.title else title }}</title>
</head>
<body>
<div>
{{ content | safe }}
</div>
</body>
</html>
// src/_data/pages.js
const fs = require(`fs`);
const path = require(`path`);
module.exports = async () => {
const result = [];
const files = await fs.promises.readdir(path.join(__dirname, `languages`));
for (const file of files) {
const data = await fs.promises.readFile(
path.join(__dirname, `languages/${file}`),
{ encoding: `utf8` }
);
const pages = JSON.parse(data).map((page) => {
page.date = new Date(); // each pagination object needs a date
page.language = file.substring(0, file.indexOf(`.json`)); // add extra meta
page.title = `${page.language} - ${page.id}`; // some title
return page;
});
result.push(...pages);
}
return result;
};
// src/_data/languages/arabic.json
[
{
"id": "01",
"content": "هلا سكنت بذي ضغثٍ فقد زعموا — شخصت تطلب ظبياً راح مجتازا",
"notes": "",
"source": "Wikipedia"
},
{
"id": "02",
"content": "اصبر على حفظ خضر واستشر فطنا، وزج همك في بغداذ منثملا",
"notes": "",
"source": "Wikipedia 2014."
}
]
// src/_data/languages/english.json
[
{
"id": "01",
"content": "lorem ipsum dolor 01",
"notes": "",
"source": "Wikipedia"
},
{
"id": "02",
"content": "lorem ipsum dolor 02",
"notes": "",
"source": "Wikipedia 2014."
}
]
@denisbrodbeck This is great! Thank you. Works like a charm! One slight thing: how would I need to tweak this to build just one page per language json file? Thanks for your help!
@denisbrodbeck This is great! Thank you. Works like a charm! One slight thing: how would I need to tweak this to build just one page per language json file? Thanks for your help!
I should clarify - in addition to building a page for each. So, sort of an index page which would link to each further generated page.
I have 56 json files in a
_data/languages
subfolder – one for each language – labelled 'english.json', 'arabic.json' etc. In each json file is an array of objects structured like this:I'm using nunjucks for my templating.
What I'd like to do is build a single page for each language (one for each json file), and build navigation to navigate between them. I'm sure this is possible using a single template, but I can't seem to figure it out. Any pointers?