more progress

This commit is contained in:
Adam Matthiesen 2024-02-19 21:06:10 -08:00
parent 795c075405
commit b462c105b5
6 changed files with 35 additions and 209 deletions

View File

@ -26,8 +26,9 @@ export default function starlightBlogPlugin(userConfig?: StarlightGhostConfig):
hooks: {
'astro:config:setup': ({ injectRoute, updateConfig }) => {
injectRoute({
pattern: '',
entrypoint: ''
pattern: '@matthiesenxyz/starlight-ghostcms/routes/index.astro',
entrypoint: '/blog',
prerender: true,
})
updateConfig({

View File

@ -1,57 +0,0 @@
---
import type { StarlightBlogLink } from '../utils/content'
interface Props {
next: StarlightBlogLink | undefined
prev: StarlightBlogLink | undefined
}
const { next, prev } = Astro.props
---
{
prev || next ? (
<div class="pagination not-content">
{prev && (
<a href={prev.href} rel="prev">
« {prev.label}
</a>
)}
{next && (
<a href={next.href} rel="next">
{next.label} »
</a>
)}
</div>
) : null
}
<style>
.pagination {
display: grid;
gap: 1rem;
grid-template-columns: 1fr 1fr;
}
a {
border-radius: 0.5rem;
border: 1px solid var(--sl-color-gray-5);
box-shadow: var(--sl-shadow-md);
color: var(--sl-color-white);
font-size: var(--sl-text-lg);
line-height: 1.4;
padding: 1rem;
text-decoration: none;
}
a:hover {
border-color: var(--sl-color-gray-2);
}
[rel='next'] {
justify-content: end;
grid-column: 2;
text-align: end;
flex-direction: row-reverse;
}
</style>

View File

@ -2,26 +2,28 @@
import StarlightMarkdownContent from '@astrojs/starlight/components/MarkdownContent.astro'
import type { Props } from '@astrojs/starlight/props'
import PrevNextLinks from '../components/PrevNextLinks.astro'
import { getBlogEntry, type StarlightBlogEntryPaginated } from '../utils/content'
import { isAnyBlogPostPage } from '../utils/page'
import Metadata from '../components/Metadata.astro'
import type { Post } from '../schemas/posts'
import { getSluggedPost } from '../utils/api'
const isBlogPost = isAnyBlogPostPage(Astro.props.slug)
let blogEntry: StarlightBlogEntryPaginated | undefined = undefined
let blogEntry: Post | undefined = undefined
if (isBlogPost) {
blogEntry = await getBlogEntry(Astro.url.pathname)
blogEntry = await getSluggedPost(Astro.props.slug)
}
---
<StarlightMarkdownContent {...Astro.props}>
{isBlogPost && blogEntry ? <Metadata entry={blogEntry.entry} /> : null}
<slot />
{isBlogPost && blogEntry ? <Metadata entry={blogEntry} /> : null}
<div> PlaceHolder for HTML </div>
{
isBlogPost && blogEntry ? (
<div class="post-footer">
<PrevNextLinks next={blogEntry.nextLink} prev={blogEntry.prevLink} />
<!-- PREV - Next Links /-->
</div>
) : null
}

View File

@ -1,20 +1,18 @@
---
import type { InferGetStaticPropsType } from 'astro'
//import type { InferGetStaticPropsType } from 'astro'
import config from 'virtual:starlight-ghost-config'
import Page from '../components/Page.astro'
import Posts from '../components/Posts.astro'
import PrevNextLinks from '../components/PrevNextLinks.astro'
//import PrevNextLinks from '../components/PrevNextLinks.astro'
import { getPageProps } from '../utils/page'
import { getAllPosts } from '../utils/api'
export const prerender = true
const entries = await getAllPosts();
export function getStaticPaths() {
}
type Props = InferGetStaticPropsType<typeof getStaticPaths>
const { entries, nextLink, prevLink } = Astro.props
//const { entries, nextLink, prevLink } = Astro.props
const pageProps = getPageProps(config.title)
---
@ -22,7 +20,7 @@ const pageProps = getPageProps(config.title)
<Page {...pageProps}>
<Posts {entries} />
<footer class="not-content">
<PrevNextLinks next={nextLink} prev={prevLink} />
<!--PrevNextLinks next={nextLink} prev={prevLink} /-->
</footer>
</Page>

View File

@ -67,6 +67,23 @@ export const getAllPosts = async () => {
return posts;
};
export const getSluggedPost = async (slug:string) => {
const result = await api.posts
.read({slug: slug})
.include({
authors: true,
tags: true,
}).fetch()
if (result.success) {
const post: Post = result.data;
return post
}
if (result.errors) {
console.log(result.errors.map((e) => e.message).join("\n"));
}
};
export const getAllPages = async () => {
const pages: Page[] = [];
let cursor = await api.pages

View File

@ -1,135 +0,0 @@
import type { z } from 'astro/zod'
import { getCollection, type AstroCollectionEntry } from 'astro:content'
import starlightConfig from 'virtual:starlight/user-config'
import config from 'virtual:starlight-ghost-config'
import type { Author } from '../schemas/authors'
export async function getBlogStaticPaths() {
const entries = await getBlogEntries()
const entryPages: StarlightBlogEntry[][] = []
for (const entry of entries) {
const lastPage = entryPages.at(-1)
if (!lastPage || lastPage.length === config.postCount) {
entryPages.push([entry])
} else {
lastPage.push(entry)
}
}
if (entryPages.length === 0) {
entryPages.push([])
}
return entryPages.map((entries, index) => {
const prevPage = index === 0 ? undefined : entryPages.at(index - 1)
const nextPage = entryPages.at(index + 1)
return {
params: {
page: index === 0 ? undefined : index + 1,
},
props: {
entries,
nextLink: nextPage ? { href: `/blog/${index + 2}`, label: 'Older posts' } : undefined,
prevLink: prevPage ? { href: index === 1 ? '/blog' : `/blog/${index}`, label: 'Newer posts' } : undefined,
} satisfies StarlightBlogStaticProps,
}
})
}
export async function getRecentBlogEntries() {
const entries = await getBlogEntries()
return entries.slice(0, config.recentPostCount)
}
export async function getBlogEntry(slug: string): Promise<StarlightBlogEntryPaginated> {
const entries = await getBlogEntries()
const entryIndex = entries.findIndex((entry) => entry.slug === slug.replace(/^\//, '').replace(/\/$/, ''))
const entry = entries[entryIndex]
if (!entry) {
throw new Error(`Blog post with slug '${slug}' not found.`)
}
const prevEntry = entries[entryIndex - 1]
const nextEntry = entries[entryIndex + 1]
return {
entry,
nextLink: nextEntry ? { href: `/${nextEntry.slug}`, label: nextEntry.data.title } : undefined,
prevLink: prevEntry ? { href: `/${prevEntry.slug}`, label: prevEntry.data.title } : undefined,
}
}
export function getBlogEntryMetadata(entry: StarlightBlogEntry): StarlightBlogEntryMetadata {
const authors: Author[] = []
if (!entry.data.authors) {
authors.push(...Object.values(authors))
} else {
authors.push(entry.data.authors)
}
return {
authors,
date: entry.data.date.toLocaleDateString(starlightConfig.defaultLocale.lang, { dateStyle: 'medium' }),
}
}
export async function getBlogEntries() {
const entries = await getCollection<StarlightEntryData>('docs', ({ id }) => {
return id.startsWith('blog/') && id !== 'blog/index.mdx'
})
return entries.sort((a, b) => {
return b.data.date.getTime() - a.data.date.getTime()
})
}
export async function getBlogEntryExcerpt(entry: StarlightBlogEntry) {
if (entry.data.excerpt) {
return entry.data.excerpt
}
const { Content } = await entry.render()
return Content
}
type StarlightEntryData = z.infer<ReturnType<typeof blogSchema>> & { title: string }
type StarlightEntry = AstroCollectionEntry<StarlightEntryData>
export type StarlightBlogEntry = StarlightEntry & {
data: {
date: Date
}
}
export interface StarlightBlogLink {
href: string
label: string
}
export interface StarlightBlogEntryPaginated {
entry: StarlightBlogEntry
nextLink: StarlightBlogLink | undefined
prevLink: StarlightBlogLink | undefined
}
interface StarlightBlogEntryMetadata {
authors: Author[]
date: string
}
interface StarlightBlogStaticProps {
entries: StarlightBlogEntry[]
nextLink: StarlightBlogLink | undefined
prevLink: StarlightBlogLink | undefined
}