Use JSON file for track rendering

This commit is contained in:
thiloho
2025-04-28 03:58:54 +02:00
parent 4a4e1a0ae9
commit 27c42cbe6f
3 changed files with 195 additions and 35 deletions

View File

@@ -1,5 +1,5 @@
import { defineCollection, z } from "astro:content"; import { defineCollection, z } from "astro:content";
import { glob } from "astro/loaders"; import { glob, file } from "astro/loaders";
const blog = defineCollection({ const blog = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }), loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }),
@@ -11,4 +11,17 @@ const blog = defineCollection({
}), }),
}); });
export const collections = { blog }; const tracks = defineCollection({
loader: file("./src/content/tracks.json"),
schema: ({ image }) =>
z.object({
id: z.number().positive(),
title: z.string(),
youtubeLink: z.string().url(),
artist: z.string(),
album: z.string(),
cover: image(),
}),
});
export const collections = { blog, tracks };

170
src/content/tracks.json Normal file
View File

@@ -0,0 +1,170 @@
[
{
"id": 1,
"title": "And So It Was",
"youtubeLink": "https://www.youtube.com/watch?v=xf7iQ5YtvxQ",
"artist": "Black Smurf",
"album": "Black Smurf, Vol. 2",
"cover": "/src/content/album-covers/Black Smurf - And So It Was.jpeg"
},
{
"id": 2,
"title": "Clouds",
"youtubeLink": "https://www.youtube.com/watch?v=CNbzyHDxdTs",
"artist": "Miscél, Hanz",
"album": "The Other Side",
"cover": "/src/content/album-covers/Miscél, Hanz - Clouds.jpeg"
},
{
"id": 3,
"title": "Desire",
"youtubeLink": "https://www.youtube.com/watch?v=VQEhIQxvRXQ",
"artist": "BOCIGE, DYLAN",
"album": "Desire",
"cover": "/src/content/album-covers/BOCIGE, DYLAN - Desire.jpeg"
},
{
"id": 4,
"title": "Destiny",
"youtubeLink": "https://www.youtube.com/watch?v=p-7_FSwTGs4",
"artist": "NEFFEX",
"album": "Destiny: The Collection",
"cover": "/src/content/album-covers/NEFFEX - Destiny.jpeg"
},
{
"id": 5,
"title": "DREAMIN",
"youtubeLink": "https://www.youtube.com/watch?v=Ns07wmgL8dY",
"artist": "SLIGHT",
"album": "SLIGHT COLLECTION VOL. 1",
"cover": "/src/content/album-covers/SLIGHT - DREAMIN.jpeg"
},
{
"id": 6,
"title": "Ewig",
"youtubeLink": "https://www.youtube.com/watch?v=yYHSwBXzD84",
"artist": "makko",
"album": "Lieb mich oder lass es, Pt.1+2",
"cover": "/src/content/album-covers/makko - Ewig.jpeg"
},
{
"id": 7,
"title": "Festnetz",
"youtubeLink": "https://www.youtube.com/watch?v=5GXUEJsYVRA",
"artist": "Dead Dawg, BHZ, Monk",
"album": "Festnetz",
"cover": "/src/content/album-covers/Dead Dawg, BHZ, Monk - Festnetz.jpeg"
},
{
"id": 8,
"title": "hide",
"youtubeLink": "https://www.youtube.com/watch?v=O6jx0yVB5O4",
"artist": "arya x",
"album": "hide",
"cover": "/src/content/album-covers/arya x - hide.jpeg"
},
{
"id": 9,
"title": "Jinzo",
"youtubeLink": "https://www.youtube.com/watch?v=q83S-l9NrMA",
"artist": "YFG Pave",
"album": "Jinzo",
"cover": "/src/content/album-covers/YFG Pave - Jinzo.jpeg"
},
{
"id": 10,
"title": "lights in a hall",
"youtubeLink": "https://www.youtube.com/watch?v=2D60wMAOF_E",
"artist": "Beamon",
"album": "LIGHTS IN A HALL",
"cover": "/src/content/album-covers/Beamon - lights in a hall.jpeg"
},
{
"id": 11,
"title": "Lost In Da Wind",
"youtubeLink": "https://www.youtube.com/watch?v=DNUwhgqCI9U",
"artist": "Jgrxxn, Lil Xav",
"album": "Lost In Da Wind",
"cover": "/src/content/album-covers/Jgrxxn, Lil Xav - Lost In Da Wind.jpeg"
},
{
"id": 12,
"title": "Miracle",
"youtubeLink": "https://www.youtube.com/watch?v=ba4MlsG_Ce8",
"artist": "Calvin Harris, Ellie Goulding",
"album": "Miracle",
"cover": "/src/content/album-covers/Calvin Harris, Ellie Goulding - Miracle.jpeg"
},
{
"id": 13,
"title": "My Girl",
"youtubeLink": "https://www.youtube.com/watch?v=lC5UbInswAs",
"artist": "ilyTOMMY",
"album": "My Girl",
"cover": "/src/content/album-covers/ilyTOMMY - My Girl.jpeg"
},
{
"id": 14,
"title": "Sweet Child O' Mine",
"youtubeLink": "https://www.youtube.com/watch?v=oMfMUfgjiLg",
"artist": "Guns N' Roses",
"album": "Appetite For Destruction",
"cover": "/src/content/album-covers/Guns N' Roses - Sweet Child O' Mine.jpeg"
},
{
"id": 15,
"title": "Ticket nach Ketama",
"youtubeLink": "https://www.youtube.com/watch?v=aNVkkJmwAYE",
"artist": "ARY, Liaze",
"album": "Ticket nach Ketama",
"cover": "/src/content/album-covers/ARY, Liaze - Ticket nach Ketama.jpeg"
},
{
"id": 16,
"title": "Too Lost To Be Found",
"youtubeLink": "https://www.youtube.com/watch?v=G9G_T3NWqf0",
"artist": "CH4YN",
"album": "Too Lost To Be Found",
"cover": "/src/content/album-covers/CH4YN - Too Lost To Be Found.jpeg"
},
{
"id": 17,
"title": "Toronto 2014",
"youtubeLink": "https://www.youtube.com/watch?v=RaaccfAJiOo",
"artist": "Daniel Caesar, Mustafa",
"album": "NEVER ENOUGH",
"cover": "/src/content/album-covers/Daniel Caesar, Mustafa - Toronto 2014.jpeg"
},
{
"id": 18,
"title": "Underworld",
"youtubeLink": "https://www.youtube.com/watch?v=wRoJ4Wp7phU",
"artist": "GDS, Juice Wrld",
"album": "Moonlight",
"cover": "/src/content/album-covers/GDS, Juice Wrld - Underworld.jpeg"
},
{
"id": 19,
"title": "vice city",
"youtubeLink": "https://www.youtube.com/watch?v=yf5Y20Ls7WE",
"artist": "XXXTENTACION",
"album": "vice city",
"cover": "/src/content/album-covers/XXXTENTACION - vice city.jpeg"
},
{
"id": 20,
"title": "War Clips",
"youtubeLink": "https://www.youtube.com/watch?v=dxu0N7mz5Ok",
"artist": "Motat",
"album": "War Clips",
"cover": "/src/content/album-covers/Motat - War Clips.jpeg"
},
{
"id": 21,
"title": "Weather Man",
"youtubeLink": "https://www.youtube.com/watch?v=4BFCN7dg51E",
"artist": "Xavier Wulf, Bones",
"album": "Caves",
"cover": "/src/content/album-covers/Xavier Wulf, Bones - Weather Man.jpeg"
}
]

