Add Pagefind searching

This commit is contained in:
Bad Manners 2024-04-03 20:06:21 -03:00
parent 568b7709ec
commit 877c02ccfc
14 changed files with 828 additions and 207 deletions

View file

@ -1,6 +1,7 @@
import { defineConfig } from "astro/config";
import tailwindIntegration from "@astrojs/tailwind";
import markdownIntegration from "@astropub/md";
import pagefindIntegration from "astro-pagefind";
// https://astro.build/config
export default defineConfig({
@ -10,6 +11,7 @@ export default defineConfig({
applyBaseStyles: false,
}),
markdownIntegration(),
pagefindIntegration(),
],
markdown: {
smartypants: false,

892
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,37 +1,39 @@
{
"name": "gallery-badmanners-xyz",
"type": "module",
"version": "1.2.2",
"version": "1.3.0",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro check && astro build",
"build": "astro check --minimumSeverity warning && astro build",
"preview": "astro preview",
"astro": "astro",
"prettier": "prettier . --write",
"export-story": "tsx scripts/export-story.ts"
},
"dependencies": {
"@astrojs/check": "^0.5.9",
"@astrojs/check": "^0.5.10",
"@astrojs/rss": "^4.0.5",
"@astrojs/tailwind": "^5.1.0",
"@astropub/md": "^0.4.0",
"@tailwindcss/typography": "^0.5.10",
"@tailwindcss/typography": "^0.5.12",
"@types/sanitize-html": "^2.11.0",
"astro": "^4.5.4",
"astro": "^4.5.16",
"astro-pagefind": "^1.5.0",
"github-slugger": "^2.0.0",
"marked": "^12.0.1",
"pagefind": "^1.1.0",
"sanitize-html": "^2.13.0",
"tailwindcss": "^3.4.1",
"tailwindcss": "^3.4.3",
"tiny-decode": "^0.1.3",
"typescript": "^5.4.2"
"typescript": "^5.4.4"
},
"devDependencies": {
"commander": "^12.0.0",
"fetch-retry": "^6.0.0",
"prettier": "^3.2.5",
"prettier-plugin-astro": "^0.13.0",
"prettier-plugin-tailwindcss": "^0.5.12",
"tsx": "^4.7.1"
"prettier-plugin-tailwindcss": "^0.5.13",
"tsx": "^4.7.2"
}
}

View file

@ -28,5 +28,11 @@
href="/tags">Tags</a
>
</li>
<li>
<a
class="hover:text-green-800 hover:underline focus:text-green-800 focus:underline dark:hover:text-bm-300 dark:focus:text-bm-300"
href="/search">Search</a
>
</li>
</ul>
</nav>

View file

@ -6,19 +6,21 @@ import logoBM from "../assets/images/logo_bm.png";
type Props = {
pageTitle?: string;
enablePagefind?: boolean;
};
const { pageTitle } = Astro.props;
const { pageTitle, enablePagefind } = Astro.props;
const logo = await getImage({ src: logoBM, width: 192 });
---
<BaseLayout pageTitle={pageTitle}>
<Fragment slot="head">
<meta content={pageTitle || "Bad Manners"} property="og:title" />
<meta property="og:title" content={pageTitle || "Bad Manners"} />
<slot name="head-description" />
<meta content={Astro.url} property="og:url" />
<meta content={logo.src} property="og:image" />
<meta content="#7DD05A" data-react-helmet="true" name="theme-color" />
<meta property="og:url" content={Astro.url} />
<meta property="og:image" content={logo.src} />
<meta property="og:image:alt" content="Logo for Bad Manners" />
<meta name="theme-color" content="#7DD05A" data-react-helmet="true" />
</Fragment>
<div
class="flex min-h-screen flex-col bg-stone-200 text-stone-800 md:flex-row dark:bg-stone-800 dark:text-stone-200 print:bg-none"
@ -68,7 +70,7 @@ const logo = await getImage({ src: logoBM, width: 192 });
</button>
</div>
</div>
<main class="ml-0 max-w-6xl px-2 pb-12 pt-4 md:ml-60 md:px-4 print:pb-0">
<main class="ml-0 max-w-6xl px-2 pb-12 pt-4 md:ml-60 md:px-4 print:pb-0" data-pagefind-body={enablePagefind ? "" : undefined}>
<slot />
</main>
</div>

View file

@ -58,11 +58,14 @@ const thumbnail =
<BaseLayout pageTitle={props.title}>
<Fragment slot="head">
<meta content={props.title} property="og:title" />
<meta content={props.contentWarning} property="og:description" />
<meta content={Astro.url} property="og:url" />
{thumbnail ? <meta content={thumbnail.src} property="og:image" /> : null}
<meta content="#7DD05A" data-react-helmet="true" name="theme-color" />
<meta property="og:title" content={props.title} data-pagefind-meta="title[content]" />
<meta property="og:description" content={props.contentWarning} />
<meta property="og:url" content={Astro.url} data-pagefind-meta="url[content]" />
{thumbnail ? <Fragment>
<meta content={thumbnail.src} property="og:image" data-pagefind-meta="image[content]" />
<meta property="og:image:alt" content={`Cover art for ${props.title}`} data-pagefind-meta="image_alt[content]" />
</Fragment> : null}
<meta name="theme-color" content="#7DD05A" data-react-helmet="true" />
</Fragment>
<div
id="top"
@ -118,6 +121,8 @@ const thumbnail =
</div>
<main
class="mx-auto max-w-3xl rounded-lg bg-stone-50 px-2 pb-4 pt-1 shadow-sm dark:bg-stone-900 print:max-w-full print:bg-none print:shadow-none"
data-pagefind-body
data-pagefind-meta="type:game"
>
<h1 id="game-title" class="px-2 pt-2 font-serif text-3xl font-semibold text-stone-800 dark:text-stone-100">
{props.title}
@ -151,6 +156,7 @@ const thumbnail =
width={props.thumbnailWidth}
height={props.thumbnailHeight}
class="mx-auto my-5 shadow-lg"
data-pagefind-meta="image[src],image_alt[alt]"
/>
</Fragment>
) : null
@ -180,6 +186,8 @@ const thumbnail =
day: "numeric",
year: "numeric",
})}
data-pagefind-index-attrs="aria-description"
data-pagefind-meta={`date:${props.pubDate.toISOString().slice(undefined, 10)}`}
>
{t(props.lang, "story/publish_date", props.pubDate.toISOString().slice(undefined, 10))}
</p>

