Migrate to Astro 5
This commit is contained in:
parent
5d701069e9
commit
bb1e533a00
129 changed files with 1408 additions and 1448 deletions
|
|
@ -8,6 +8,6 @@ import GalleryLayout from "@layouts/GalleryLayout.astro";
|
|||
<meta name="description" content="The requested link could not be found." />
|
||||
</Fragment>
|
||||
<h1 class="m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">404 – Not Found</h1>
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden="true" />
|
||||
<p class="my-4">The requested link could not be found. Make sure that the URL is correct.</p>
|
||||
</GalleryLayout>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { APIRoute, GetStaticPaths } from "astro";
|
||||
import { getCollection, type CollectionEntry, getEntries } from "astro:content";
|
||||
import type { PostWebsite } from "@content/config";
|
||||
import type { PostWebsite } from "src/content.config";
|
||||
import { t } from "@i18n";
|
||||
import { formatCopyrightedCharacters } from "@utils/format_copyrighted_characters";
|
||||
import { markdownToBbcode } from "@utils/markdown_to_bbcode";
|
||||
|
|
@ -36,7 +36,7 @@ type Props = {
|
|||
};
|
||||
|
||||
type Params = {
|
||||
slug: CollectionEntry<"stories">["slug"];
|
||||
id: CollectionEntry<"stories">["id"];
|
||||
};
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
|
|
@ -44,7 +44,7 @@ export const getStaticPaths: GetStaticPaths = async () => {
|
|||
return [];
|
||||
}
|
||||
return (await getCollection("stories")).map((story) => ({
|
||||
params: { slug: story.slug } satisfies Params,
|
||||
params: { id: story.id } satisfies Params,
|
||||
props: { story } satisfies Props,
|
||||
}));
|
||||
};
|
||||
|
|
@ -52,6 +52,9 @@ export const getStaticPaths: GetStaticPaths = async () => {
|
|||
export const GET: APIRoute<Props, Params> = async ({ props: { story }, site }) => {
|
||||
try {
|
||||
const { lang } = story.data;
|
||||
if (!story.body) {
|
||||
throw new Error("Story body cannot be empty");
|
||||
}
|
||||
const copyrightedCharacters = await formatCopyrightedCharacters(story.data.copyrightedCharacters);
|
||||
const authorsList = await getEntries(story.data.authors);
|
||||
const commissionersList = story.data.commissioners && (await getEntries(story.data.commissioners));
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
---
|
||||
import type { GetStaticPaths } from "astro";
|
||||
import { type CollectionEntry, getCollection } from "astro:content";
|
||||
import { type CollectionEntry, getCollection, render } from "astro:content";
|
||||
import { PUBLISH_DRAFTS } from "astro:env/server";
|
||||
import BlogPostLayout from "@layouts/BlogPostLayout.astro";
|
||||
|
||||
type Props = CollectionEntry<"blog">;
|
||||
|
||||
type Params = {
|
||||
slug: CollectionEntry<"blog">["slug"];
|
||||
id: CollectionEntry<"blog">["id"];
|
||||
};
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
|
|
@ -15,13 +15,13 @@ export const getStaticPaths: GetStaticPaths = async () => {
|
|||
return posts
|
||||
.filter((post) => import.meta.env.DEV || PUBLISH_DRAFTS || !post.data.isDraft)
|
||||
.map((post) => ({
|
||||
params: { slug: post.slug } satisfies Params,
|
||||
params: { id: post.id } satisfies Params,
|
||||
props: post satisfies Props,
|
||||
}));
|
||||
};
|
||||
|
||||
const post = Astro.props;
|
||||
const { Content } = await post.render();
|
||||
const { Content } = await render(post);
|
||||
---
|
||||
|
||||
<BlogPostLayout {...post.data}>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import rss from "@astrojs/rss";
|
||||
import type { APIRoute } from "astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import { getCollection, render } from "astro:content";
|
||||
import { blogFeedItem, type EntryWithPubDate } from "@utils/feed";
|
||||
|
||||
const MAX_ITEMS = 8;
|
||||
|
|
@ -22,7 +22,7 @@ export const GET: APIRoute = async ({ site }) => {
|
|||
xmlns: { atom: "http://www.w3.org/2005/Atom" },
|
||||
customData: `<link href="${new URL("blog", site)}" rel="alternate" type="text/html" /><atom:link href="${new URL("blog/feed.xml", site)}" rel="self" type="application/rss+xml" />`,
|
||||
items: await Promise.all(
|
||||
posts.map(async ({ data, slug, render }) => blogFeedItem(site, data, slug, (await render()).Content)),
|
||||
posts.map(async (post) => blogFeedItem(site, post.data, post.id, (await render(post)).Content)),
|
||||
),
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const posts = await Promise.all(
|
|||
<meta name="description" content="A collection of blog posts written by Bad Manners." />
|
||||
</Fragment>
|
||||
<h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Blog</h1>
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden="true" />
|
||||
<div class="my-4 flex w-full">
|
||||
<p class="p-summary grow">Whatever has been rattling in my head as of late.</p>
|
||||
<a class="u-url text-link ml-2 p-1 md:mr-5" href="/blog/feed.xml" rel="alternate" title="RSS feed" data-tooltip>
|
||||
|
|
@ -39,7 +39,7 @@ const posts = await Promise.all(
|
|||
<li class="h-entry">
|
||||
<a
|
||||
class="u-url text-link hover:underline focus:underline"
|
||||
href={`/blog/${post.slug}`}
|
||||
href={`/blog/${post.id}`}
|
||||
title={markdownToPlaintext(post.data.description)}
|
||||
data-tooltip
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import rss from "@astrojs/rss";
|
||||
import type { APIRoute } from "astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import { getCollection, render } from "astro:content";
|
||||
import { blogFeedItem, gameFeedItem, storyFeedItem, type EntryWithPubDate } from "@utils/feed";
|
||||
|
||||
const MAX_ITEMS = 8;
|
||||
|
|
@ -36,17 +36,17 @@ export const GET: APIRoute = async ({ site }) => {
|
|||
customData: `<link href="${site}" rel="alternate" type="text/html" /><atom:link href="${new URL("feed.xml", site)}" rel="self" type="application/rss+xml" />`,
|
||||
items: await Promise.all(
|
||||
[
|
||||
stories.map(({ data, slug, render }) => ({
|
||||
date: data.pubDate,
|
||||
fn: async () => storyFeedItem(site, data, slug, (await render()).Content),
|
||||
stories.map((story) => ({
|
||||
date: story.data.pubDate,
|
||||
fn: async () => storyFeedItem(site, story.data, story.id, (await render(story)).Content),
|
||||
})),
|
||||
games.map(({ data, slug, render }) => ({
|
||||
date: data.pubDate,
|
||||
fn: async () => gameFeedItem(site, data, slug, (await render()).Content),
|
||||
games.map((game) => ({
|
||||
date: game.data.pubDate,
|
||||
fn: async () => gameFeedItem(site, game.data, game.id, (await render(game)).Content),
|
||||
})),
|
||||
posts.map(({ data, slug, render }) => ({
|
||||
date: data.pubDate,
|
||||
fn: async () => blogFeedItem(site, data, slug, (await render()).Content),
|
||||
posts.map((post) => ({
|
||||
date: post.data.pubDate,
|
||||
fn: async () => blogFeedItem(site, post.data, post.id, (await render(post)).Content),
|
||||
})),
|
||||
]
|
||||
.flat()
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
---
|
||||
import type { GetStaticPaths } from "astro";
|
||||
import { type CollectionEntry, getCollection } from "astro:content";
|
||||
import { type CollectionEntry, getCollection, render } from "astro:content";
|
||||
import GameLayout from "@layouts/GameLayout.astro";
|
||||
import { PUBLISH_DRAFTS } from "astro:env/server";
|
||||
|
||||
type Props = CollectionEntry<"games">;
|
||||
|
||||
type Params = {
|
||||
slug: CollectionEntry<"games">["slug"];
|
||||
id: CollectionEntry<"games">["id"];
|
||||
};
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
|
|
@ -15,13 +15,13 @@ export const getStaticPaths: GetStaticPaths = async () => {
|
|||
return games
|
||||
.filter((game) => import.meta.env.DEV || PUBLISH_DRAFTS || !game.data.isDraft)
|
||||
.map((game) => ({
|
||||
params: { slug: game.slug } satisfies Params,
|
||||
params: { id: game.id } satisfies Params,
|
||||
props: game satisfies Props,
|
||||
}));
|
||||
};
|
||||
|
||||
const game = Astro.props;
|
||||
const { Content } = await game.render();
|
||||
const { Content } = await render(game);
|
||||
---
|
||||
|
||||
<GameLayout {...game.data}>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import rss from "@astrojs/rss";
|
||||
import type { APIRoute } from "astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import { getCollection, render } from "astro:content";
|
||||
import { gameFeedItem, type EntryWithPubDate } from "@utils/feed";
|
||||
|
||||
const MAX_ITEMS = 8;
|
||||
|
|
@ -9,7 +9,7 @@ export const GET: APIRoute = async ({ site }) => {
|
|||
if (!site) {
|
||||
throw new Error("site is required.");
|
||||
}
|
||||
const stories = (
|
||||
const games = (
|
||||
(await getCollection("games", (game) => !game.data.isDraft && game.data.pubDate)) as EntryWithPubDate<"games">[]
|
||||
)
|
||||
.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
|
||||
|
|
@ -22,7 +22,7 @@ export const GET: APIRoute = async ({ site }) => {
|
|||
xmlns: { atom: "http://www.w3.org/2005/Atom" },
|
||||
customData: `<link href="${new URL("games", site)}" rel="alternate" type="text/html" /><atom:link href="${new URL("games/feed.xml", site)}" rel="self" type="application/rss+xml" />`,
|
||||
items: await Promise.all(
|
||||
stories.map(async ({ data, slug, render }) => gameFeedItem(site, data, slug, (await render()).Content)),
|
||||
games.map(async (game) => gameFeedItem(site, game.data, game.id, (await render(game)).Content)),
|
||||
),
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const games = await Promise.all(
|
|||
<meta name="description" content="A safe vore videogame created by Bad Manners." />
|
||||
</Fragment>
|
||||
<h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Games</h1>
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden="true" />
|
||||
<div class="my-4 flex w-full">
|
||||
<p class="p-summary grow">A game that I've gone and done.</p>
|
||||
<a class="u-url text-link ml-2 p-1 md:mr-5" href="/games/feed.xml" rel="alternate" title="RSS feed" data-tooltip>
|
||||
|
|
@ -38,7 +38,7 @@ const games = await Promise.all(
|
|||
<li class="h-entry">
|
||||
<a
|
||||
class="u-url text-link hover:underline focus:underline"
|
||||
href={`/games/${game.slug}`}
|
||||
href={`/games/${game.id}`}
|
||||
title={t(game.data.lang, "game/warnings", game.data.platforms, game.data.contentWarning)}
|
||||
data-tooltip
|
||||
>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ async function storyEntry(story: EntryWithPubDate<"stories">): Promise<LatestIte
|
|||
type: "Story",
|
||||
isAgeRestricted: story.data.isAgeRestricted,
|
||||
thumbnail: story.data.thumbnail,
|
||||
href: `/stories/${story.slug}`,
|
||||
href: `/stories/${story.id}`,
|
||||
title: story.data.title,
|
||||
authors: await getEntries(story.data.authors),
|
||||
lang: story.data.lang,
|
||||
|
|
@ -82,7 +82,7 @@ async function gameEntry(game: EntryWithPubDate<"games">): Promise<LatestItemsEn
|
|||
type: "Game",
|
||||
isAgeRestricted: game.data.isAgeRestricted,
|
||||
thumbnail: game.data.thumbnail,
|
||||
href: `/games/${game.slug}`,
|
||||
href: `/games/${game.id}`,
|
||||
title: game.data.title,
|
||||
authors: await getEntries(game.data.authors),
|
||||
lang: game.data.lang,
|
||||
|
|
@ -96,7 +96,7 @@ async function blogEntry(post: EntryWithPubDate<"blog">): Promise<LatestItemsEnt
|
|||
type: "Blog post",
|
||||
isAgeRestricted: post.data.isAgeRestricted,
|
||||
thumbnail: post.data.thumbnail,
|
||||
href: `/blog/${post.slug}`,
|
||||
href: `/blog/${post.id}`,
|
||||
title: post.data.title,
|
||||
authors: await getEntries(post.data.authors),
|
||||
lang: post.data.lang,
|
||||
|
|
@ -157,7 +157,7 @@ if (featuredItems.length > MAX_FEATURED_ITEMS) {
|
|||
<meta name="description" content="Find stories, games, and blog posts made by Bad Manners." />
|
||||
</Fragment>
|
||||
<h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Gallery</h1>
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden="true" />
|
||||
<div class="p-summary">
|
||||
<div class="my-4 flex">
|
||||
<p class="grow">
|
||||
|
|
|
|||
|
|
@ -33,6 +33,6 @@ const bundlePath = `${import.meta.env.BASE_URL}pagefind/`;
|
|||
<meta name="description" content="Search for stories, games, and blog posts made by Bad Manners." />
|
||||
</Fragment>
|
||||
<h1 class="m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Search</h1>
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden="true" />
|
||||
<div id="search" class="pagefind-ui pagefind-init my-4" data-pagefind-ui data-bundle-path={bundlePath}></div>
|
||||
</GalleryLayout>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import type { GetStaticPaths } from "astro";
|
||||
import { type CollectionEntry, getCollection } from "astro:content";
|
||||
import { type CollectionEntry, getCollection, render } from "astro:content";
|
||||
import getReadingTime from "reading-time";
|
||||
import StoryLayout from "@layouts/StoryLayout.astro";
|
||||
import { PUBLISH_DRAFTS } from "astro:env/server";
|
||||
|
|
@ -8,7 +8,7 @@ import { PUBLISH_DRAFTS } from "astro:env/server";
|
|||
type Props = CollectionEntry<"stories">;
|
||||
|
||||
type Params = {
|
||||
slug: CollectionEntry<"stories">["slug"];
|
||||
id: CollectionEntry<"stories">["id"];
|
||||
};
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
|
|
@ -16,22 +16,25 @@ export const getStaticPaths: GetStaticPaths = async () => {
|
|||
return stories
|
||||
.filter((story) => import.meta.env.DEV || PUBLISH_DRAFTS || !story.data.isDraft)
|
||||
.map((story) => ({
|
||||
params: { slug: story.slug } satisfies Params,
|
||||
params: { id: story.id } satisfies Params,
|
||||
props: story satisfies Props,
|
||||
}));
|
||||
};
|
||||
|
||||
const story = Astro.props;
|
||||
if (!story.body) {
|
||||
throw new Error("Story body cannot be empty");
|
||||
}
|
||||
const readingTime = getReadingTime(story.body);
|
||||
if (story.data.wordCount && Math.abs(story.data.wordCount - readingTime.words) >= 150) {
|
||||
console.warn(
|
||||
`WARNING: "wordCount" differs greatly from actual word count for published story ` +
|
||||
`${story.data.title} ("${story.slug}") ` +
|
||||
`${story.data.title} ("${story.id}") ` +
|
||||
`(expected ~${story.data.wordCount}, found ${readingTime.words})`,
|
||||
);
|
||||
}
|
||||
|
||||
const { Content } = await story.render();
|
||||
const { Content } = await render(story);
|
||||
---
|
||||
|
||||
<StoryLayout {...story.data}>
|
||||
|
|
@ -35,7 +35,7 @@ const totalPages = Math.ceil(page.total / page.size);
|
|||
<meta name="description" content="Safe vore stories written by Bad Manners." />
|
||||
</Fragment>
|
||||
<h1 class="p-name m-2 grow text-3xl font-semibold text-stone-800 dark:text-stone-100">Stories</h1>
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden="true" />
|
||||
<div class="my-4 flex">
|
||||
<p class="p-summary grow">The bulk of my content!</p>
|
||||
<a class="u-url text-link ml-2 p-1 md:mr-5" href="/stories/feed.xml" rel="alternate" title="RSS feed" data-tooltip>
|
||||
|
|
@ -84,7 +84,7 @@ const totalPages = Math.ceil(page.total / page.size);
|
|||
<li class="h-entry break-inside-avoid">
|
||||
<a
|
||||
class="u-url text-link hover:underline focus:underline"
|
||||
href={`/stories/${story.slug}`}
|
||||
href={`/stories/${story.id}`}
|
||||
title={t(story.data.lang, "story/warnings", story.data.wordCount, story.data.contentWarning)}
|
||||
data-tooltip
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import rss from "@astrojs/rss";
|
||||
import type { APIRoute } from "astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import { getCollection, render } from "astro:content";
|
||||
import { storyFeedItem, type EntryWithPubDate } from "@utils/feed";
|
||||
|
||||
const MAX_ITEMS = 8;
|
||||
|
|
@ -25,7 +25,7 @@ export const GET: APIRoute = async ({ site }) => {
|
|||
xmlns: { atom: "http://www.w3.org/2005/Atom" },
|
||||
customData: `<link href="${new URL("stories/1", site)}" rel="alternate" type="text/html" /><atom:link href="${new URL("stories/feed.xml", site)}" rel="self" type="application/rss+xml" />`,
|
||||
items: await Promise.all(
|
||||
stories.map(async ({ data, slug, render }) => storyFeedItem(site, data, slug, (await render()).Content)),
|
||||
stories.map(async (story) => storyFeedItem(site, story.data, story.id, (await render(story)).Content)),
|
||||
),
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ const stories = (await getCollection(
|
|||
(story) => !story.data.isDraft && story.data.pubDate && story.data.series?.id === series.id,
|
||||
)) as StoryWithPubDate[];
|
||||
const mainChapters = stories
|
||||
.filter((story) => story.slug.startsWith("the-lost-of-the-marshes/chapter-"))
|
||||
.filter((story) => story.id.startsWith("the-lost-of-the-marshes/chapter-"))
|
||||
.sort((a, b) => a.data.pubDate.getTime() - b.data.pubDate.getTime());
|
||||
const bonusChapters = stories
|
||||
.filter((story) => story.slug.startsWith("the-lost-of-the-marshes/bonus-"))
|
||||
.filter((story) => story.id.startsWith("the-lost-of-the-marshes/bonus-"))
|
||||
.sort((a, b) => a.data.pubDate.getTime() - b.data.pubDate.getTime());
|
||||
const mainChaptersWithSummaries = mainChapters.filter((story) => story.data.summary);
|
||||
---
|
||||
|
|
@ -31,7 +31,7 @@ const mainChaptersWithSummaries = mainChapters.filter((story) => story.data.summ
|
|||
/>
|
||||
</Fragment>
|
||||
<h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">{series.data.name}</h1>
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden="true" />
|
||||
<p class="p-summary my-4">
|
||||
This is the main hub for the story of Quince, Nikili, and Suu, as well as all bonus content.
|
||||
</p>
|
||||
|
|
@ -59,7 +59,7 @@ const mainChaptersWithSummaries = mainChapters.filter((story) => story.data.summ
|
|||
.filter((story) => story.data.summary)
|
||||
.map((story) => (
|
||||
<li class="my-2">
|
||||
<a class="text-link underline" href={`/stories/${story.slug}`}>
|
||||
<a class="text-link underline" href={`/stories/${story.id}`}>
|
||||
{story.data.shortTitle || story.data.title}:
|
||||
</a>
|
||||
<span>{story.data.summary}</span>
|
||||
|
|
@ -72,7 +72,7 @@ const mainChaptersWithSummaries = mainChapters.filter((story) => story.data.summ
|
|||
{
|
||||
mainChapters.map((story) => (
|
||||
<li class="h-entry break-inside-avoid">
|
||||
<a class="u-url text-link hover:underline focus:underline" href={`/stories/${story.slug}`}>
|
||||
<a class="u-url text-link hover:underline focus:underline" href={`/stories/${story.id}`}>
|
||||
{story.data.thumbnail ? (
|
||||
<Image
|
||||
class="u-photo w-48"
|
||||
|
|
@ -106,7 +106,7 @@ const mainChaptersWithSummaries = mainChapters.filter((story) => story.data.summ
|
|||
{
|
||||
bonusChapters.map((story) => (
|
||||
<li class="h-entry break-inside-avoid">
|
||||
<a class="u-url text-link hover:underline focus:underline" href={`/stories/${story.slug}`}>
|
||||
<a class="u-url text-link hover:underline focus:underline" href={`/stories/${story.id}`}>
|
||||
{story.data.thumbnail ? (
|
||||
<Image
|
||||
class="u-photo w-48"
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ if (uncategorizedTagsSet.size > 0) {
|
|||
<meta name="description" content="Find all content by Bad Manners with a specific tag." />
|
||||
</Fragment>
|
||||
<h1 class="m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">All available tags</h1>
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden="true" />
|
||||
<section class="my-2" aria-labelledby="category-series">
|
||||
<h2 id="category-series" class="p-2 text-xl font-semibold text-stone-800 dark:text-stone-100">Series</h2>
|
||||
<ul class="list-disc pl-8">
|
||||
|
|
|
|||
|
|
@ -28,6 +28,6 @@ const { badTag } = Astro.props;
|
|||
<meta name="robots" content="noindex" />
|
||||
</Fragment>
|
||||
<h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Works tagged "{badTag}"</h1>
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden="true" />
|
||||
<p class="my-4">No.</p>
|
||||
</GalleryLayout>
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ const totalWorksWithTag = t(
|
|||
<meta name="description" content={`Works by Bad Manners tagged with "${props.tag}".`} />
|
||||
</Fragment>
|
||||
<h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Works tagged "{props.tag}"</h1>
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
|
||||
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden="true" />
|
||||
<div class="my-4">
|
||||
<Prose>
|
||||
{description ? <Markdown of={description} /> : null}
|
||||
|
|
@ -167,7 +167,7 @@ const totalWorksWithTag = t(
|
|||
<li class="h-entry break-inside-avoid">
|
||||
<a
|
||||
class="u-url text-link hover:underline focus:underline"
|
||||
href={`/stories/${story.slug}`}
|
||||
href={`/stories/${story.id}`}
|
||||
title={t(story.data.lang, "story/warnings", story.data.wordCount, story.data.contentWarning)}
|
||||
data-tooltip
|
||||
>
|
||||
|
|
@ -238,7 +238,7 @@ const totalWorksWithTag = t(
|
|||
<li class="h-entry break-inside-avoid">
|
||||
<a
|
||||
class="u-url text-link hover:underline focus:underline"
|
||||
href={`/games/${game.slug}`}
|
||||
href={`/games/${game.id}`}
|
||||
title={t(game.data.lang, "game/warnings", game.data.platforms, game.data.contentWarning)}
|
||||
data-tooltip
|
||||
>
|
||||
|
|
@ -305,7 +305,7 @@ const totalWorksWithTag = t(
|
|||
<li class="h-entry break-inside-avoid">
|
||||
<a
|
||||
class="u-url text-link hover:underline focus:underline"
|
||||
href={`/blog/${post.slug}`}
|
||||
href={`/blog/${post.id}`}
|
||||
title={markdownToPlaintext(post.data.description)}
|
||||
data-tooltip
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue