mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-29 15:10:06 +00:00
feature:
文章分类功能
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { getAllPosts, getAllTags, getPostBlocks } from '@/lib/notion'
|
||||
import { getAllCategories, getAllPosts, getAllTags, getPostBlocks } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import { getPageTableOfContents } from 'notion-utils'
|
||||
import { useRouter } from 'next/router'
|
||||
@@ -9,11 +9,11 @@ import formatDate from '@/lib/formatDate'
|
||||
import { Code, Collection, CollectionRow, Equation, NotionRenderer } from 'react-notion-x'
|
||||
import RewardButton from '@/components/RewardButton'
|
||||
import ShareBar from '@/components/ShareBar'
|
||||
import BlogPostMini from '@/components/BlogPostMini'
|
||||
import BlogPostCardMini from '@/components/BlogPostCardMini'
|
||||
import Comment from '@/components/Comment'
|
||||
import TocBar from '@/components/TocBar'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import { useRef } from 'react'
|
||||
import React, { useRef } from 'react'
|
||||
import Custom404 from '@/pages/404'
|
||||
|
||||
import 'prismjs/themes/prism-okaidia.css'
|
||||
@@ -27,19 +27,19 @@ import 'prismjs/components/prism-typescript'
|
||||
const mapPageUrl = id => {
|
||||
return 'https://www.notion.so/' + id.replace(/-/g, '')
|
||||
}
|
||||
const ArticleDetail = ({ post, blockMap, tags, prev, next, posts }) => {
|
||||
const ArticleDetail = ({ post, blockMap, tags, prev, next, posts, categories }) => {
|
||||
if (!post) {
|
||||
return <Custom404/>
|
||||
}
|
||||
const meta = {
|
||||
title: post.title,
|
||||
title: `${post.title} | ${BLOG.title}`,
|
||||
description: post.summary,
|
||||
type: 'article'
|
||||
}
|
||||
const targetRef = useRef(null)
|
||||
const url = BLOG.link + useRouter().asPath
|
||||
|
||||
return <BaseLayout meta={meta} tags={tags} post={post} totalPosts={posts} >
|
||||
return <BaseLayout meta={meta} tags={tags} post={post} totalPosts={posts} categories={categories} >
|
||||
{/* 阅读进度条 */}
|
||||
<Progress targetRef={targetRef} />
|
||||
|
||||
@@ -65,25 +65,10 @@ const ArticleDetail = ({ post, blockMap, tags, prev, next, posts }) => {
|
||||
{post.summary}
|
||||
</h2>
|
||||
|
||||
{/* 文章信息 */}
|
||||
{/* 文章作者等关联信息 */}
|
||||
<div className='justify-between flex flex-wrap bg-gray-50 p-2 dark:bg-gray-800 dark:text-white'>
|
||||
<div className='flex-nowrap flex'>
|
||||
|
||||
{post.slug !== 'about' && (<>
|
||||
<a
|
||||
className='hidden md:block duration-200 px-1' href='/article/about'
|
||||
>
|
||||
<Image alt={BLOG.author} width={33} height={33} src='/avatar.svg'
|
||||
className='rounded-full cursor-pointer transform hover:scale-125 duration-200' />
|
||||
</a>
|
||||
</>)}
|
||||
{post.tags && (
|
||||
<div className='flex flex-nowrap leading-8 p-1'>
|
||||
{post.tags.map(tag => (
|
||||
<TagItem key={tag} tag={tag} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className='cursor-pointer text-md py-2 mx-2 hover:underline'><i className='fa fa-folder-open-o mr-1'/>{post.category}</div>
|
||||
|
||||
{post.type[0] !== 'Page' && (
|
||||
<div className='flex items-start text-gray-500 dark:text-gray-400 leading-10'>
|
||||
@@ -93,6 +78,15 @@ const ArticleDetail = ({ post, blockMap, tags, prev, next, posts }) => {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{post.tags && (
|
||||
<div className='flex flex-nowrap leading-8 p-1'>
|
||||
{post.tags.map(tag => (
|
||||
<TagItem key={tag} tag={tag} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
|
||||
{/* 不蒜子 */}
|
||||
@@ -141,10 +135,10 @@ const ArticleDetail = ({ post, blockMap, tags, prev, next, posts }) => {
|
||||
</section>
|
||||
|
||||
<div className='text-gray-800 my-5 dark:text-gray-300'>
|
||||
<div className='mt-4 font-bold'>继续阅读</div>
|
||||
<div className='mt-4 font-bold'>其他文章</div>
|
||||
<div className='flex flex-wrap lg:flex-nowrap lg:space-x-10 justify-between py-2'>
|
||||
<BlogPostMini post={prev} />
|
||||
<BlogPostMini post={next} />
|
||||
<BlogPostCardMini post={prev} />
|
||||
<BlogPostCardMini post={next} />
|
||||
</div>
|
||||
</div>
|
||||
{/* 评论互动 */}
|
||||
@@ -198,13 +192,15 @@ export async function getStaticProps ({ params: { slug } }) {
|
||||
}
|
||||
posts = posts.filter(post => post.type[0] === 'Post')
|
||||
const tags = await getAllTags(posts)
|
||||
const categories = await getAllCategories(posts)
|
||||
|
||||
// 获取推荐文章
|
||||
const index = posts.indexOf(post)
|
||||
const prev = posts.slice(index - 1, index)[0] ?? posts.slice(-1)[0]
|
||||
const next = posts.slice(index + 1, index + 2)[0] ?? posts[0]
|
||||
|
||||
return {
|
||||
props: { post, blockMap, tags, prev, next, posts },
|
||||
props: { post, blockMap, tags, prev, next, posts, categories },
|
||||
revalidate: 1
|
||||
}
|
||||
}
|
||||
|
||||
56
pages/category/[category].js
Normal file
56
pages/category/[category].js
Normal file
@@ -0,0 +1,56 @@
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import TagsBar from '@/components/TagsBar'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
||||
|
||||
export default function Category ({ tags, posts, category, categories }) {
|
||||
const meta = {
|
||||
title: `${BLOG.title} | ${category}`,
|
||||
description: BLOG.description,
|
||||
type: 'website'
|
||||
}
|
||||
return <BaseLayout meta={meta} tags={tags} currentCategory={category} totalPosts={posts} categories={categories}>
|
||||
<div className='flex-grow bg-gray-200 dark:bg-black shadow-inner'>
|
||||
<TagsBar tags={tags} />
|
||||
<BlogPostListScroll posts={posts} tags={tags} currentCategory={category}/>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
}
|
||||
|
||||
export async function getStaticProps ({ params }) {
|
||||
const category = params.category
|
||||
let posts = await getAllPosts({ from: 'category-props' })
|
||||
posts = posts.filter(
|
||||
post => post.status[0] === 'Published' && post.type[0] === 'Post'
|
||||
)
|
||||
const tags = await getAllTags(posts)
|
||||
const categories = await getAllCategories(posts)
|
||||
const filteredPosts = posts.filter(
|
||||
post => post && post.category && post.category.includes(category)
|
||||
)
|
||||
return {
|
||||
props: {
|
||||
tags,
|
||||
posts: filteredPosts,
|
||||
category,
|
||||
categories
|
||||
},
|
||||
revalidate: 1
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStaticPaths () {
|
||||
if (BLOG.isProd) {
|
||||
const tags = await getAllTags()
|
||||
return {
|
||||
paths: Object.keys(tags).map(tag => ({ params: { tag } })),
|
||||
fallback: true
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
paths: [],
|
||||
fallback: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import { getAllPosts, getAllTags, getAllCategories } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import TagsBar from '@/components/TagsBar'
|
||||
@@ -10,6 +10,7 @@ export async function getStaticProps () {
|
||||
post => post.status[0] === 'Published' && post.type[0] === 'Post'
|
||||
)
|
||||
const tags = await getAllTags(posts)
|
||||
const categories = await getAllCategories(posts)
|
||||
const meta = {
|
||||
title: `${BLOG.title} | ${BLOG.description} `,
|
||||
description: BLOG.description,
|
||||
@@ -19,15 +20,16 @@ export async function getStaticProps () {
|
||||
props: {
|
||||
posts,
|
||||
tags,
|
||||
categories,
|
||||
meta
|
||||
},
|
||||
revalidate: 1
|
||||
}
|
||||
}
|
||||
|
||||
const Index = ({ posts, tags, meta }) => {
|
||||
const Index = ({ posts, tags, meta, categories }) => {
|
||||
return (
|
||||
<BaseLayout meta={meta} tags={tags} totalPosts={posts}>
|
||||
<BaseLayout meta={meta} tags={tags} totalPosts={posts} categories={categories}>
|
||||
<div className='flex-grow bg-gray-200 dark:bg-black shadow-inner'>
|
||||
<TagsBar tags={tags} />
|
||||
<BlogPostListScroll posts={posts} tags={tags} />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import TagsBar from '@/components/TagsBar'
|
||||
@@ -11,6 +11,8 @@ export async function getStaticProps () {
|
||||
post => post.status[0] === 'Published' && post.type[0] === 'Post'
|
||||
)
|
||||
const tags = await getAllTags(posts)
|
||||
const categories = await getAllCategories(posts)
|
||||
|
||||
const meta = {
|
||||
title: `${BLOG.title} | ${BLOG.description} `,
|
||||
description: BLOG.description,
|
||||
@@ -20,13 +22,14 @@ export async function getStaticProps () {
|
||||
props: {
|
||||
posts,
|
||||
tags,
|
||||
meta
|
||||
meta,
|
||||
categories
|
||||
},
|
||||
revalidate: 1
|
||||
}
|
||||
}
|
||||
|
||||
const Search = ({ posts, tags, meta }) => {
|
||||
const Search = ({ posts, tags, meta, categories }) => {
|
||||
// 处理查询过滤 支持标签、关键词过滤
|
||||
let filteredPosts = []
|
||||
const searchKey = getSearchKey()
|
||||
@@ -38,10 +41,10 @@ const Search = ({ posts, tags, meta }) => {
|
||||
})
|
||||
}
|
||||
return (
|
||||
<BaseLayout meta={meta} tags={tags} totalPosts={posts} currentSearch={searchKey}>
|
||||
<BaseLayout meta={meta} tags={tags} totalPosts={posts} currentSearch={searchKey} categories={categories}>
|
||||
<div className='flex-grow bg-gray-200 dark:bg-black shadow-inner'>
|
||||
<TagsBar tags={tags} />
|
||||
<BlogPostListScroll posts={filteredPosts} tags={tags} />
|
||||
<BlogPostListScroll posts={filteredPosts} tags={tags} currentSearch={searchKey} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
)
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import TagsBar from '@/components/TagsBar'
|
||||
import BlogPostListPage from '@/components/BlogPostListPage'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
||||
|
||||
export default function Tag ({ tags, posts, currentTag }) {
|
||||
export default function Tag ({ tags, posts, currentTag, categories }) {
|
||||
const meta = {
|
||||
title: `${BLOG.title} | ${currentTag}`,
|
||||
title: `${BLOG.title} | #${currentTag}`,
|
||||
description: BLOG.description,
|
||||
type: 'website'
|
||||
}
|
||||
return <BaseLayout meta={meta} tags={tags} currentTag={currentTag}>
|
||||
<div className='flex-grow'>
|
||||
return <BaseLayout meta={meta} tags={tags} currentTag={currentTag} categories={categories} totalPosts={posts}>
|
||||
<div className='flex-grow bg-gray-200 dark:bg-black shadow-inner'>
|
||||
<TagsBar tags={tags} currentTag={currentTag}/>
|
||||
<BlogPostListPage posts={posts} tags={tags}/>
|
||||
<BlogPostListScroll posts={posts} tags={tags} currentTag={currentTag}/>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
}
|
||||
@@ -25,6 +25,7 @@ export async function getStaticProps ({ params }) {
|
||||
post => post.status[0] === 'Published' && post.type[0] === 'Post'
|
||||
)
|
||||
const tags = await getAllTags(posts)
|
||||
const categories = await getAllCategories(posts)
|
||||
const filteredPosts = posts.filter(
|
||||
post => post && post.tags && post.tags.includes(currentTag)
|
||||
)
|
||||
@@ -32,7 +33,8 @@ export async function getStaticProps ({ params }) {
|
||||
props: {
|
||||
tags,
|
||||
posts: filteredPosts,
|
||||
currentTag
|
||||
currentTag,
|
||||
categories
|
||||
},
|
||||
revalidate: 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user