View file

@ -68,11 +68,14 @@ const thumbnail =
<BaseLayout pageTitle={props.title}>
<Fragment slot="head">
<meta content={props.title} property="og:title" />
<meta content={`Word count: ${props.wordCount}. ${props.contentWarning}`} property="og:description" />
<meta content={Astro.url} property="og:url" />
{thumbnail ? <meta content={thumbnail.src} property="og:image" /> : null}
<meta content="#7DD05A" data-react-helmet="true" name="theme-color" />
<meta property="og:title" content={props.title} data-pagefind-meta="title[content]" />
<meta property="og:description" content={`Word count: ${props.wordCount}. ${props.contentWarning}`} />
<meta property="og:url" content={Astro.url} data-pagefind-meta="url[content]" />
{thumbnail ? <Fragment>
<meta content={thumbnail.src} property="og:image" data-pagefind-meta="image[content]" />
<meta property="og:image:alt" content={`Cover art for ${props.shortTitle || props.title}`} data-pagefind-meta="image_alt[content]" />
</Fragment> : null}
<meta name="theme-color" content="#7DD05A" data-react-helmet="true" />
</Fragment>
<div
id="top"
@ -130,6 +133,8 @@ const thumbnail =
</div>
<main
class="mx-auto max-w-3xl rounded-lg bg-stone-50 px-2 pb-4 pt-1 shadow-sm dark:bg-stone-900 print:max-w-full print:bg-none print:shadow-none"
data-pagefind-body
data-pagefind-meta="type:story"
>
{
prev || next ? (
@ -210,7 +215,7 @@ const thumbnail =
<img
loading="eager"
src={thumbnail.src}
alt={`Cover art for ${props.title}`}
alt={`Cover art for ${props.shortTitle || props.title}`}
width={props.thumbnailWidth}
height={props.thumbnailHeight}
class="mx-auto my-5 shadow-lg"
@ -243,6 +248,8 @@ const thumbnail =
day: "numeric",
year: "numeric",
})}
data-pagefind-index-attrs="aria-description"
data-pagefind-meta={`date:${props.pubDate.toISOString().slice(undefined, 10)}`}
>
{t(props.lang, "story/publish_date", props.pubDate.toISOString().slice(undefined, 10))}
</p>

View file

