Last active
September 23, 2023 08:23
-
-
Save solace/61685cfd85b0cd301ec9608610695b4c to your computer and use it in GitHub Desktop.
Support categories and tags migrated from WordPress in Eleventy. See https://micheleong.com/2023/09/23/migrate-wordpress-eleventy-colocated-images
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// File: lib/collections/categories.js | |
const slugify = require("slugify"); | |
const getAllKeyValues = require("../utils/getAllKeyValues"); | |
module.exports = (collection) => { | |
let allCategories = getAllKeyValues( | |
collection.getFilteredByGlob("src/posts/**/*.md"), | |
"categories" | |
); | |
return allCategories.map((category) => ({ | |
title: category, | |
slug: slugify(category), | |
})); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
layout: default | |
permalink: /category/index.html | |
--- | |
<h1 class="text-3xl text-center font-bold leading-normal mt-0 mb-3">Categories</h1> | |
<div class="mt-3 text-center"> | |
{% for category in collections.categories %} | |
<a href="{{ '/category/' | url }}{{ category.slug }}" class="inline-block bg-slate-200 rounded-full px-3 py-1 text-sm font-medium m-0.5">{{ category.title }}</a> | |
{% endfor %} | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
layout: default | |
eleventyExcludeFromCollections: true | |
pagination: | |
data: collections.pagedPostsByCategory | |
size: 1 | |
alias: paged | |
permalink: "/category/{{ paged.category.slug }}/{% if paged.number > 1 %}{{ paged.number }}/{% endif %}index.html" | |
--- | |
<h1 class="text-3xl text-center font-bold leading-normal mt-0 mb-3">Category: {{ paged.category.title }}</h1> | |
<div class="flex flex-wrap -mx-2"> | |
{% include "partials/post-grid.njk" %} | |
</div> | |
{% if collections.pagedPostsByCategory[paged.category.slug].length > site.paginate %} | |
{% include "partials/paginator.njk" %} | |
{% endif %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = eleventyConfig => { | |
... | |
// Add custom categories and hashtag collections | |
config.addCollection('categories', require('./lib/collections/categories')); | |
config.addCollection('pagedPostsByCategory', require('./lib/collections/pagedPostsByCategory')); | |
config.addCollection("hashtags", require('./lib/collections/hashtags')); | |
config.addCollection('pagedPostsByHashtag', require('./lib/collections/pagedPostsByHashtag')); | |
... | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// File: lib/utils/getAllKeyValues.js | |
// Source: https://www.webstoemp.com/blog/basic-custom-taxonomies-with-eleventy/ | |
const lodash = require("lodash"); | |
/** | |
* Get all unique key values from a collection | |
* | |
* @param {Array} collectionArray - collection to loop through | |
* @param {String} key - key to get values from | |
*/ | |
module.exports = function getAllKeyValues(collectionArray, key) { | |
// get all values from collection | |
let allValues = collectionArray.map((item) => { | |
return item.data[key] ? item.data[key] : []; | |
}); | |
// flatten values array | |
allValues = lodash.flattenDeep(allValues); | |
// to lowercase | |
allValues = allValues.map((item) => item.toLowerCase()); | |
// remove duplicates | |
allValues = [...new Set(allValues)]; | |
// order alphabetically | |
allValues = allValues.sort(function (a, b) { | |
return a.localeCompare(b, "en", { sensitivity: "base" }); | |
}); | |
// return | |
return allValues; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// File: lib/filters/include.js | |
const lodash = require("lodash"); | |
/** | |
* Select all objects in an array | |
* where the path includes the value to match | |
* capitalisation and diacritics are removed from compared values | |
* | |
* @param {Array} arr - array of objects to inspect | |
* @param {String} path - path to inspect for each object | |
* @param {String} value - value to match | |
* @return {Array} - new array | |
*/ | |
module.exports = function (arr, path, value) { | |
value = lodash.deburr(value).toLowerCase(); | |
return arr.filter((item) => { | |
let pathValue = lodash.get(item, path); | |
pathValue = Array.isArray(pathValue) ? pathValue : [pathValue]; | |
pathValue = pathValue.map((v) => lodash.deburr(v).toLowerCase()); | |
return pathValue.includes(value); | |
}); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// File: lib/collections/pagedPostsByCategory.js | |
const siteData = require('../../src/_data/site'); | |
const includes = require('../filters/include'); | |
module.exports = (coll) => { | |
const allPosts = require('./posts')(coll); | |
const categoryList = require('./categories')(coll); | |
const maxPostsPerPage = siteData.paginate; | |
const pagedPosts = []; | |
categoryList.forEach((category) => { | |
const taggedPosts = includes(allPosts, "data.categories", category.title).reverse(); | |
const numberOfPages = Math.ceil(taggedPosts.length / maxPostsPerPage); | |
for (let pageNum = 1; pageNum <= numberOfPages; pageNum++) { | |
const sliceFrom = (pageNum - 1) * maxPostsPerPage; | |
const sliceTo = sliceFrom + maxPostsPerPage; | |
pagedPosts.push({ | |
category, | |
number: pageNum, | |
posts: taggedPosts.slice(sliceFrom, sliceTo), | |
first: pageNum === 1, | |
last: pageNum === numberOfPages | |
}); | |
} | |
}); | |
return pagedPosts; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// File: lib/collections/pagedPostsByHashtag.js | |
const siteData = require('../../src/_data/site'); | |
const includes = require('../filters/include'); | |
module.exports = (coll) => { | |
const allPosts = require('./posts')(coll); | |
const hashtagList = require('./hashtags')(coll); | |
const maxPostsPerPage = siteData.paginate; | |
const pagedPosts = []; | |
hashtagList.forEach((hashtag) => { | |
const taggedPosts = includes(allPosts, "data.hashtags", hashtag.title).reverse(); | |
const numberOfPages = Math.ceil(taggedPosts.length / maxPostsPerPage); | |
for (let pageNum = 1; pageNum <= numberOfPages; pageNum++) { | |
const sliceFrom = (pageNum - 1) * maxPostsPerPage; | |
const sliceTo = sliceFrom + maxPostsPerPage; | |
pagedPosts.push({ | |
hashtag, | |
number: pageNum, | |
posts: taggedPosts.slice(sliceFrom, sliceTo), | |
first: pageNum === 1, | |
last: pageNum === numberOfPages | |
}); | |
} | |
}); | |
return pagedPosts; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
layout: default | |
eleventyExcludeFromCollections: true | |
pagination: | |
data: collections.pagedPostsByHashtag | |
size: 1 | |
alias: paged | |
permalink: "/tag/{{ paged.hashtag.slug }}/{% if paged.number > 1 %}{{ paged.number }}/{% endif %}index.html" | |
--- | |
<h1 class="text-3xl text-center font-bold leading-normal mt-0 mb-3">Tagged with: {{ paged.hashtag.title }}</h1> | |
<div class="flex flex-wrap -mx-2"> | |
{% include "partials/post-grid.njk" %} | |
</div> | |
{% if collections.pagedPostsByHashtag[paged.hashtag.slug].length > site.paginate %} | |
{% include "partials/paginator.njk" %} | |
{% endif %} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment