refactor: aggregate tag count with contentlayer

This commit is contained in:
Timothy Lin 2023-07-12 00:51:31 +08:00
parent 391e529083
commit d61487efa4
5 changed files with 40 additions and 9 deletions

1
app/tag-data.json Normal file
View File

@ -0,0 +1 @@
{"markdown":1,"code":1,"features":1,"next-js":5,"math":1,"ols":1,"github":1,"guide":4,"tailwind":2,"holiday":1,"canada":1,"images":1,"writings":1,"book":1,"reflection":1,"multi-author":1,"feature":1}

View File

@ -1,8 +1,9 @@
import { slug } from 'github-slugger'
import { getAllTags, allCoreContent } from 'pliny/utils/contentlayer'
import { allCoreContent } from 'pliny/utils/contentlayer'
import siteMetadata from '@/data/siteMetadata'
import ListLayout from '@/layouts/ListLayout'
import { allBlogs } from 'contentlayer/generated'
import tagData from 'app/tag-data.json'
import { genPageMetadata } from 'app/seo'
import { Metadata } from 'next'
@ -21,8 +22,9 @@ export async function generateMetadata({ params }: { params: { tag: string } }):
}
export const generateStaticParams = async () => {
const tags = await getAllTags(allBlogs)
const paths = Object.keys(tags).map((tag) => ({
const tagCounts = tagData as Record<string, number>
const tagKeys = Object.keys(tagCounts)
const paths = tagKeys.map((tag) => ({
tag: tag,
}))
return paths

View File

@ -1,15 +1,15 @@
import { getAllTags } from 'pliny/utils/contentlayer'
import Link from '@/components/Link'
import Tag from '@/components/Tag'
import { slug } from 'github-slugger'
import { allBlogs } from 'contentlayer/generated'
import tagData from 'app/tag-data.json'
import { genPageMetadata } from 'app/seo'
export const metadata = genPageMetadata({ title: 'Tags', description: 'Things I blog about' })
export default async function Page() {
const tags = await getAllTags(allBlogs)
const sortedTags = Object.keys(tags).sort((a, b) => tags[b] - tags[a])
const tagCounts = tagData as Record<string, number>
const tagKeys = Object.keys(tagCounts)
const sortedTags = tagKeys.sort((a, b) => tagCounts[b] - tagCounts[a])
return (
<>
<div className="flex flex-col items-start justify-start divide-y divide-gray-200 dark:divide-gray-700 md:mt-24 md:flex-row md:items-center md:justify-center md:space-x-6 md:divide-y-0">
@ -19,7 +19,7 @@ export default async function Page() {
</h1>
</div>
<div className="flex max-w-lg flex-wrap">
{Object.keys(tags).length === 0 && 'No tags found.'}
{tagKeys.length === 0 && 'No tags found.'}
{sortedTags.map((t) => {
return (
<div key={t} className="mb-2 mr-5 mt-2">
@ -29,7 +29,7 @@ export default async function Page() {
className="-ml-2 text-sm font-semibold uppercase text-gray-600 dark:text-gray-300"
aria-label={`View posts tagged ${t}`}
>
{` (${tags[t]})`}
{` (${tagCounts[t]})`}
</Link>
</div>
)

View File

@ -1,5 +1,7 @@
import { defineDocumentType, ComputedFields, makeSource } from 'contentlayer/source-files'
import { writeFileSync } from 'fs'
import readingTime from 'reading-time'
import GithubSlugger from 'github-slugger'
import path from 'path'
// Remark packages
import remarkGfm from 'remark-gfm'
@ -38,6 +40,26 @@ const computedFields: ComputedFields = {
toc: { type: 'string', resolve: (doc) => extractTocHeadings(doc.body.raw) },
}
/**
* Count the occurrences of all tags across blog posts and write to json file
*/
function createTagCount(allBlogs) {
const tagCount: Record<string, number> = {}
allBlogs.forEach((file) => {
if (file.tags && file.draft !== true) {
file.tags.forEach((tag) => {
const formattedTag = GithubSlugger.slug(tag)
if (formattedTag in tagCount) {
tagCount[formattedTag] += 1
} else {
tagCount[formattedTag] = 1
}
})
}
})
writeFileSync('./app/tag-data.json', JSON.stringify(tagCount))
}
export const Blog = defineDocumentType(() => ({
name: 'Blog',
filePathPattern: 'blog/**/*.mdx',
@ -113,4 +135,9 @@ export default makeSource({
rehypePresetMinify,
],
},
onSuccess: async (importData) => {
const { allBlogs } = await importData()
createTagCount(allBlogs)
createSearchIndex(allBlogs)
},
})

View File

@ -35,6 +35,7 @@
"**/*.js",
"**/*.ts",
"**/*.tsx",
"**/*.json",
".contentlayer/generated",
".contentlayer/generated/**/*.json",
".next/types/**/*.ts"