@ -9,7 +9,7 @@ const games = (await getCollection("games", (game) => !game.data.isDraft)).sort(
---
<GalleryLayout pageTitle="Games">
<meta slot="head-description" content="Bad Manners || A game that I've gone and done." property="og:description" />
<meta slot="head-description" property="og:description" content="Bad Manners || A game that I've gone and done." />
<h1 class="m-2 text-2xl font-semibold text-stone-800 dark:text-stone-100">Games</h1>
<p class="my-4">A game that I've gone and done.</p>
<ul class="my-6 flex flex-wrap items-start justify-center gap-4 text-center md:justify-normal">

View file

@ -42,7 +42,7 @@ const latestItems: LatestItemsEntry[] = [
---
<GalleryLayout pageTitle="Gallery">
<meta slot="head-description" content="Bad Manners || Welcome to my gallery!" property="og:description" />
<meta slot="head-description" property="og:description" content="Bad Manners || Welcome to my gallery!" />
<h1 class="m-2 text-2xl font-semibold text-stone-800 dark:text-stone-100">My gallery</h1>
<p class="my-4">Welcome to my gallery! Use the navigation menu to navigate through my content.</p>
<ul class="list-disc pl-8">

11
src/pages/search.astro Normal file
View file

@ -0,0 +1,11 @@
---
import SearchComponent from "astro-pagefind/components/Search";
import GalleryLayout from "../layouts/GalleryLayout.astro";
---
<GalleryLayout pageTitle="Search">
<meta slot="head-description" property="og:description" content="Bad Manners || Search" />
<h1 class="m-2 text-2xl font-semibold text-stone-800 dark:text-stone-100">Search</h1>
<SearchComponent id="search" className="my-4 pagefind-ui" />
</GalleryLayout>

View file

@ -21,7 +21,7 @@ const totalPages = Math.ceil(page.total / page.size);
---
<GalleryLayout pageTitle="Stories">
<meta slot="head-description" content={`Bad Manners || ${page.total} stories.`} property="og:description" />
<meta slot="head-description" property="og:description" content={`Bad Manners || ${page.total} stories.`} />
<h1 class="m-2 text-2xl font-semibold text-stone-800 dark:text-stone-100">Stories</h1>
<p class="my-4">The bulk of my content!</p>
<p class="text-center font-light text-stone-950 dark:text-white">

View file

@ -15,16 +15,12 @@ const bonusChapters = stories
const mainChaptersWithSummaries = mainChapters.filter((story) => story.data.summary);
---
<GalleryLayout pageTitle={series.data.name}>
<meta
slot="head-description"
content={`Bad Manners || The story of Quince, Nikili, and Suu.`}
property="og:description"
/>
<GalleryLayout pageTitle={series.data.name} enablePagefind={true}>
<meta slot="head-description" property="og:description" content="Bad Manners || The story of Quince, Nikili, and Suu."/>
<h1 class="m-2 text-2xl font-semibold text-stone-800 dark:text-stone-100">{series.data.name}</h1>
<p class="my-4">This is the main hub for the story of Quince, Nikili, and Suu, as well as all bonus content.</p>
<section class="my-2" aria-labelledby="main-chapters">
<h2 id="main-chapters" class="p-2 text-xl font-semibold text-stone-800 dark:text-stone-100">Main chapters</h2>
<h2 id="main-chapters" class="p-2 text-xl font-semibold text-stone-800 dark:text-stone-100" data-pagefind-meta="type:series">Main chapters</h2>
<details
class="mx-3 mb-6 mt-1 rounded-lg border border-stone-400 bg-stone-300 dark:border-stone-500 dark:bg-stone-700"
>
@ -99,6 +95,7 @@ const mainChaptersWithSummaries = mainChapters.filter((story) => story.data.summ
class="mx-auto w-full max-w-4xl break-before-page"
src={mapImage}
alt="A geopolitical map for the setting of The Lost of the Marshes"
data-pagefind-meta="image[src],image_alt[alt]"
/>
</section>
</GalleryLayout>

View file

@ -82,11 +82,11 @@ if (uncategorizedTagsSet.size > 0) {
}
---
<GalleryLayout pageTitle={`Tags`}>
<GalleryLayout pageTitle="Tags">
<meta
property="og:description"
slot="head-description"
content="Bad Manners || Find all content with a specific tag."
property="og:description"
/>
<h1 class="m-2 text-2xl font-semibold text-stone-800 dark:text-stone-100">All available tags</h1>
<p class="my-4">You can find all content with a specific tag by selecting it below from the appropriate category.</p>

View file

@ -3,7 +3,37 @@
@tailwind utilities;
@layer components {
.text-link {
.text-link, .pagefind-ui .pagefind-ui__result-link {
@apply text-stone-800 hover:text-bm-500 focus:text-bm-500 dark:text-zinc-300 dark:hover:text-bm-400 dark:focus:text-bm-400;
}
.pagefind-ui {
--pagefind-ui-primary: theme(colors.stone.800);
--pagefind-ui-text: theme(colors.stone.900);
--pagefind-ui-background: theme(colors.stone.50);
--pagefind-ui-border: theme(colors.stone.400);
--pagefind-ui-tag: theme(colors.bm.300);
--pagefind-ui-scale: 0.8;
--pagefind-ui-font: theme(fontFamily.sans);
--pagefind-ui-border-width: 1px;
--pagefind-ui-border-radius: 8px;
--pagefind-ui-image-border-radius: 0px;
}
@media screen(md) {
.pagefind-ui {
--pagefind-ui-scale: 0.9;
}
}
@media not print {
.dark .pagefind-ui {
--pagefind-ui-primary: theme(colors.stone.200);
--pagefind-ui-text: theme(colors.stone.100);
--pagefind-ui-background: theme(colors.stone.700);
--pagefind-ui-border: theme(colors.stone.500);
--pagefind-ui-tag: theme(colors.green.800);
}
}
}