View File

@@ -1,31 +1,9 @@
--- ---
import PageLayout from "../layouts/PageLayout.astro"; import PageLayout from "../layouts/PageLayout.astro";
import { Image } from "astro:assets"; import { Image } from "astro:assets";
import { parse } from "node:path"; import { getCollection } from "astro:content";
const albumCovers = await Astro.glob("../content/album-covers/*"); const tracks = await getCollection("tracks");
const processedAlbumCovers = albumCovers.map((cover) => {
const filePathWithoutParams = cover.default.src.split("?")[0];
const filename = parse(filePathWithoutParams).name;
const lastDashIndex = filename.lastIndexOf(" - ");
let artists =
lastDashIndex !== -1 ? filename.substring(0, lastDashIndex) : filename;
let title = lastDashIndex !== -1 ? filename.substring(lastDashIndex + 3) : "";
if (import.meta.env.PROD) {
title = title.replace(/\..{8}$/, "");
artists = artists.replaceAll("_", ",");
}
return { cover, artists, title };
});
const sortedAlbumCovers = processedAlbumCovers.sort((a, b) =>
a.title.localeCompare(b.title),
);
--- ---
<PageLayout <PageLayout
@@ -35,26 +13,25 @@ const sortedAlbumCovers = processedAlbumCovers.sort((a, b) =>
<p class="mb-8"> <p class="mb-8">
This is a collection of some of my favourite music tracks, each listed by This is a collection of some of my favourite music tracks, each listed by
artist and song title. Click on an album cover to go straight to the song on artist and song title. Click on an album cover to go straight to the song on
YouTube Music! YouTube!
</p> </p>
<div <div
class="not-prose relative start-1/2 -ms-[min(50vw-1rem,50ch)] grid max-w-[calc(min(100vw-2rem,100ch))] grid-cols-[repeat(auto-fit,minmax(min(100%,200px),1fr))] place-content-center gap-4" class="not-prose relative start-1/2 -ms-[min(50vw-1rem,50ch)] grid max-w-[calc(min(100vw-2rem,100ch))] grid-cols-[repeat(auto-fit,minmax(min(100%,200px),1fr))] place-content-center gap-4"
> >
{ {
sortedAlbumCovers.map(({ cover, artists, title }) => ( tracks.map((track) => (
<figure> <figure>
<a <a href={track.data.youtubeLink}>
href={`https://music.youtube.com/search?q=${encodeURIComponent(`${title} - ${artists}`)}`}
>
<Image <Image
src={cover.default} src={track.data.cover}
alt={`Cover for the song '${title}' by artist(s) '${artists}'`} alt={`Cover for the song '${track.data.title}' by artist(s) '${track.data.artist}'`}
class="border border-neutral-400 duration-300 hover:scale-105 dark:border-neutral-500" class="border border-neutral-400 duration-300 hover:scale-105 dark:border-neutral-500"
/> />
</a> </a>
<figcaption class="flex flex-col p-4 text-center"> <figcaption class="flex flex-col p-4 text-center">
<p class="text-lg font-bold">{title}</p> <p class="text-lg font-bold">{track.data.title}</p>
<p>{artists}</p> <p>{track.data.artist}</p>
<p class="text-sm">{track.data.album}</p>
</figcaption> </figcaption>
</figure> </figure>
)) ))