feat(top-tags): surface top tags and genres across relevant views

This commit is contained in:
Cory Dransfeldt 2025-05-15 08:54:59 -07:00
parent e133fd959d
commit 4f15e88074
No known key found for this signature in database
10 changed files with 94 additions and 9 deletions

14
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "coryd.dev",
"version": "5.0.1",
"version": "5.1.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "coryd.dev",
"version": "5.0.1",
"version": "5.1.2",
"license": "MIT",
"dependencies": {
"html-minifier-terser": "7.2.0",
@ -31,7 +31,7 @@
"postcss-import": "^16.1.0",
"postcss-import-ext-glob": "^2.1.1",
"rimraf": "^6.0.1",
"terser": "^5.39.1",
"terser": "^5.39.2",
"truncate-html": "^1.2.1"
},
"engines": {
@ -4486,13 +4486,13 @@
"license": "MIT"
},
"node_modules/terser": {
"version": "5.39.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.39.1.tgz",
"integrity": "sha512-Mm6+uad0ZuDtcV8/4uOZQDQ8RuiC5Pu+iZRedJtF7yA/27sPL7d++In/AJKpWZlU3SYMPPkVfwetn6sgZ66pUA==",
"version": "5.39.2",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.39.2.tgz",
"integrity": "sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg==",
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
"acorn": "^8.14.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},

View file

@ -1,6 +1,6 @@
{
"name": "coryd.dev",
"version": "5.0.2",
"version": "5.1.2",
"description": "The source for my personal site. Built using 11ty (and other tools).",
"type": "module",
"engines": {
@ -54,7 +54,7 @@
"postcss-import": "^16.1.0",
"postcss-import-ext-glob": "^2.1.1",
"rimraf": "^6.0.1",
"terser": "^5.39.1",
"terser": "^5.39.2",
"truncate-html": "^1.2.1"
}
}

View file

@ -0,0 +1,37 @@
CREATE OR REPLACE FUNCTION get_top_tag_groups()
RETURNS JSON AS $$
BEGIN
RETURN json_build_object(
'tags', (
SELECT json_agg(t) FROM (
SELECT tag, COUNT(*) AS usage_count
FROM optimized_tagged_content
WHERE type IN ('article', 'link')
GROUP BY tag
ORDER BY usage_count DESC
LIMIT 10
) t
),
'watching_genres', (
SELECT json_agg(t) FROM (
SELECT tag, COUNT(*) AS usage_count
FROM optimized_tagged_content
WHERE type IN ('tv', 'movies')
GROUP BY tag
ORDER BY usage_count DESC
LIMIT 10
) t
),
'books_genres', (
SELECT json_agg(t) FROM (
SELECT tag, COUNT(*) AS usage_count
FROM optimized_tagged_content
WHERE type = 'books'
GROUP BY tag
ORDER BY usage_count DESC
LIMIT 10
) t
)
);
END;
$$ LANGUAGE plpgsql STABLE;

27
src/data/topTags.js Normal file
View file

@ -0,0 +1,27 @@
import EleventyFetch from "@11ty/eleventy-fetch";
const { POSTGREST_URL, POSTGREST_API_KEY } = process.env;
const fetchTopTags = async () => {
try {
return await EleventyFetch(`${POSTGREST_URL}/rpc/get_top_tag_groups`, {
duration: "1h",
type: "json",
fetchOptions: {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${POSTGREST_API_KEY}`,
},
},
});
} catch (error) {
console.error("Error fetching top tag entries:", error);
return [];
}
};
export default async function () {
console.log(await fetchTopTags())
return await fetchTopTags();
}

View file

@ -0,0 +1 @@
<p><mark>{{ label }}</mark>{%- for tag in tags %} <a href="/tags/{{ tag.tag }}">#{{ tag.tag }}</a>{%- endfor -%}</p>

View file

@ -10,6 +10,10 @@ updated: "now"
{%- assign currentBookCount = books.currentYear | size -%}
<h2 class="page-title">Currently reading</h2>
<p>Here's what I'm reading at the moment. I've finished <mark>{{ currentBookCount }} books</mark> this year. I've read <mark>{{ books.daysRead }}</mark> days in a row and counting.</p>
{% render "blocks/top-tags.liquid"
label:"Top genres"
tags:topTags.books_genres
%}
<p class="book-years">{{ books.years | bookYearLinks }}</p>
{% render "blocks/banners/rss.liquid",
url: "/feeds/books.xml",

View file

@ -15,6 +15,10 @@ updated: "now"
%}
<p>Here's all of the TV and movies I've been watching presented in what is (hopefully) an organized fashion.</p>
<p><a href="/watching/shows/upcoming">You can see all of the shows I've got queued up here.</a></p>
{% render "blocks/top-tags.liquid"
label:"Top genres"
tags:topTags.watching_genres
%}
{% render "blocks/banners/rss.liquid",
url: "/feeds/movies.xml",
text: "Subscribe to my movies feed or follow along on this page"

View file

@ -9,6 +9,10 @@ permalink: "/links/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}
{% if pagination.pageNumber == 0 %}
<h2 class="page-title">Links</h2>
<p>These are links I've liked or otherwise found interesting. They're all added manually, after having been read and, I suppose, properly considered.</p>
{% render "blocks/top-tags.liquid"
label:"Top tags"
tags:topTags.tags
%}
{% render "blocks/banners/rss.liquid",
url: "/feeds/links.xml",
text: "Subscribe to my links feed or follow along on this page"

View file

@ -9,6 +9,10 @@ permalink: "/posts/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}
<h2 class="page-title">Posts</h2>
<p>These are all of my blog posts on this site (I like some more than others).</p>
<p>I tend to write about whatever strikes me, with a focus on development, technology, automation or issues I run into with these things. This is all typically light on editing with and heavy on spur of the moment thoughts.</p>
{% render "blocks/top-tags.liquid"
label:"Top tags"
tags:topTags.tags
%}
{% render "blocks/banners/rss.liquid",
url: "/feeds/posts.xml",
text: "Subscribe to my posts feed or follow along on this page"

View file

@ -6,6 +6,10 @@ description: Search through posts and other content on my site.
<h2 class="page-title">Search</h2>
<p>You can find <a href="/posts">posts</a>, <a href="/links">links</a>, <a href="/music/#artists">artists</a>, genres, <a href="/watching#movies">movies</a>, <a href="/watching#tv">shows</a> and <a href="/books">books</a> via the field below (though it only surfaces movies and shows I've watched and books I've written something about). <a href="/tags">You can also browse my tags list</a>.</p>
{% render "blocks/top-tags.liquid"
label:"Top tags"
tags:topTags.tags
%}
<noscript>
<p><mark>If you're seeing this it means that you've (quite likely) disabled JavaScript (that's a totally valid choice!).</mark> You can search for anything on my site using the form below, but your query will be routed through <a href="https://duckduckgo.com">DuckDuckGo</a>.</p>
<p><mark>Type something in and hit enter.</mark></p>