feat: clean up filters
Some sorely needed reorganization and pruning
This commit is contained in:
parent
e6cfa88f61
commit
ea6280226a
11 changed files with 159 additions and 176 deletions
28
config/filters/collection.js
Normal file
28
config/filters/collection.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
import date from "./date.js";
|
||||
|
||||
const filterFavourites = (collection) => {
|
||||
return collection.filter(
|
||||
(item) => item.data.favourite || item.data.isFavourite,
|
||||
);
|
||||
};
|
||||
|
||||
const organizeByYear = (collection) => {
|
||||
const collectionByYear = {};
|
||||
|
||||
collection.forEach((item) => {
|
||||
const year = date.formatDate(item.date, "YYYY");
|
||||
|
||||
if (!collectionByYear[year]) {
|
||||
return (collectionByYear[year] = [item]);
|
||||
}
|
||||
|
||||
collectionByYear[year].push(item);
|
||||
});
|
||||
|
||||
return collectionByYear;
|
||||
};
|
||||
|
||||
export default {
|
||||
filterFavourites,
|
||||
organizeByYear,
|
||||
};
|
14
config/filters/date.js
Normal file
14
config/filters/date.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc.js";
|
||||
import advancedFormat from "dayjs/plugin/advancedFormat.js";
|
||||
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(advancedFormat);
|
||||
|
||||
const formatDate = (date, format) => dayjs.utc(date).format(format);
|
||||
const formatAsUTCString = (date) => new Date(date).toUTCString();
|
||||
|
||||
export default {
|
||||
formatDate,
|
||||
formatAsUTCString,
|
||||
};
|
31
config/filters/feed.js
Normal file
31
config/filters/feed.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { JSDOM } from "jsdom";
|
||||
|
||||
// From coryd.dev
|
||||
// https://www.coryd.dev/posts/2025/generating-absolute-urls-in-my-rss-feeds/
|
||||
const convertRelativeLinks = (htmlContent, url) => {
|
||||
if (!htmlContent || !url) return htmlContent;
|
||||
|
||||
const dom = new JSDOM(htmlContent);
|
||||
const document = dom.window.document;
|
||||
|
||||
document.querySelectorAll("a[href]").forEach((link) => {
|
||||
let href = link.getAttribute("href");
|
||||
|
||||
if (href.startsWith("#")) {
|
||||
link.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!href.startsWith("http://") && !href.startsWith("https://"))
|
||||
link.setAttribute(
|
||||
"href",
|
||||
`${url.replace(/\/$/, "")}/${href.replace(/^\/+/, "")}`,
|
||||
);
|
||||
});
|
||||
|
||||
return document.body.innerHTML;
|
||||
};
|
||||
|
||||
export default {
|
||||
convertRelativeLinks,
|
||||
};
|
20
config/filters/general.js
Normal file
20
config/filters/general.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
import pluralizeBase from "pluralize";
|
||||
|
||||
const filter = (collection, filters = []) => {
|
||||
return collection.filter((item) => !filters.includes(item));
|
||||
};
|
||||
|
||||
const keys = Object.keys;
|
||||
|
||||
const limit = (collection, limit = 5) => collection.slice(0, limit);
|
||||
|
||||
const pluralize = (string, count = 0) => {
|
||||
return pluralizeBase(string, count);
|
||||
};
|
||||
|
||||
export default {
|
||||
filter,
|
||||
keys,
|
||||
limit,
|
||||
pluralize,
|
||||
};
|
|
@ -1,132 +1,15 @@
|
|||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc.js";
|
||||
import advancedFormat from "dayjs/plugin/advancedFormat.js";
|
||||
import collection from "./collection.js";
|
||||
import date from "./date.js";
|
||||
import feed from "./feed.js";
|
||||
import general from "./general.js";
|
||||
import postcss from "./postcss/index.js";
|
||||
import tag from "./tag.js";
|
||||
|
||||
import pluralizeBase from "pluralize";
|
||||
|
||||
import { JSDOM } from "jsdom";
|
||||
|
||||
export const keys = Object.keys;
|
||||
export const values = Object.values;
|
||||
export const entries = Object.entries;
|
||||
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(advancedFormat);
|
||||
|
||||
export const formatDate = (date, format) => dayjs.utc(date).format(format);
|
||||
export const formatAsUTCString = (date) => new Date(date).toUTCString();
|
||||
|
||||
export const organizeByDate = (collection) => {
|
||||
const collectionByDate = {};
|
||||
|
||||
collection.forEach((item) => {
|
||||
const year = formatDate(item.date, "YYYY");
|
||||
|
||||
if (!collectionByDate[year]) {
|
||||
return (collectionByDate[year] = [item]);
|
||||
}
|
||||
|
||||
collectionByDate[year].push(item);
|
||||
});
|
||||
|
||||
return collectionByDate;
|
||||
};
|
||||
|
||||
export const transformByDate = (collection) => {
|
||||
const collectionByDate = {};
|
||||
|
||||
collection.forEach((item) => {
|
||||
const year = formatDate(item.date, "YYYY");
|
||||
|
||||
if (!collectionByDate[year]) {
|
||||
return (collectionByDate[year] = { value: year, data: [item] });
|
||||
}
|
||||
|
||||
collectionByDate[year].data.push(item);
|
||||
});
|
||||
|
||||
return collectionByDate;
|
||||
};
|
||||
|
||||
export const allTagCounts = (collection, ignore = ["post"]) => {
|
||||
if (!collection.length) {
|
||||
throw new Error("Invalid collection, no items");
|
||||
}
|
||||
|
||||
const tagCounts = new Map();
|
||||
|
||||
for (const item of collection) {
|
||||
const tags = item.data.tags;
|
||||
|
||||
tags?.forEach((tag) => tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1));
|
||||
}
|
||||
|
||||
ignore.forEach((tag) => tagCounts.delete(tag));
|
||||
|
||||
const tagArray = Array.from(tagCounts.entries())
|
||||
.map(([tag, count]) => ({
|
||||
tag,
|
||||
count,
|
||||
}))
|
||||
.sort((a, b) => b.count - a.count);
|
||||
|
||||
return tagArray;
|
||||
};
|
||||
|
||||
export const filter = (collection, filters = []) => {
|
||||
return collection.filter((item) => !filters.includes(item));
|
||||
};
|
||||
|
||||
export const pluralize = (string, count = 0) => {
|
||||
return pluralizeBase(string, count);
|
||||
};
|
||||
|
||||
export const limit = (collection, limit = 5) => collection.slice(0, limit);
|
||||
|
||||
export const filterFavourites = (collection) => {
|
||||
return collection.filter(
|
||||
(item) => item.data.favourite || item.data.isFavourite,
|
||||
);
|
||||
};
|
||||
|
||||
export const filterByTags = (collection, tags = []) => {
|
||||
return collection.filter(
|
||||
(item) =>
|
||||
item.data.tags && !item.data.tags.every((tag) => tags.includes(tag)),
|
||||
);
|
||||
};
|
||||
|
||||
export const isOld = (dateArg) => {
|
||||
const date = dayjs(dateArg);
|
||||
const now = dayjs();
|
||||
|
||||
const diffInYears = now.diff(date, "years");
|
||||
|
||||
return diffInYears >= 2;
|
||||
};
|
||||
|
||||
// From coryd.dev
|
||||
// https://www.coryd.dev/posts/2025/generating-absolute-urls-in-my-rss-feeds/
|
||||
export const convertRelativeLinks = (htmlContent, url) => {
|
||||
if (!htmlContent || !url) return htmlContent;
|
||||
|
||||
const dom = new JSDOM(htmlContent);
|
||||
const document = dom.window.document;
|
||||
|
||||
document.querySelectorAll("a[href]").forEach((link) => {
|
||||
let href = link.getAttribute("href");
|
||||
|
||||
if (href.startsWith("#")) {
|
||||
link.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!href.startsWith("http://") && !href.startsWith("https://"))
|
||||
link.setAttribute(
|
||||
"href",
|
||||
`${url.replace(/\/$/, "")}/${href.replace(/^\/+/, "")}`,
|
||||
);
|
||||
});
|
||||
|
||||
return document.body.innerHTML;
|
||||
export default {
|
||||
...collection,
|
||||
...date,
|
||||
...feed,
|
||||
...general,
|
||||
...postcss,
|
||||
...tag,
|
||||
};
|
||||
|
|
5
config/filters/postcss/index.js
Normal file
5
config/filters/postcss/index.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import postcss from "./postcss.js";
|
||||
|
||||
export default {
|
||||
...postcss,
|
||||
};
|
|
@ -4,7 +4,7 @@
|
|||
* ---
|
||||
* https://github.com/philhawksworth/eleventyone/blob/master/src/site/css/styles.11ty.js
|
||||
*/
|
||||
import postcss from "postcss";
|
||||
import { default as postcssBase } from "postcss";
|
||||
import postcssImport from "postcss-import";
|
||||
import postcssImportExtGlob from "postcss-import-ext-glob";
|
||||
import autoprefixer from "autoprefixer";
|
||||
|
@ -15,9 +15,9 @@ import fontFamily from "./utils/font-family.js";
|
|||
import fontVariables from "./utils/font-variables.js";
|
||||
import spacing from "./utils/spacing.js";
|
||||
|
||||
const postCss = async (rawCss) => {
|
||||
const postcss = async (rawCss) => {
|
||||
const css = `${rawCss}${fontFamily}${fontVariables}${colors}${spacing}`;
|
||||
return await postcss([
|
||||
return await postcssBase([
|
||||
postcssImportExtGlob,
|
||||
postcssImport,
|
||||
autoprefixer,
|
||||
|
@ -27,4 +27,6 @@ const postCss = async (rawCss) => {
|
|||
.then((result) => result.css);
|
||||
};
|
||||
|
||||
export default postCss;
|
||||
export default {
|
||||
postcss,
|
||||
};
|
||||
|
|
36
config/filters/tag.js
Normal file
36
config/filters/tag.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
const allTagCounts = (collection, ignore = ["post"]) => {
|
||||
if (!collection.length) {
|
||||
throw new Error("Invalid collection, no items");
|
||||
}
|
||||
|
||||
const tagCounts = new Map();
|
||||
|
||||
for (const item of collection) {
|
||||
const tags = item.data.tags;
|
||||
|
||||
tags?.forEach((tag) => tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1));
|
||||
}
|
||||
|
||||
ignore.forEach((tag) => tagCounts.delete(tag));
|
||||
|
||||
const tagArray = Array.from(tagCounts.entries())
|
||||
.map(([tag, count]) => ({
|
||||
tag,
|
||||
count,
|
||||
}))
|
||||
.sort((a, b) => b.count - a.count);
|
||||
|
||||
return tagArray;
|
||||
};
|
||||
|
||||
const filterByTags = (collection, tags = []) => {
|
||||
return collection.filter(
|
||||
(item) =>
|
||||
item.data.tags && !item.data.tags.every((tag) => tags.includes(tag)),
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
allTagCounts,
|
||||
filterByTags,
|
||||
};
|
|
@ -1,27 +1,10 @@
|
|||
import util from "util";
|
||||
import pluginRss from "@11ty/eleventy-plugin-rss";
|
||||
import pluginNoRobots from "eleventy-plugin-no-robots";
|
||||
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
|
||||
|
||||
import { collectionByTag, postsByTag } from "./config/collections/index.js";
|
||||
|
||||
import {
|
||||
allTagCounts,
|
||||
convertRelativeLinks,
|
||||
entries,
|
||||
filter,
|
||||
filterByTags,
|
||||
filterFavourites,
|
||||
formatDate,
|
||||
formatAsUTCString,
|
||||
isOld,
|
||||
keys,
|
||||
limit,
|
||||
organizeByDate,
|
||||
pluralize,
|
||||
values,
|
||||
} from "./config/filters/index.js";
|
||||
import postcss from "./config/filters/postcss/postcss.js";
|
||||
import filters from "./config/filters/index.js";
|
||||
import markdown from "./config/plugins/markdown.js";
|
||||
import liteYoutube from "./config/shortcodes/youtube.js";
|
||||
|
||||
|
@ -32,7 +15,6 @@ export default function (eleventyConfig) {
|
|||
eleventyConfig.addWatchTarget("./src/css");
|
||||
|
||||
// --------------------- Plugins ---------------------
|
||||
eleventyConfig.addPlugin(pluginRss);
|
||||
eleventyConfig.addPlugin(pluginNoRobots);
|
||||
|
||||
// --------------------- Custom Collections -----------------------
|
||||
|
@ -51,22 +33,9 @@ export default function (eleventyConfig) {
|
|||
);
|
||||
|
||||
// --------------------- Custom Filters -----------------------
|
||||
eleventyConfig.addFilter("allTagCounts", allTagCounts);
|
||||
eleventyConfig.addFilter("convertRelativeLinks", convertRelativeLinks);
|
||||
eleventyConfig.addFilter("entries", entries);
|
||||
eleventyConfig.addFilter("filter", filter);
|
||||
eleventyConfig.addFilter("filterFavourites", filterFavourites);
|
||||
eleventyConfig.addFilter("filterByTags", filterByTags);
|
||||
eleventyConfig.addFilter("formatDate", formatDate);
|
||||
eleventyConfig.addFilter("formatAsUTCString", formatAsUTCString);
|
||||
eleventyConfig.addFilter("isOld", isOld);
|
||||
eleventyConfig.addFilter("keys", keys);
|
||||
eleventyConfig.addFilter("limit", limit);
|
||||
eleventyConfig.addFilter("organizeByDate", organizeByDate);
|
||||
eleventyConfig.addFilter("values", values);
|
||||
eleventyConfig.addFilter("pluralize", pluralize);
|
||||
|
||||
eleventyConfig.addFilter("postcss", postcss);
|
||||
Object.keys(filters).forEach((filterName) => {
|
||||
eleventyConfig.addFilter(filterName, filters[filterName]);
|
||||
});
|
||||
|
||||
// --------------------- Custom Transforms -----------------------
|
||||
eleventyConfig.addPlugin(htmlConfigTransform);
|
||||
|
@ -101,7 +70,6 @@ export default function (eleventyConfig) {
|
|||
["src/assets/fonts/", "src/assets/images"].forEach((path) =>
|
||||
eleventyConfig.addPassthroughCopy(path),
|
||||
);
|
||||
eleventyConfig.addPassthroughCopy("_redirects");
|
||||
|
||||
// --------------------- Markdown -----------------------
|
||||
eleventyConfig.setLibrary("md", markdown);
|
||||
|
@ -109,10 +77,6 @@ export default function (eleventyConfig) {
|
|||
// --------------------- Shortcodes -----------------------
|
||||
eleventyConfig.addShortcode("youtube", liteYoutube);
|
||||
|
||||
eleventyConfig.addFilter("console", function (value) {
|
||||
return util.inspect(value);
|
||||
});
|
||||
|
||||
return {
|
||||
// Optional (default is set): If your site deploys to a subdirectory, change `pathPrefix`, for example with with GitHub pages
|
||||
pathPrefix: "/",
|
||||
|
|
|
@ -8,7 +8,7 @@ description: Read all of my posts.
|
|||
<p>
|
||||
Browse all of my posts, or narrow things down <a href="/tags">via tags</a>.
|
||||
</p>
|
||||
{% set itemsByYear = collections.post | reverse | organizeByDate %}
|
||||
{% set itemsByYear = collections.post | reverse | organizeByYear %}
|
||||
{% set years = itemsByYear | keys | sort("desc") %}
|
||||
<section class="flow">
|
||||
{% for year in years %}
|
||||
|
|
|
@ -15,7 +15,7 @@ eleventyComputed:
|
|||
<p>
|
||||
All posts tagged with "{{ tag }}", or go back to <a href="/tags">all tags</a>.
|
||||
</p>
|
||||
{% set itemsByYear = collections.postsByTag[tag] | reverse | organizeByDate %}
|
||||
{% set itemsByYear = collections.postsByTag[tag] | reverse | organizeByYear %}
|
||||
{% set years = itemsByYear | keys | sort("desc") %}
|
||||
<section class="flow">
|
||||
{% for year in years %}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue