add related posts and update some styling
This commit is contained in:
@ -6,11 +6,50 @@ export default function(eleventyConfig) {
|
|||||||
return Object.keys(target);
|
return Object.keys(target);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* Exclude all posts with given URLs from a collection list */
|
||||||
|
eleventyConfig.addFilter("excludeFromCollection", function (collection=[], urls=[this.ctx.page.url]) {
|
||||||
|
return collection.filter(post => urls.indexOf(post.url) === -1);
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Filter a collection by a set of tags, returning any that share one or more tags */
|
||||||
|
eleventyConfig.addFilter("filterByTags", function(collection=[], ...requiredTags) {
|
||||||
|
return collection.filter(post => {
|
||||||
|
return requiredTags.flat().some(tag => post.data.tags.includes(tag));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Return n elements from a list */
|
||||||
|
eleventyConfig.addFilter("head", (collection=[], n) => {
|
||||||
|
if(!Array.isArray(collection) || collection.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if( n < 0 ) {
|
||||||
|
return collection.slice(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return collection.slice(0, n);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/* For <time> elements */
|
/* For <time> elements */
|
||||||
eleventyConfig.addFilter("htmlDateString", (dateObj) => {
|
eleventyConfig.addFilter("htmlDateString", (dateObj) => {
|
||||||
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat('yyyy-LL-dd');
|
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat('yyyy-LL-dd');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* What it says on the tin */
|
||||||
|
eleventyConfig.addFilter("randomize", function(array) {
|
||||||
|
// Create a copy of the array to avoid modifying the original
|
||||||
|
let shuffledArray = array.slice();
|
||||||
|
|
||||||
|
// Fisher-Yates shuffle algorithm
|
||||||
|
for (let i = shuffledArray.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
|
[shuffledArray[i], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return shuffledArray;
|
||||||
|
});
|
||||||
|
|
||||||
/* Human-readable dates */
|
/* Human-readable dates */
|
||||||
eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => {
|
eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => {
|
||||||
return DateTime.fromJSDate(dateObj, { zone: zone || "utc" })
|
return DateTime.fromJSDate(dateObj, { zone: zone || "utc" })
|
||||||
@ -22,7 +61,7 @@ export default function(eleventyConfig) {
|
|||||||
return tags.filter(tag => ["all", "posts", "gallery", "reference", "tagPagination"].indexOf(tag) === -1);
|
return tags.filter(tag => ["all", "posts", "gallery", "reference", "tagPagination"].indexOf(tag) === -1);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* What it says */
|
/* What it says on the tin */
|
||||||
eleventyConfig.addFilter("sortAlphabetically", strings =>
|
eleventyConfig.addFilter("sortAlphabetically", strings =>
|
||||||
(strings || []).sort((b, a) => b.localeCompare(a))
|
(strings || []).sort((b, a) => b.localeCompare(a))
|
||||||
);
|
);
|
||||||
|
|||||||
@ -41,8 +41,6 @@
|
|||||||
|
|
||||||
<main id="main">
|
<main id="main">
|
||||||
{{ content | safe }}
|
{{ content | safe }}
|
||||||
|
|
||||||
<hr>
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{% include "footer.njk" %}
|
{% include "footer.njk" %}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ layout: base.njk
|
|||||||
---
|
---
|
||||||
{% css %}{% include "css/post.css" %}{% endcss %}
|
{% css %}{% include "css/post.css" %}{% endcss %}
|
||||||
{% css %}{% include "css/highlighting.css" %}{% endcss %}
|
{% css %}{% include "css/highlighting.css" %}{% endcss %}
|
||||||
|
{% css %}{% include "css/lists.css" %}{% endcss %}
|
||||||
{% js %}{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}{% endjs %}
|
{% js %}{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}{% endjs %}
|
||||||
|
|
||||||
<heading-anchors content="<i class='fa-solid fa-anchor'></i>">
|
<heading-anchors content="<i class='fa-solid fa-anchor'></i>">
|
||||||
@ -43,4 +44,16 @@ layout: base.njk
|
|||||||
{% set newerTitle = newerPost.data.title %}
|
{% set newerTitle = newerPost.data.title %}
|
||||||
{% set inPost = true %}
|
{% set inPost = true %}
|
||||||
{% include "pagination.njk" %}
|
{% include "pagination.njk" %}
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
{% set relevantTags = tags | removeBasicTags %}
|
||||||
|
{% set postlist = collections.posts | filterByTags(relevantTags) | excludeFromCollection([page.url, olderHref, newerHref]) | randomize | head(3) %}
|
||||||
|
{% if postlist.length %}
|
||||||
|
<section class="related-posts">
|
||||||
|
<h2>related posts</h2>
|
||||||
|
{% include "postlist.njk" %}
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</heading-anchors>
|
</heading-anchors>
|
||||||
|
|||||||
15
css/main.css
15
css/main.css
@ -49,8 +49,6 @@
|
|||||||
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
|
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
|
||||||
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
|
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
|
||||||
--color-grey: light-dark(var(--color-grey-dark), var(--color-grey-light));
|
--color-grey: light-dark(var(--color-grey-dark), var(--color-grey-light));
|
||||||
|
|
||||||
--header-offset: 3.1rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Base */
|
/* Base */
|
||||||
@ -71,7 +69,7 @@ main {
|
|||||||
width: 60vw;
|
width: 60vw;
|
||||||
max-width: 1000px;
|
max-width: 1000px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
scroll-margin-top: var(--header-offset);
|
scroll-margin-top: 7rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1050px) {
|
@media (max-width: 1050px) {
|
||||||
@ -90,7 +88,6 @@ main {
|
|||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
line-height: 1.25;
|
line-height: 1.25;
|
||||||
color: var(--color-teal);
|
color: var(--color-teal);
|
||||||
scroll-margin-top: var(--header-offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
@ -99,6 +96,10 @@ h1 {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2, h3, h4, h5, h6 {
|
||||||
|
scroll-margin-top: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
font-size: 2.2rem;
|
font-size: 2.2rem;
|
||||||
@ -260,13 +261,9 @@ time {
|
|||||||
|
|
||||||
/* Horizontal rules */
|
/* Horizontal rules */
|
||||||
hr {
|
hr {
|
||||||
color: var(--color-teal);
|
border: .25rem solid var(--color-pink);
|
||||||
border: .25rem solid var(--color-teal);
|
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
}
|
}
|
||||||
hr:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Used on home, reference, gallery pages */
|
/* Used on home, reference, gallery pages */
|
||||||
.centered {
|
.centered {
|
||||||
|
|||||||
@ -3,9 +3,10 @@ header {
|
|||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
background-color: var(--color-bg);
|
background-color: var(--color-bg);
|
||||||
box-shadow: 0 .25rem .15rem var(--color-shadow);
|
|
||||||
padding: .75rem 0;
|
padding: .75rem 0;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
border-bottom: .5rem solid var(--color-teal);
|
||||||
|
box-shadow: 0 .25rem .15rem var(--color-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Header links, pagination links */
|
/* Header links, pagination links */
|
||||||
@ -198,6 +199,7 @@ header li {
|
|||||||
footer {
|
footer {
|
||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
|
border-top: .5rem solid var(--color-pink);
|
||||||
}
|
}
|
||||||
|
|
||||||
footer ul {
|
footer ul {
|
||||||
|
|||||||
@ -72,4 +72,3 @@
|
|||||||
left: .1rem;
|
left: .1rem;
|
||||||
box-shadow: .05rem .05rem var(--color-shadow);
|
box-shadow: .05rem .05rem var(--color-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ tags:
|
|||||||
- software
|
- software
|
||||||
---
|
---
|
||||||
|
|
||||||
recently I wrote *several* sites using [Eleventy](https://www.11ty.dev/){target="_blank" rel="external"} (4? 5?). Including, over the past few days, this one! That's right, if you're reading this, we're now running on 11ty and hosted by [heckin.technology](https://heckin.technology/){target="_blank" rel="external"}. See ya, GitHub. Won't miss ya.
|
recently I wrote *several* sites using [Eleventy](https://www.11ty.dev/){target="_blank" rel="external"} (4? 5?). Including, over the past few days, rewriting this one! That's right, if you're reading this, we're now running on 11ty and hosted by [heckin.technology](https://heckin.technology/){target="_blank" rel="external"}. See ya, GitHub. Won't miss ya.
|
||||||
|
|
||||||
I've compiled some of the things I've learned in a standalone site: [11ty Lessons](https://inherentlee.codeberg.page/lessons/){target="_blank" rel="external"}.
|
I've compiled some of the things I've learned in a standalone site: [11ty Lessons](https://inherentlee.codeberg.page/lessons/){target="_blank" rel="external"}.
|
||||||
|
|
||||||
@ -26,18 +26,19 @@ while that is useful for *this* site, when building another site I wanted to see
|
|||||||
|
|
||||||
I started by referring to [this GitHub issue about related posts](https://github.com/11ty/eleventy/discussions/2534){target="_blank rel="external"}. I had to fix a few errors that arose from the suggested code.
|
I started by referring to [this GitHub issue about related posts](https://github.com/11ty/eleventy/discussions/2534){target="_blank rel="external"}. I had to fix a few errors that arose from the suggested code.
|
||||||
|
|
||||||
I also wanted to make two changes:
|
I also wanted to make three changes:
|
||||||
|
|
||||||
1. I didn't want to just see posts that shared *all* tags, but rather posts that shared *any* tag
|
1. I didn't want to just see posts that shared *all* tags, but rather posts that shared *any* tag
|
||||||
1. I wanted to randomly add a few posts instead of just getting whatever was first (with a shared tag) in the post order
|
1. I wanted to randomly add a few posts instead of just getting whatever was first (with a shared tag) in the post order
|
||||||
|
1. I wanted to exclude the posts that I could reach with between-post pagination
|
||||||
|
|
||||||
### filters.js
|
### filters.js
|
||||||
|
|
||||||
after adjusting for those needs, I had the following in `filters.js`:
|
after adjusting for those needs, I had the following in `filters.js`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
eleventyConfig.addNunjucksFilter("excludeFromCollection", function (collection=[], pageUrl=this.ctx.page.url) {
|
eleventyConfig.addFilter("excludeFromCollection", function (collection=[], urls=[this.ctx.page.url]) {
|
||||||
return collection.filter(post => post.url !== pageUrl);
|
return collection.filter(post => urls.indexOf(post.url) === -1);
|
||||||
});
|
});
|
||||||
|
|
||||||
eleventyConfig.addFilter("filterByTags", function(collection=[], ...requiredTags) {
|
eleventyConfig.addFilter("filterByTags", function(collection=[], ...requiredTags) {
|
||||||
@ -67,7 +68,12 @@ I used this in my post layout. `filterTagList` comes with the base blog by defau
|
|||||||
{% raw %}
|
{% raw %}
|
||||||
```html
|
```html
|
||||||
{% set relevantTags = tags | filterTagList %}
|
{% set relevantTags = tags | filterTagList %}
|
||||||
{% set postlist = collections.posts | filterByTags(relevantTags) | excludeFromCollection(page.url) | randomize | head(2) %}
|
|
||||||
|
{% set olderPost = collections.posts | getPreviousCollectionItem %}
|
||||||
|
{% set newerPost = collections.posts | getNextCollectionItem %}
|
||||||
|
{% set urlsToExclude = [page.url, olderPost.url, newerPost.url]}
|
||||||
|
|
||||||
|
{% set postlist = collections.posts | filterByTags(relevantTags) | excludeFromCollection(urlsToExclude) | randomize | head(3) %}
|
||||||
{% if postlist.length %}
|
{% if postlist.length %}
|
||||||
<section class="related-posts">
|
<section class="related-posts">
|
||||||
<h2>related posts</h2>
|
<h2>related posts</h2>
|
||||||
|
|||||||
Reference in New Issue
Block a user