Skip to content

Commit

Permalink
upgrade vitepress + use createContentLoader
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Mar 13, 2023
1 parent 2863bec commit 41759df
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 147 deletions.
55 changes: 27 additions & 28 deletions .vitepress/genFeed.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,52 @@
import path from 'path'
import { readFileSync, writeFileSync } from 'fs'
import { writeFileSync } from 'fs'
import { Feed } from 'feed'
import { fileURLToPath } from 'url'
import { load } from './theme/posts.data.js'
import { createContentLoader, type SiteConfig } from 'vitepress'

const url = `https://blog.vuejs.org`
const dirname = path.dirname(fileURLToPath(import.meta.url))
const baseUrl = `https://blog.vuejs.org`

export async function genFeed() {
export async function genFeed(config: SiteConfig) {
const feed = new Feed({
title: 'The Vue Point',
description: 'The official blog for the Vue.js project',
id: url,
link: url,
id: baseUrl,
link: baseUrl,
language: 'en',
image: 'https://vuejs.org/images/logo.png',
favicon: `${url}/favicon.ico`,
favicon: `${baseUrl}/favicon.ico`,
copyright:
'Copyright (c) 2021-present, Yuxi (Evan) You and blog contributors'
})

for (const post of await load(true)) {
const file = path.resolve(dirname, `dist${post.href}.html`)
const rendered = readFileSync(file, 'utf-8')
const content = rendered.match(
/<div [^<>]+?class="prose[^<>]+?>([\s\S]*)<\/div><\/div><footer/
)
const posts = await createContentLoader('posts/*.md', {
excerpt: true,
render: true
}).load()

if (!content) {
throw new Error(`no content match found for file ${post.href}`)
}
posts.sort(
(a, b) =>
+new Date(b.frontmatter.date as string) -
+new Date(a.frontmatter.date as string)
)

for (const { url, excerpt, frontmatter, html } of posts) {
feed.addItem({
title: post.title,
id: `${url}${post.href}`,
link: `${url}${post.href}`,
description: post.excerpt,
content: content[1],
title: frontmatter.title,
id: `${baseUrl}${url}`,
link: `${baseUrl}${url}`,
description: excerpt,
content: html,
author: [
{
name: post.data.author,
link: post.data.twitter
? `https://twitter.com/${post.data.twitter}`
name: frontmatter.author,
link: frontmatter.twitter
? `https://twitter.com/${frontmatter.twitter}`
: undefined
}
],
date: post.data.date
date: frontmatter.date
})
}

writeFileSync(path.resolve(dirname, 'dist/feed.rss'), feed.rss2())
writeFileSync(path.join(config.outDir, 'feed.rss'), feed.rss2())
}
45 changes: 15 additions & 30 deletions .vitepress/theme/Article.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const { frontmatter: data } = useData()
const route = useRoute()
function findCurrentIndex() {
return posts.findIndex((p) => p.href === route.path)
return posts.findIndex((p) => p.url === route.path)
}
// use the customData date which contains pre-resolved date info
Expand All @@ -24,59 +24,44 @@ const prevPost = computed(() => posts[findCurrentIndex() + 1])
<header class="pt-6 xl:pb-10 space-y-1 text-center">
<Date :date="date" />
<h1
class="
text-3xl
leading-9
font-extrabold
text-gray-900 dark:text-white
tracking-tight
sm:text-4xl sm:leading-10
md:text-5xl md:leading-14
"
class="text-3xl leading-9 font-extrabold text-gray-900 dark:text-white tracking-tight sm:text-4xl sm:leading-10 md:text-5xl md:leading-14"
>
{{ data.title }}
</h1>
</header>

<div
class="
divide-y
xl:divide-y-0
divide-gray-200 dark:divide-slate-200/5
xl:grid xl:grid-cols-4 xl:gap-x-10
pb-16
xl:pb-20
"
class="divide-y xl:divide-y-0 divide-gray-200 dark:divide-slate-200/5 xl:grid xl:grid-cols-4 xl:gap-x-10 pb-16 xl:pb-20"
style="grid-template-rows: auto 1fr"
>
<Author />
<div class="divide-y divide-gray-200 dark:divide-slate-200/5 xl:pb-0 xl:col-span-3 xl:row-span-2">
<div
class="divide-y divide-gray-200 dark:divide-slate-200/5 xl:pb-0 xl:col-span-3 xl:row-span-2"
>
<Content class="prose dark:prose-invert max-w-none pt-10 pb-8" />
</div>

<footer
class="
text-sm
font-medium
leading-5
divide-y divide-gray-200 dark:divide-slate-200/5
xl:col-start-1 xl:row-start-2
"
class="text-sm font-medium leading-5 divide-y divide-gray-200 dark:divide-slate-200/5 xl:col-start-1 xl:row-start-2"
>
<div v-if="nextPost" class="py-8">
<h2 class="text-xs tracking-wide uppercase text-gray-500 dark:text-white">
<h2
class="text-xs tracking-wide uppercase text-gray-500 dark:text-white"
>
Next Article
</h2>
<div class="link">
<a :href="nextPost.href">{{ nextPost.title }}</a>
<a :href="nextPost.url">{{ nextPost.title }}</a>
</div>
</div>
<div v-if="prevPost" class="py-8">
<h2 class="text-xs tracking-wide uppercase text-gray-500 dark:text-white">
<h2
class="text-xs tracking-wide uppercase text-gray-500 dark:text-white"
>
Previous Article
</h2>
<div class="link">
<a :href="prevPost.href">{{ prevPost.title }}</a>
<a :href="prevPost.url">{{ prevPost.title }}</a>
</div>
</div>
<div class="pt-8">
Expand Down
24 changes: 9 additions & 15 deletions .vitepress/theme/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,26 @@ const { frontmatter } = useData()
<div class="divide-y divide-gray-200 dark:divide-slate-200/5">
<div class="pt-6 pb-8 space-y-2 md:space-y-5">
<h1
class="
text-3xl
leading-9
font-extrabold
text-gray-900 dark:text-white
tracking-tight
sm:text-4xl sm:leading-10
md:text-6xl md:leading-14
"
class="text-3xl leading-9 font-extrabold text-gray-900 dark:text-white tracking-tight sm:text-4xl sm:leading-10 md:text-6xl md:leading-14"
>
{{ frontmatter.title }}
</h1>
<p class="text-lg leading-7 text-gray-500 dark:text-white">{{ $frontmatter.subtext }}</p>
<p class="text-lg leading-7 text-gray-500 dark:text-white">
{{ frontmatter.subtext }}
</p>
</div>
<ul class="divide-y divide-gray-200 dark:divide-slate-200/5">
<li class="py-12" v-for="{ title, href, date, excerpt } of posts">
<li class="py-12" v-for="{ title, url, date, excerpt } of posts">
<article
class="space-y-2 xl:grid xl:grid-cols-4 xl:space-y-0 xl:items-baseline"
>
<Date :date="date" />
<div class="space-y-5 xl:col-span-3">
<div class="space-y-6">
<h2 class="text-2xl leading-8 font-bold tracking-tight">
<a class="text-gray-900 dark:text-white" :href="href">{{ title }}</a>
<a class="text-gray-900 dark:text-white" :href="url">{{
title
}}</a>
</h2>
<div
v-if="excerpt"
Expand All @@ -42,9 +38,7 @@ const { frontmatter } = useData()
></div>
</div>
<div class="text-base leading-6 font-medium">
<a class="link" aria-label="read more" :href="href"
>Read more →</a
>
<a class="link" aria-label="read more" :href="url">Read more →</a>
</div>
</div>
</article>
Expand Down
86 changes: 17 additions & 69 deletions .vitepress/theme/posts.data.ts
Original file line number Diff line number Diff line change
@@ -1,86 +1,34 @@
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { createMarkdownRenderer, MarkdownRenderer } from 'vitepress'
import { fileURLToPath } from 'url'
import { createContentLoader } from 'vitepress'

let md: MarkdownRenderer
const dirname = path.dirname(fileURLToPath(import.meta.url))
const postDir = path.resolve(dirname, '../../posts')

export interface Post {
interface Post {
title: string
href: string
url: string
date: {
time: number
string: string
}
excerpt: string | undefined
data?: Record<string, any>
}

interface PostWithData extends Post {
data: Record<string, any>
}

declare const data: Post[]
export { data }

export async function load(): Promise<Post[]>
export async function load(asFeed: boolean): Promise<PostWithData[]>
export async function load(asFeed = false) {
md = md || (await createMarkdownRenderer(process.cwd()))
return fs
.readdirSync(postDir)
.map((file) => getPost(file, postDir, asFeed))
.sort((a, b) => b.date.time - a.date.time)
}

export default {
watch: path.join(postDir, '*.md'),
load() {
return load()
}
}

const cache = new Map()

function getPost(file: string, postDir: string, asFeed = false): Post {
const fullePath = path.join(postDir, file)
const timestamp = fs.statSync(fullePath).mtimeMs

const cached = cache.get(fullePath)
if (cached && timestamp === cached.timestamp) {
return cached.post
}

const src = fs.readFileSync(fullePath, 'utf-8')
const { data, excerpt } = matter(src, { excerpt: true })

const post: Post = {
title: data.title,
href: `/posts/${file.replace(/\.md$/, '')}`,
date: formatDate(data.date),
excerpt: excerpt && md.render(excerpt)
}
if (asFeed) {
// only attach these when building the RSS feed to avoid bloating the
// client bundle size
post.data = data
export default createContentLoader('posts/*.md', {
excerpt: true,
transform(raw): Post[] {
return raw
.map(({ url, frontmatter, excerpt }) => ({
title: frontmatter.title,
url,
excerpt,
date: formatDate(frontmatter.date)
}))
.sort((a, b) => b.date.time - a.date.time)
}
})

cache.set(fullePath, {
timestamp,
post
})

return post
}

function formatDate(date: string | Date): Post['date'] {
if (!(date instanceof Date)) {
date = new Date(date)
}
function formatDate(raw: string): Post['date'] {
const date = new Date(raw)
date.setUTCHours(12)
return {
time: +date,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"feed": "^4.2.1",
"gray-matter": "^4.0.2",
"tailwindcss": "^3.1.8",
"vitepress": "^1.0.0-alpha.52",
"vitepress": "^1.0.0-alpha.54",
"vue": "^3.2.47"
}
}
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 41759df

Please sign in to comment.