add authors page, facebook and twitter autofil from ghost if not set by user, and added an about page that will auto populate if users have a Page on their ghost server called about like in the default configuration.
This commit is contained in:
parent
271ad759a8
commit
e99553f413
|
@ -2,12 +2,16 @@ import type { StarlightPlugin, StarlightUserConfig } from '@astrojs/starlight/ty
|
|||
import type { AstroIntegrationLogger } from 'astro'
|
||||
import { type StarlightGhostConfig, validateConfig } from './src/schemas/config'
|
||||
import { vitePluginStarlightGhostConfig } from './src/integrations/vite'
|
||||
import { facebook, getSettings, invariant, twitter } from './src/utils/api'
|
||||
|
||||
const settings = await getSettings()
|
||||
|
||||
export type { StarlightGhostConfig }
|
||||
|
||||
export default function starlightGhostCMS(userConfig?: StarlightGhostConfig): StarlightPlugin {
|
||||
const config: StarlightGhostConfig = validateConfig(userConfig)
|
||||
|
||||
invariant(settings, "Settings not available... check your api key/url")
|
||||
|
||||
return {
|
||||
name: '@matthiesenxyz/starlight-ghostcms-plugin',
|
||||
hooks: {
|
||||
|
@ -15,7 +19,9 @@ export default function starlightGhostCMS(userConfig?: StarlightGhostConfig): St
|
|||
updateStarlightConfig({
|
||||
social: {
|
||||
...starlightConfig.social,
|
||||
rss: `${astroConfig.site}/rss.xml`
|
||||
rss: `${astroConfig.site}/rss.xml`,
|
||||
twitter: twitter(settings.twitter?settings.twitter:""),
|
||||
facebook: facebook(settings.facebook?settings.facebook:""),
|
||||
},
|
||||
components: {
|
||||
...starlightConfig.components,
|
||||
|
@ -39,6 +45,15 @@ export default function starlightGhostCMS(userConfig?: StarlightGhostConfig): St
|
|||
entrypoint: '@matthiesenxyz/starlight-ghostcms/routes/[slug].astro',
|
||||
prerender: true,
|
||||
})
|
||||
injectRoute({
|
||||
pattern: '/blog/about',
|
||||
entrypoint: '@matthiesenxyz/starlight-ghostcms/routes/about.astro',
|
||||
prerender: true,
|
||||
})
|
||||
injectRoute({
|
||||
pattern: '/blog/authors',
|
||||
entrypoint: '@matthiesenxyz/starlight-ghostcms/routes/authors.astro',
|
||||
})
|
||||
injectRoute({
|
||||
pattern: '/rss.xml',
|
||||
entrypoint: '@matthiesenxyz/starlight-ghostcms/routes/rss.xml.ts'
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
"./overrides/Sidebar.astro": "./src/overrides/Sidebar.astro",
|
||||
"./overrides/SiteTitle.astro": "./src/overrides/SiteTitle.astro",
|
||||
"./routes/index.astro": "./src/routes/index.astro",
|
||||
"./routes/about.astro": "./src/routes/about.astro",
|
||||
"./routes/authors.astro": "./src/routes/authors.astro",
|
||||
"./routes/[slug].astro": "./src/routes/[slug].astro",
|
||||
"./routes/rss.xml.ts": "./src/routes/rss.xml.ts",
|
||||
"./schema": "./src/schemas/config.ts"
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -7,11 +7,11 @@ interface Props {
|
|||
|
||||
const { author } = Astro.props
|
||||
|
||||
const isLink = author.website !== undefined
|
||||
const isLink = author.slug !== undefined
|
||||
const Element = isLink ? 'a' : 'div'
|
||||
---
|
||||
|
||||
<Element href={isLink ? author.website : undefined} class="author">
|
||||
<Element href={isLink ? '/blog/authors' : undefined} class="author">
|
||||
{author.profile_image && <img alt={author.name} src={author.profile_image} />}
|
||||
<div class="text">
|
||||
<div class="name">{author.name}</div>
|
||||
|
|
|
@ -3,23 +3,63 @@ import StarlightSidebar from '@astrojs/starlight/components/Sidebar.astro'
|
|||
import type { Props } from '@astrojs/starlight/props'
|
||||
import config from 'virtual:starlight-ghost-config'
|
||||
import { isBlogPostPage, isBlogRoot } from '../utils/page'
|
||||
import { getAllPosts } from '../utils/api'
|
||||
import { getAllPages, getAllPosts, getSluggedPage } from '../utils/api/api-functions.js'
|
||||
import type { SidebarEntry } from './sidebartypes'
|
||||
|
||||
export async function getRecentBlogEntries(){
|
||||
const entries = await getAllPosts()
|
||||
return entries.slice(0, config.recentPostCount)
|
||||
}
|
||||
|
||||
export async function getBlogPageEntries(){
|
||||
const entries = await getAllPages()
|
||||
return entries;
|
||||
}
|
||||
|
||||
export function checkpath(path: string){
|
||||
if ( path.slice(0, 5) === "/blog" ){
|
||||
return true
|
||||
} else { return false }
|
||||
}
|
||||
|
||||
export function isAbout(path: string){
|
||||
if ( path === "/blog/about" ){
|
||||
return true
|
||||
} else { return false }
|
||||
}
|
||||
|
||||
export function isAuthors(path: string){
|
||||
if ( path === "/blog/authors" ){
|
||||
return true
|
||||
} else { return false }
|
||||
}
|
||||
const isBlog = checkpath(Astro.url.pathname)
|
||||
const recentEntries = isBlog ? await getRecentBlogEntries() : []
|
||||
const aboutPage = await getSluggedPage("about");
|
||||
const AboutEntry:SidebarEntry = {
|
||||
attrs: {}, badge: undefined,
|
||||
href: '/blog/about',
|
||||
isCurrent: isAbout(Astro.url.pathname),
|
||||
type: 'link',
|
||||
label: aboutPage?.post?.title
|
||||
}
|
||||
|
||||
const emptyEntry:SidebarEntry = { attrs: {}, badge: undefined,
|
||||
href: '#', isCurrent: false, type: 'link', label: '', }
|
||||
|
||||
const about = aboutPage?AboutEntry:emptyEntry
|
||||
|
||||
const blogSidebar: Props['sidebar'] = isBlog
|
||||
? [
|
||||
about,
|
||||
{
|
||||
attrs: {},
|
||||
badge: undefined,
|
||||
href: '/blog/authors',
|
||||
isCurrent: isAuthors(Astro.url.pathname),
|
||||
label: 'Our Authors',
|
||||
type: 'link',
|
||||
},
|
||||
{
|
||||
attrs: {},
|
||||
badge: undefined,
|
||||
|
@ -33,7 +73,7 @@ const blogSidebar: Props['sidebar'] = isBlog
|
|||
collapsed: false,
|
||||
entries: recentEntries.map((blogEntry) => ({
|
||||
attrs: {},
|
||||
badge: undefined,
|
||||
badge: blogEntry.featured?({text: "⭐", variant: "note"}):undefined,
|
||||
href: `/blog/${blogEntry.slug}`,
|
||||
isCurrent: isBlogPostPage(Astro.props.slug, `blog/${blogEntry.slug}`),
|
||||
label: blogEntry.title,
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
---
|
||||
import type { Props } from "@astrojs/starlight/props";
|
||||
import AstrolightSiteTitle from "@astrojs/starlight/components/SiteTitle.astro";
|
||||
import config from 'virtual:starlight-ghost-config'
|
||||
---
|
||||
|
||||
<AstrolightSiteTitle {...Astro.props} />
|
||||
<div>
|
||||
<a href="/blog">{config.title}</a>
|
||||
<a href="/blog">Blog</a>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
import { z } from 'astro/zod';
|
||||
import type { AstroBuiltinAttributes } from 'astro';
|
||||
import type { HTMLAttributes } from 'astro/types';
|
||||
|
||||
const linkHTMLAttributesSchema = z.record(
|
||||
z.union([z.string(), z.number(), z.boolean(), z.undefined()])
|
||||
) as z.Schema<Omit<HTMLAttributes<'a'>, keyof AstroBuiltinAttributes | 'children'>>;
|
||||
export type LinkHTMLAttributes = z.infer<typeof linkHTMLAttributesSchema>;
|
||||
|
||||
const badgeSchema = () =>
|
||||
z.object({
|
||||
variant: z.enum(['note', 'danger', 'success', 'caution', 'tip', 'default']).default('default'),
|
||||
text: z.string(),
|
||||
});
|
||||
|
||||
export const BadgeConfigSchema = () =>
|
||||
z
|
||||
.union([z.string(), badgeSchema()])
|
||||
.transform((badge) => {
|
||||
if (typeof badge === 'string') {
|
||||
return { variant: 'default' as const, text: badge };
|
||||
}
|
||||
return badge;
|
||||
})
|
||||
.optional();
|
||||
|
||||
export type Badge = z.output<ReturnType<typeof badgeSchema>>;
|
||||
|
||||
export interface Link {
|
||||
type: 'link';
|
||||
label: string;
|
||||
href: string;
|
||||
isCurrent: boolean;
|
||||
badge: Badge | undefined;
|
||||
attrs: LinkHTMLAttributes;
|
||||
}
|
||||
|
||||
interface Group {
|
||||
type: 'group';
|
||||
label: string;
|
||||
entries: (Link | Group)[];
|
||||
collapsed: boolean;
|
||||
badge: Badge | undefined;
|
||||
}
|
||||
|
||||
export type SidebarEntry = Link | Group;
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
import config from 'virtual:starlight-ghost-config'
|
||||
import Metadata from '../components/Metadata.astro'
|
||||
import Page from '../components/Page.astro'
|
||||
//import PrevNextLinks from '../components/PrevNextLinks.astro'
|
||||
import { getPageProps } from '../utils/page'
|
||||
import { getSluggedPage } from '../utils/api'
|
||||
|
||||
const aboutPage = await getSluggedPage("about");
|
||||
|
||||
//const { entries, nextLink, prevLink } = Astro.props
|
||||
|
||||
const pageProps = getPageProps(aboutPage?.post?.title)
|
||||
---
|
||||
|
||||
<Page {...pageProps}>
|
||||
{config.supportGhost && (
|
||||
<div id="pghost">Powered by <a href="https://ghost.org">Ghost</a></div>
|
||||
)}
|
||||
<Metadata entry={aboutPage.post} />
|
||||
<Fragment set:html={aboutPage.post.html} />
|
||||
<footer class="not-content">
|
||||
<!--PrevNextLinks next={nextLink} prev={prevLink} /-->
|
||||
</footer>
|
||||
</Page>
|
||||
|
||||
<style>
|
||||
#pghost {
|
||||
color: gray;
|
||||
position: absolute;
|
||||
top: 4rem;
|
||||
}
|
||||
#pghost a {
|
||||
color: gray;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
import config from 'virtual:starlight-ghost-config'
|
||||
import Page from '../components/Page.astro'
|
||||
//import PrevNextLinks from '../components/PrevNextLinks.astro'
|
||||
import { getAllAuthors } from '../utils/api/api-functions'
|
||||
import { getPageProps } from '../utils/page'
|
||||
import AdvancedAuthorCard from '../components/AdvancedAuthorCard.astro';
|
||||
|
||||
//const { entries, nextLink, prevLink } = Astro.props
|
||||
|
||||
const { authors } = await getAllAuthors();
|
||||
|
||||
const pageProps = getPageProps("Our Authors")
|
||||
---
|
||||
|
||||
<Page {...pageProps}>
|
||||
{config.supportGhost && (
|
||||
<div id="pghost">Powered by <a href="https://ghost.org">Ghost</a></div>
|
||||
)}
|
||||
|
||||
|
||||
<div class="authors">
|
||||
<ul>
|
||||
{authors.map((author: any) => (
|
||||
<li>
|
||||
<AdvancedAuthorCard {author} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<footer class="not-content">
|
||||
<!--PrevNextLinks next={nextLink} prev={prevLink} /-->
|
||||
</footer>
|
||||
</Page>
|
||||
|
||||
<style>
|
||||
#pghost {
|
||||
color: gray;
|
||||
position: absolute;
|
||||
top: 4rem;
|
||||
}
|
||||
#pghost a {
|
||||
color: gray;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
</style>
|
|
@ -106,6 +106,22 @@ export const getAllPages = async () => {
|
|||
return pages;
|
||||
};
|
||||
|
||||
export const getSluggedPage = async (slug:string) => {
|
||||
const results = await api.pages
|
||||
.read({slug: slug})
|
||||
.include({
|
||||
authors: true,
|
||||
tags: true,
|
||||
}).fetch()
|
||||
|
||||
if (!results.success) {
|
||||
throw new Error(results.errors.map((e) => e.message).join(", "));
|
||||
}
|
||||
return {
|
||||
post: results.data,
|
||||
};
|
||||
};
|
||||
|
||||
export const getSettings = async () => {
|
||||
const res = await api.settings.fetch();
|
||||
if (res.success) {
|
||||
|
|
Loading…
Reference in New Issue