diff --git a/.eleventy.js b/.eleventy.js index 61d080a..59bcd2e 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -1,44 +1,74 @@ const eleventyNavigationPlugin = require('@11ty/eleventy-navigation') const pluginRss = require('@11ty/eleventy-plugin-rss') -const { DateTime } = require('luxon') +const { + getAllPosts, + getCategoryList, + getCategorisedPosts +} = require('./config/collections') + +const { + readableDate +} = require('./config/filters') + +const { + imageShortcode +} = require('./config/shortcodes') + module.exports = function(eleventyConfig) { + + /*================================*/ + /* plugins and configurations */ + /*================================*/ eleventyConfig.addPlugin(eleventyNavigationPlugin) eleventyConfig.addPlugin(pluginRss) - eleventyConfig.addLayoutAlias('page', 'layouts/page') - eleventyConfig.addLayoutAlias('article', 'layouts/article') - - eleventyConfig.addPassthroughCopy('./src/assets/icons') - eleventyConfig.addPassthroughCopy('./src/assets/sprite.svg') - eleventyConfig.addPassthroughCopy({ - 'node_modules/svg-icon-sprite/dist/svg-icon-sprite.js': 'assets/svg-icon-sprite.js' - }) - eleventyConfig.addPassthroughCopy('./src/assets/social-image.jpg') - - eleventyConfig.addNunjucksAsyncShortcode('image', require('./src/_11ty/imageShortcode').imageShortcode) - - eleventyConfig.addFilter('readableDate', dateObj => { - return DateTime.fromJSDate(dateObj, { - zone: 'Europe/Paris', - }).setLocale('en').toLocaleString(DateTime.DATE_FULL) - }) - - /* Creating a collection of blogposts by filtering based on folder and filetype */ - eleventyConfig.addCollection('blog', (collectionApi) => { - return collectionApi.getFilteredByGlob('./src/blog/*.md').reverse() - }) - eleventyConfig.addCollection('categoryList', require('./src/_11ty/getCategoryList')) - eleventyConfig.addCollection('categories', require('./src/_11ty/createCategories')) - - eleventyConfig.setFrontMatterParsingOptions({ excerpt: true, excerpt_separator: "", excerpt_alias: 'excerpt' }) + /*===================================================*/ + /* files that need to be copied to the build folder */ + /*===================================================*/ + eleventyConfig.addPassthroughCopy('./src/assets/social-image.jpg') + eleventyConfig.addPassthroughCopy('./src/assets/icons') + eleventyConfig.addPassthroughCopy('./src/assets/sprite.svg') + eleventyConfig.addPassthroughCopy({ + 'node_modules/svg-icon-sprite/dist/svg-icon-sprite.js': 'assets/svg-icon-sprite.js' + }) + + + /*=================*/ + /* Layouts */ + /*=================*/ + eleventyConfig.addLayoutAlias('page', 'layouts/page') + eleventyConfig.addLayoutAlias('article', 'layouts/article') + + + /*=================*/ + /* Collections */ + /*=================*/ + eleventyConfig.addCollection('blog', getAllPosts) + eleventyConfig.addCollection('categoryList', getCategoryList) + eleventyConfig.addCollection('categorisedPosts', getCategorisedPosts) + + + /*=================*/ + /* Filters */ + /*=================*/ + eleventyConfig.addFilter('readableDate', readableDate) + + + /*=================*/ + /* shortcodes */ + /*=================*/ + eleventyConfig.addNunjucksAsyncShortcode('image', imageShortcode) + + + return { dir: { input: 'src', diff --git a/config/collections.js b/config/collections.js new file mode 100644 index 0000000..ed43700 --- /dev/null +++ b/config/collections.js @@ -0,0 +1,77 @@ +const slugify = require('slugify') + +/* Creating a collection containing all blogposts by filtering based on folder and filetype */ +const getAllPosts = (collectionApi) => { + return collectionApi.getFilteredByGlob('./src/blog/*.md') + .reverse() +} + +const getCategoryList = (collectionApi) => { + const catPages = [] + let categories = [] + const blogPosts = collectionApi.getFilteredByGlob('./src/blog/*.md') + + blogPosts.map((item) => { + categories.push(item.data.category) + }) + + categories = categories.sort(sortAlphabetically) + const temp = [...new Set(categories)] + + temp.forEach((category) => { + const slug = strToSlug(category); + + if(slug !== 'in-the-spotlight') { + catPages.push({ + 'key': slug, + 'name': category + }) + } + }) + + return catPages +} + +const getCategorisedPosts = (collectionApi) => { + const categorisedPosts = {} + + collectionApi.getFilteredByGlob('./src/blog/*.md').forEach(item => { + const category = item.data.category + + // Ignore the ones without a category + if (typeof category !== 'string') + return + + const slug = strToSlug(category) + + if (Array.isArray(categorisedPosts[slug])) { + categorisedPosts[slug].push(item) + } else { + categorisedPosts[slug] = [item] + } + }) + + return categorisedPosts +} + +module.exports = { + getAllPosts, + getCategoryList, + getCategorisedPosts +} + + +function strToSlug(str) { + const options = { + replacement: "-", + remove: /[&,+()$~%.'":*?<>{}]/g, + lower: true, + } + + return slugify(str, options) +} + + +function sortAlphabetically(a, b) { + return a.localeCompare(b, "en", { sensitivity: "base" }) +} \ No newline at end of file diff --git a/config/filters.js b/config/filters.js new file mode 100644 index 0000000..d83c51e --- /dev/null +++ b/config/filters.js @@ -0,0 +1,11 @@ +const { DateTime } = require('luxon') + +const readableDate = (dateObj) => { + return DateTime.fromJSDate(dateObj, { + zone: 'Europe/Paris', + }).setLocale('en').toLocaleString(DateTime.DATE_FULL) +} + +module.exports = { + readableDate +} \ No newline at end of file diff --git a/config/shortcodes.js b/config/shortcodes.js new file mode 100644 index 0000000..3b6fc00 --- /dev/null +++ b/config/shortcodes.js @@ -0,0 +1,30 @@ +const Image = require('@11ty/eleventy-img') + +const imageShortcode = async (imageObj = {}) => { + const widths = imageObj.widths || [300, 600, 900, 1200] + const className = imageObj.className || "image" + + const sizes = "(min-width: 100px) 50vw, 100vw" + const metadata = await Image(imageObj.src, { + formats: ["webp"], + outputDir: "./_site/assets/images/generated/", + urlPath: "/assets/images/generated/", + widths: widths + }) + const alt = imageObj.alt; + + const imageAttributes = { + class: className, + alt, + sizes, + loading: "lazy", + decoding: "async", + } + + return Image.generateHTML(metadata, imageAttributes) +} + + +module.exports = { + imageShortcode +} diff --git a/src/_11ty/createCategories.js b/src/_11ty/createCategories.js deleted file mode 100644 index 5304f45..0000000 --- a/src/_11ty/createCategories.js +++ /dev/null @@ -1,33 +0,0 @@ -const slugify = require('slugify') - -module.exports = (collectionApi) => { - const categories = {} - - collectionApi.getFilteredByGlob('./src/blog/*.md').forEach(item => { - let category = item.data.category - - // Ignore the ones without a category - if (typeof category !== 'string') - return - - const slug = strToSlug(category) - - if (Array.isArray(categories[slug])) { - categories[slug].push(item) - } else { - categories[slug] = [item] - } - }) - - return categories -} - -function strToSlug(str) { - const options = { - replacement: '-', - remove: /[&,+()$~%.'':*?<>{}]/g, - lower: true, - } - - return slugify(str, options); -} \ No newline at end of file diff --git a/src/_11ty/getCategoryList.js b/src/_11ty/getCategoryList.js deleted file mode 100644 index b9a326b..0000000 --- a/src/_11ty/getCategoryList.js +++ /dev/null @@ -1,43 +0,0 @@ -const slugify = require('slugify') - -module.exports = (collectionApi) => { - const catPages = [] - let categories = [] - const blogPosts = collectionApi.getFilteredByGlob('./src/blog/*.md') - - blogPosts.map((item) => { - let category = item.data.category - categories.push(category) - }) - - categories = categories.sort(sortAlphabetically) - let temp = [...new Set(categories)] - - temp.forEach((category) => { - let slug = strToSlug(category); - - if(slug !== 'in-the-spotlight') { - catPages.push({ - 'key': slug, - 'name': category - }) - } - }) - - return catPages -} - -function strToSlug(str) { - const options = { - replacement: '-', - remove: /[&,+()$~%.'':*?<>{}]/g, - lower: true, - } - - return slugify(str, options) -} - - -function sortAlphabetically(a, b) { - return a.localeCompare(b, 'en', { sensitivity: 'base' }); -} \ No newline at end of file diff --git a/src/_11ty/imageShortcode.js b/src/_11ty/imageShortcode.js deleted file mode 100644 index e00b51b..0000000 --- a/src/_11ty/imageShortcode.js +++ /dev/null @@ -1,31 +0,0 @@ -const Image = require('@11ty/eleventy-img') - -const imageShortcode = async ( - relativeSrc, - alt, - className, - widths = [null, 300, 800, 1280], - formats = ['webp'], - sizes = '(min-width: 100px)' -) => { - const imageMetadata = await Image(relativeSrc, { - widths, - formats, - outputDir: './_site/assets/images/generated/', - urlPath: '/assets/images/generated/', - }) - - const imageAttributes = { - alt, - sizes, - loading: 'lazy', - decoding: 'async', - } - - if(className) {imageAttributes['class'] = className } - - return Image.generateHTML(imageMetadata, imageAttributes) -} - - -module.exports.imageShortcode = imageShortcode; \ No newline at end of file diff --git a/src/blog/article1.md b/src/blog/article1.md index 84f3fd0..ddf39ec 100644 --- a/src/blog/article1.md +++ b/src/blog/article1.md @@ -8,5 +8,5 @@ category: "cat1" Having landed on this Eleventy starter, you probably are no stranger to Eleventy. But if you are, you should definitely check out its benefits. Getting started with Eleventy is quick and easy. -{% image "https://images.unsplash.com/photo-1555066931-4365d14bab8c", "A laptop with some lines of code on the screen", "image", [300, 600] %} +{% image {src: "https://images.unsplash.com/photo-1555066931-4365d14bab8c", alt: "A laptop with some lines of code on the screen", className: "image", widths: [300, 600] } %} diff --git a/src/category.njk b/src/category.njk index eb207a5..4c430c5 100644 --- a/src/category.njk +++ b/src/category.njk @@ -13,5 +13,5 @@ eleventyComputed:

{{ title }}

{% include "./_includes/components/categoryNav.njk" %} -{% set articles = collections.categories[cat.key] | reverse %} +{% set articles = collections.categorisedPosts[cat.key] | reverse %} {% include "./_includes/components/articleList.njk" %} \ No newline at end of file