mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-13 23:16:47 +00:00
文章路由支持配置,完善自定义Notion字段配置
This commit is contained in:
@@ -31,6 +31,9 @@ const BLOG = {
|
||||
BACKGROUND_DARK: '#000000', // use hex value, don't forget '#'
|
||||
SUB_PATH: '', // leave this empty unless you want to deploy in a folder
|
||||
|
||||
POST_URL_PREFIX: process.env.NEXT_PUBLIC_POST_URL_PREFIX || 'article', // POST类型文章的默认路径前缀,例如默认POST类型的路径是 /article/[slug]
|
||||
// 如果此项配置为 '' 空, 则文章将没有前缀路径,使用场景: 希望 文章前缀路径为 /post 的情况 支持多级
|
||||
|
||||
POST_LIST_STYLE: 'page', // ['page','scroll] 文章列表样式:页码分页、单页滚动加载
|
||||
POST_LIST_PREVIEW: process.env.NEXT_PUBLIC_POST_PREVIEW || 'false', // 是否在列表加载文章预览
|
||||
POST_PREVIEW_LINES: 12, // 预览博客行数
|
||||
|
||||
@@ -44,7 +44,7 @@ const CommonHead = ({ meta, children }) => {
|
||||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:title" content={title} />
|
||||
{JSON.parse(BLOG.ANALYTICS_BUSUANZI_ENABLE) && <meta name="referrer" content="no-referrer-when-downgrade" />}
|
||||
{meta?.type === 'article' && (
|
||||
{meta?.type === 'Post' && (
|
||||
<>
|
||||
<meta
|
||||
property="article:published_time"
|
||||
|
||||
@@ -164,7 +164,7 @@ function fixCopy(codeCopy) {
|
||||
*/
|
||||
const mapPageUrl = id => {
|
||||
// return 'https://www.notion.so/' + id.replace(/-/g, '')
|
||||
return '/article/' + id.replace(/-/g, '')
|
||||
return '/' + id.replace(/-/g, '')
|
||||
}
|
||||
|
||||
function getMediumZoomMargin() {
|
||||
|
||||
@@ -7,7 +7,9 @@ import { isIterable } from '../utils'
|
||||
* @param tagOptions tags的下拉选项
|
||||
* @returns {Promise<{}|*[]>}
|
||||
*/
|
||||
export function getAllTags({ allPosts, sliceCount = 0, tagOptions }) {
|
||||
export function getAllTags({ allPages, sliceCount = 0, tagOptions }) {
|
||||
const allPosts = allPages.filter(page => page.type === 'Post')
|
||||
|
||||
if (!allPosts || !tagOptions) {
|
||||
return []
|
||||
}
|
||||
|
||||
@@ -21,8 +21,7 @@ import getPageProperties from './getPageProperties'
|
||||
*/
|
||||
export async function getGlobalNotionData({
|
||||
pageId = BLOG.NOTION_PAGE_ID,
|
||||
from,
|
||||
pageType = ['Post']
|
||||
from
|
||||
}) {
|
||||
// 获取Notion数据
|
||||
const notionPageData = deepClone(await getNotionPageData({ pageId, from }))
|
||||
@@ -42,7 +41,9 @@ export async function getGlobalNotionData({
|
||||
* @param {*}} param0
|
||||
* @returns
|
||||
*/
|
||||
function getLatestPosts({ allPosts, from, latestPostCount }) {
|
||||
function getLatestPosts({ allPages, from, latestPostCount }) {
|
||||
const allPosts = allPages.filter(page => page.type === 'Post')
|
||||
|
||||
const latestPosts = Object.create(allPosts).sort((a, b) => {
|
||||
const dateA = new Date(a?.lastEditedTime || a?.createdTime || a?.date?.start_date)
|
||||
const dateB = new Date(b?.lastEditedTime || b?.createdTime || b?.date?.start_date)
|
||||
@@ -82,7 +83,7 @@ function getCustomNav({ allPages }) {
|
||||
const customNav = []
|
||||
if (allPages && allPages.length > 0) {
|
||||
allPages.forEach(p => {
|
||||
if (p?.status?.[0] === 'Published') {
|
||||
if (p?.status === 'Published' && p?.type === 'Page') {
|
||||
if (p?.slug?.indexOf('http') === 0) {
|
||||
customNav.push({ icon: p.icon || null, name: p.title, to: p.slug, show: true })
|
||||
} else {
|
||||
@@ -101,7 +102,7 @@ function getCustomNav({ allPages }) {
|
||||
*/
|
||||
function getTagOptions(schema) {
|
||||
if (!schema) return {}
|
||||
const tagSchema = Object.values(schema).find(e => e.name === 'tags')
|
||||
const tagSchema = Object.values(schema).find(e => e.name === BLOG.NOTION_PROPERTY_NAME.tags)
|
||||
return tagSchema?.options || []
|
||||
}
|
||||
|
||||
@@ -112,7 +113,7 @@ function getTagOptions(schema) {
|
||||
*/
|
||||
function getCategoryOptions(schema) {
|
||||
if (!schema) return {}
|
||||
const categorySchema = Object.values(schema).find(e => e.name === 'category')
|
||||
const categorySchema = Object.values(schema).find(e => e.name === BLOG.NOTION_PROPERTY_NAME.category)
|
||||
return categorySchema?.options || []
|
||||
}
|
||||
|
||||
@@ -121,7 +122,8 @@ function getCategoryOptions(schema) {
|
||||
* @param allPosts
|
||||
* @returns {Promise<{}|*[]>}
|
||||
*/
|
||||
function getAllCategories({ allPosts, categoryOptions, sliceCount = 0 }) {
|
||||
function getAllCategories({ allPages, categoryOptions, sliceCount = 0 }) {
|
||||
const allPosts = allPages.filter(page => page.type === 'Post')
|
||||
if (!allPosts || !categoryOptions) {
|
||||
return []
|
||||
}
|
||||
@@ -220,7 +222,7 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) {
|
||||
// Check Type Page-Database和Inline-Database
|
||||
if (
|
||||
rawMetadata?.type !== 'collection_view_page' &&
|
||||
rawMetadata?.type !== 'collection_view'
|
||||
rawMetadata?.type !== 'collection_view'
|
||||
) {
|
||||
console.warn(`pageId "${pageId}" is not a database`)
|
||||
return null
|
||||
@@ -252,24 +254,23 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) {
|
||||
}
|
||||
}
|
||||
// 读取映射 配置
|
||||
console.log('当前Notion映射配置-(在blog.config.js中配置)', BLOG.NOTION_PROPERTY_NAME)
|
||||
const { type, status } = BLOG.NOTION_PROPERTY_NAME
|
||||
let postCount = 0
|
||||
|
||||
const allPages = collectionData.filter(post => {
|
||||
return post && post[type] &&
|
||||
['Page'].indexOf(post[type]?.[0]) > -1 &&
|
||||
(post[status]?.[0] === 'Published' || post[status]?.[0] === 'Invisible')
|
||||
})
|
||||
const allPosts = collectionData.filter(post => {
|
||||
return post && post[status] &&
|
||||
['Post'].indexOf(post[type]?.[0]) > -1 &&
|
||||
post[status]?.[0] === 'Published'
|
||||
})
|
||||
console.log('全部单页', allPages.length, '全部博客', allPosts.length)
|
||||
if (post.type === 'Post' && (post.status === 'Published' || post.status === 'Invisible')) {
|
||||
postCount++
|
||||
}
|
||||
|
||||
return post &&
|
||||
post.type &&
|
||||
(post.type === 'Post' || post.type === 'Page') &&
|
||||
(post.status === 'Published' || post.status === 'Invisible')
|
||||
}
|
||||
)
|
||||
|
||||
// Sort by date
|
||||
if (BLOG.POSTS_SORT_BY === 'date') {
|
||||
allPosts.sort((a, b) => {
|
||||
allPages.sort((a, b) => {
|
||||
const dateA = new Date(a?.date?.start_date || a.createdTime)
|
||||
const dateB = new Date(b?.date?.start_date || b.createdTime)
|
||||
return dateB - dateA
|
||||
@@ -277,15 +278,13 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) {
|
||||
}
|
||||
|
||||
const customNav = getCustomNav({ allPages })
|
||||
const postCount = allPosts?.length || 0
|
||||
const categories = getAllCategories({ allPosts, categoryOptions, sliceCount: BLOG.PREVIEW_CATEGORY_COUNT })
|
||||
const tags = getAllTags({ allPosts, tagOptions, sliceCount: BLOG.PREVIEW_TAG_COUNT })
|
||||
const latestPosts = getLatestPosts({ allPosts, from, latestPostCount: 5 })
|
||||
const categories = getAllCategories({ allPages, categoryOptions, sliceCount: BLOG.PREVIEW_CATEGORY_COUNT })
|
||||
const tags = getAllTags({ allPages, tagOptions, sliceCount: BLOG.PREVIEW_TAG_COUNT })
|
||||
const latestPosts = getLatestPosts({ allPages, from, latestPostCount: 5 })
|
||||
|
||||
return {
|
||||
siteInfo,
|
||||
allPages,
|
||||
allPosts,
|
||||
collection,
|
||||
collectionQuery,
|
||||
collectionId,
|
||||
|
||||
@@ -58,6 +58,7 @@ async function getPageProperties(id, block, schema, authToken, tagOptions, siteI
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置自定义字段
|
||||
const fieldNames = BLOG.NOTION_PROPERTY_NAME
|
||||
if (fieldNames) {
|
||||
@@ -65,7 +66,16 @@ async function getPageProperties(id, block, schema, authToken, tagOptions, siteI
|
||||
if (fieldNames[key] && properties[fieldNames[key]]) properties[key] = properties[fieldNames[key]]
|
||||
})
|
||||
}
|
||||
properties.slug = properties.slug ?? properties.id
|
||||
|
||||
properties.type = properties.type[0]
|
||||
properties.status = properties.status[0]
|
||||
|
||||
if (properties.type === 'Post') {
|
||||
properties.slug = BLOG.POST_URL_PREFIX + '/' + (properties.slug ?? properties.id)
|
||||
} else {
|
||||
properties.slug = (properties.slug ?? properties.id)
|
||||
}
|
||||
|
||||
properties.createdTime = formatDate(new Date(value.created_time).toString(), BLOG.LANG)
|
||||
properties.lastEditedTime = formatDate(new Date(value?.last_edited_time).toString(), BLOG.LANG)
|
||||
properties.fullWidth = value.format?.page_full_width ?? false
|
||||
|
||||
@@ -38,7 +38,7 @@ export async function generateRss(posts) {
|
||||
feed.addItem({
|
||||
title: post.title,
|
||||
guid: `${post.id}`,
|
||||
link: `${BLOG.LINK}/article/${post.slug}`,
|
||||
link: `${BLOG.LINK}/${post.slug}`,
|
||||
description: post.summary,
|
||||
content: await createFeedContent(post),
|
||||
date: new Date(post?.date?.start_date || post?.createdTime)
|
||||
|
||||
@@ -62,8 +62,8 @@ const Slug = props => {
|
||||
const meta = {
|
||||
title: `${post?.title} | ${siteInfo?.title}`,
|
||||
description: post?.summary,
|
||||
type: 'article',
|
||||
slug: 'article/' + post?.slug,
|
||||
type: post.type,
|
||||
slug: post?.slug,
|
||||
image: post?.page_cover,
|
||||
category: post?.category?.[0],
|
||||
tags: post?.tags
|
||||
@@ -95,13 +95,16 @@ export async function getStaticPaths() {
|
||||
}
|
||||
|
||||
export async function getStaticProps({ params: { slug } }) {
|
||||
const from = `slug-props-${slug}`
|
||||
// slug 是个数组
|
||||
const fullSlug = slug.join('/')
|
||||
const from = `slug-props-${fullSlug}`
|
||||
const props = await getGlobalNotionData({ from, pageType: ['Post'] })
|
||||
const allPosts = props.allPosts
|
||||
props.post = props.allPosts.find((p) => {
|
||||
return p.slug === slug || p.id === idToUuid(slug)
|
||||
const allPosts = props.allPages.filter(page => page.type === 'Post')
|
||||
props.post = allPosts.find((p) => {
|
||||
return p.slug === fullSlug || p.id === idToUuid(fullSlug)
|
||||
})
|
||||
if (!props.post) {
|
||||
console.warn('无效地址', fullSlug)
|
||||
return { props, revalidate: 1 }
|
||||
}
|
||||
props.post.blockMap = await getPostBlocks(props.post.id, 'slug')
|
||||
@@ -114,6 +117,7 @@ export async function getStaticProps({ params: { slug } }) {
|
||||
allPosts,
|
||||
BLOG.POST_RECOMMEND_COUNT
|
||||
)
|
||||
delete props.allPages
|
||||
return {
|
||||
props,
|
||||
revalidate: 1
|
||||
115
pages/[slug].js
115
pages/[slug].js
@@ -1,115 +0,0 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { getPostBlocks } from '@/lib/notion'
|
||||
import { getGlobalNotionData } from '@/lib/notion/getNotionData'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import * as ThemeMap from '@/themes'
|
||||
import React from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { isBrowser } from '@/lib/utils'
|
||||
|
||||
/**
|
||||
* 根据notion的slug访问页面,针对类型为Page的页面
|
||||
* @param {*} props
|
||||
* @returns
|
||||
*/
|
||||
const Slug = props => {
|
||||
const { theme, changeLoadingState } = useGlobal()
|
||||
const ThemeComponents = ThemeMap[theme]
|
||||
const { post } = props
|
||||
|
||||
if (!post) {
|
||||
changeLoadingState(true)
|
||||
const router = useRouter()
|
||||
setTimeout(() => {
|
||||
if (isBrowser()) {
|
||||
const article = document.getElementById('container')
|
||||
if (!article) {
|
||||
router.push('/404').then(() => {
|
||||
console.warn('找不到页面', router.asPath)
|
||||
})
|
||||
}
|
||||
}
|
||||
}, 5000)
|
||||
const meta = { title: `${props?.siteInfo?.title || BLOG.TITLE} | loading` }
|
||||
return <ThemeComponents.LayoutSlug {...props} showArticleInfo={true} meta={meta} />
|
||||
}
|
||||
|
||||
changeLoadingState(false)
|
||||
|
||||
// 文章锁🔐
|
||||
const [lock, setLock] = React.useState(post.password && post.password !== '')
|
||||
React.useEffect(() => {
|
||||
if (post.password && post.password !== '') {
|
||||
setLock(true)
|
||||
} else {
|
||||
setLock(false)
|
||||
}
|
||||
}, [post])
|
||||
|
||||
/**
|
||||
* 验证文章密码
|
||||
* @param {*} result
|
||||
*/
|
||||
const validPassword = result => {
|
||||
if (result) {
|
||||
setLock(false)
|
||||
}
|
||||
}
|
||||
|
||||
const { siteInfo } = props
|
||||
const meta = {
|
||||
title: `${post?.title} | ${siteInfo?.title}`,
|
||||
description: post?.summary,
|
||||
type: 'article',
|
||||
slug: 'article/' + post?.slug,
|
||||
image: post?.page_cover,
|
||||
category: post?.category?.[0],
|
||||
tags: post?.tags
|
||||
}
|
||||
|
||||
props = { ...props, meta, lock, setLock, validPassword }
|
||||
|
||||
return <ThemeComponents.LayoutSlug {...props} showArticleInfo={false} />
|
||||
}
|
||||
|
||||
export async function getStaticPaths() {
|
||||
if (!BLOG.isProd) {
|
||||
return {
|
||||
paths: [],
|
||||
fallback: true
|
||||
}
|
||||
}
|
||||
|
||||
const from = 'slug-paths'
|
||||
const { allPages } = await getGlobalNotionData({ from, pageType: ['Page'] })
|
||||
|
||||
return {
|
||||
paths: allPages.map(row => ({ params: { slug: row.slug } })),
|
||||
fallback: true
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStaticProps({ params: { slug } }) {
|
||||
const from = `slug-props-${slug}`
|
||||
const props = await getGlobalNotionData({ from, pageType: ['Page'] })
|
||||
const { allPages } = props
|
||||
const page = allPages?.find(p => p.slug === slug)
|
||||
if (!page) {
|
||||
return { props: {}, revalidate: 1 }
|
||||
}
|
||||
|
||||
try {
|
||||
page.blockMap = await getPostBlocks(page.id, 'slug')
|
||||
} catch (error) {
|
||||
console.error('获取文章详情失败', error)
|
||||
}
|
||||
|
||||
props.post = page
|
||||
|
||||
return {
|
||||
props,
|
||||
revalidate: 1
|
||||
}
|
||||
}
|
||||
|
||||
export default Slug
|
||||
@@ -11,8 +11,9 @@ const Index = props => {
|
||||
|
||||
export async function getStaticProps() {
|
||||
const from = 'index'
|
||||
const props = await getGlobalNotionData({ from, pageType: ['Post'] })
|
||||
const { allPosts, siteInfo } = props
|
||||
const props = await getGlobalNotionData({ from })
|
||||
const { allPages, siteInfo } = props
|
||||
const allPosts = allPages.filter(page => page.type === 'Post')
|
||||
const meta = {
|
||||
title: `${siteInfo?.title} | ${siteInfo?.description}`,
|
||||
description: siteInfo?.description,
|
||||
|
||||
@@ -43,7 +43,7 @@ export const LayoutArchive = props => {
|
||||
</span>{' '}
|
||||
|
||||
<Link
|
||||
href={`${BLOG.SUB_PATH}/article/${post.slug}`}
|
||||
href={`${BLOG.SUB_PATH}/${post.slug}`}
|
||||
passHref
|
||||
>
|
||||
<a className="dark:text-gray-400 dark:hover:text-gray-300 overflow-x-hidden hover:underline cursor-pointer text-gray-600">
|
||||
|
||||
@@ -30,7 +30,7 @@ export const LayoutCategory = props => {
|
||||
{postsToShow.map(p => (
|
||||
<article key={p.id} className="mb-12" >
|
||||
<h2 className="mb-4">
|
||||
<Link href={`/article/${p.slug}`}>
|
||||
<Link href={`/${p.slug}`}>
|
||||
<a className="text-black text-xl md:text-2xl no-underline hover:underline"> {p.title}</a>
|
||||
</Link>
|
||||
</h2>
|
||||
|
||||
@@ -62,7 +62,7 @@ export const LayoutSearch = props => {
|
||||
{postsToShow.map(p => (
|
||||
<article key={p.id} className="mb-12" >
|
||||
<h2 className="mb-4">
|
||||
<Link href={`/article/${p.slug}`}>
|
||||
<Link href={`/${p.slug}`}>
|
||||
<a className="text-black text-xl md:text-2xl no-underline hover:underline replace"> {p.title}</a>
|
||||
</Link>
|
||||
</h2>
|
||||
|
||||
@@ -28,7 +28,7 @@ export const LayoutTag = props => {
|
||||
{postsToShow.map(p => (
|
||||
<article key={p.id} className="mb-12" >
|
||||
<h2 className="mb-4">
|
||||
<Link href={`/article/${p.slug}`}>
|
||||
<Link href={`/${p.slug}`}>
|
||||
<a className="text-black text-xl md:text-2xl no-underline hover:underline"> {p.title}</a>
|
||||
</Link>
|
||||
</h2>
|
||||
|
||||
@@ -23,7 +23,7 @@ export const BlogList = (props) => {
|
||||
{posts.map(p => (
|
||||
<article key={p.id} className="mb-12" >
|
||||
<h2 className="mb-4">
|
||||
<Link href={`/article/${p.slug}`}>
|
||||
<Link href={`/${p.slug}`}>
|
||||
<a className="text-black dark:text-gray-100 text-xl md:text-2xl no-underline hover:underline"> {p.title}</a>
|
||||
</Link>
|
||||
</h2>
|
||||
|
||||
@@ -30,7 +30,7 @@ export const SideBar = (props) => {
|
||||
<div className="p-4">
|
||||
<ul className="list-reset leading-normal">
|
||||
{latestPosts?.map(p => {
|
||||
return <Link key={p.id} href={`/article/${p.slug}`} passHref>
|
||||
return <Link key={p.id} href={`/${p.slug}`} passHref>
|
||||
<li> <a href="#" className="text-gray-darkest text-sm">{p.title}</a></li>
|
||||
</Link>
|
||||
})}
|
||||
|
||||
@@ -10,12 +10,12 @@ export default function ArticleAround ({ prev, next }) {
|
||||
return <></>
|
||||
}
|
||||
return <section className='text-gray-800 h-28 flex items-center justify-between space-x-5 my-4'>
|
||||
<Link href={`/article/${prev.slug}`} passHref>
|
||||
<Link href={`/${prev.slug}`} passHref>
|
||||
<a className='text-sm cursor-pointer justify-center items-center flex w-full h-full bg-white bg-opacity-40 hover:bg-hexo-black-gray dark:bg-hexo-black-gray dark:text-gray-200 hover:text-white duration-300'>
|
||||
<i className='mr-1 fas fa-angle-double-left' />{prev.title}
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`/article/${next.slug}`} passHref>
|
||||
<Link href={`/${next.slug}`} passHref>
|
||||
<a className='text-sm cursor-pointer justify-center items-center flex w-full h-full bg-white bg-opacity-40 hover:bg-hexo-black-gray dark:bg-hexo-black-gray dark:text-gray-200 hover:text-white duration-300'>{next.title}
|
||||
<i className='ml-1 my-1 fas fa-angle-double-right' />
|
||||
</a>
|
||||
|
||||
@@ -13,7 +13,7 @@ const BlogCard = ({ post, showSummary }) => {
|
||||
className="animate__animated animate__fadeIn flex flex-col-reverse justify-between duration-300"
|
||||
>
|
||||
<div className="p-2 flex flex-col w-full">
|
||||
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`} passHref>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref>
|
||||
<a
|
||||
className={`cursor-pointer font-bold hover:underline text-xl ${showPreview ? 'justify-center' : 'justify-start'
|
||||
} leading-tight text-gray-700 dark:text-gray-100 hover:text-blue-500 dark:hover:text-blue-400`}
|
||||
@@ -30,7 +30,7 @@ const BlogCard = ({ post, showSummary }) => {
|
||||
</div>
|
||||
|
||||
{CONFIG_FUKA.POST_LIST_COVER && post?.page_cover && (
|
||||
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`} passHref>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref>
|
||||
<div className="h-40 w-full relative duration-200 cursor-pointer transform overflow-hidden">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
|
||||
@@ -29,7 +29,7 @@ const BlogArchiveItem = ({ posts = [], archiveTitle }) => {
|
||||
<div id={post?.date?.start_date}>
|
||||
<span className="text-gray-400">{post.date?.start_date}</span>{' '}
|
||||
|
||||
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`} passHref>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref>
|
||||
<a className="dark:text-gray-400 dark:hover:text-gray-300 overflow-x-hidden hover:underline cursor-pointer text-gray-600">
|
||||
{post.title}
|
||||
</a>
|
||||
|
||||
@@ -11,12 +11,12 @@ export default function ArticleAdjacent ({ prev, next }) {
|
||||
return <></>
|
||||
}
|
||||
return <section className='text-gray-800 items-center text-xs md:text-sm flex justify-between m-1 '>
|
||||
<Link href={`/article/${prev.slug}`} passHref>
|
||||
<Link href={`/${prev.slug}`} passHref>
|
||||
<a className='py-1 cursor-pointer hover:underline justify-start items-center dark:text-white flex w-full h-full duration-200'>
|
||||
<i className='mr-1 fas fa-angle-left' />{prev.title}
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`/article/${next.slug}`} passHref>
|
||||
<Link href={`/${next.slug}`} passHref>
|
||||
<a className='py-1 cursor-pointer hover:underline justify-end items-center dark:text-white flex w-full h-full duration-200'>{next.title}
|
||||
<i className='ml-1 my-1 fas fa-angle-right' />
|
||||
</a>
|
||||
|
||||
@@ -35,7 +35,7 @@ export default function ArticleRecommend({ recommendPosts, siteInfo }) {
|
||||
<Link
|
||||
key={post.id}
|
||||
title={post.title}
|
||||
href={`${BLOG.SUB_PATH}/article/${post.slug}`}
|
||||
href={`${BLOG.SUB_PATH}/${post.slug}`}
|
||||
passHref
|
||||
>
|
||||
<a
|
||||
|
||||
@@ -29,7 +29,7 @@ const BlogPostArchive = ({ posts = [], archiveTitle }) => {
|
||||
<div id={post?.date?.start_date}>
|
||||
<span className="text-gray-400">{post.date?.start_date}</span>{' '}
|
||||
|
||||
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`} passHref>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref>
|
||||
<a className="dark:text-gray-400 dark:hover:text-indigo-300 overflow-x-hidden hover:underline cursor-pointer text-gray-600">
|
||||
{post.title}
|
||||
</a>
|
||||
|
||||
@@ -14,7 +14,7 @@ const BlogPostCard = ({ post, showSummary }) => {
|
||||
className="animate__animated animate__fadeIn flex flex-col-reverse lg:flex-row justify-between duration-300"
|
||||
>
|
||||
<div className="lg:p-8 p-4 flex flex-col w-full">
|
||||
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`} passHref>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref>
|
||||
<a
|
||||
className={`replace cursor-pointer hover:underline text-2xl font-sans ${showPreview ? 'text-center' : ''
|
||||
} leading-tight text-gray-700 dark:text-gray-100 hover:text-indigo-700 dark:hover:text-indigo-400`}
|
||||
@@ -79,7 +79,7 @@ const BlogPostCard = ({ post, showSummary }) => {
|
||||
</div>
|
||||
|
||||
{CONFIG_HEXO.POST_LIST_COVER && !showPreview && post?.page_cover && !post.results && (
|
||||
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`} passHref>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref>
|
||||
<div className="flex w-full relative duration-200 rounded-t-xl lg:rounded-r-xl lg:rounded-t-none cursor-pointer transform overflow-hidden">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
|
||||
@@ -25,7 +25,7 @@ const LatestPostsGroup = ({ latestPosts, siteInfo }) => {
|
||||
</div>
|
||||
</div>
|
||||
{latestPosts.map(post => {
|
||||
const selected = currentPath === `${BLOG.SUB_PATH}/article/${post.slug}`
|
||||
const selected = currentPath === `${BLOG.SUB_PATH}/${post.slug}`
|
||||
const headerImage = post?.page_cover
|
||||
? `url("${post.page_cover}")`
|
||||
: `url("${siteInfo?.pageCover}")`
|
||||
@@ -34,7 +34,7 @@ const LatestPostsGroup = ({ latestPosts, siteInfo }) => {
|
||||
<Link
|
||||
key={post.id}
|
||||
title={post.title}
|
||||
href={`${BLOG.SUB_PATH}/article/${post.slug}`}
|
||||
href={`${BLOG.SUB_PATH}/${post.slug}`}
|
||||
passHref
|
||||
>
|
||||
<a className={'my-1 flex font-sans'}>
|
||||
|
||||
@@ -45,7 +45,7 @@ export const LayoutArchive = props => {
|
||||
</span>{' '}
|
||||
|
||||
<Link
|
||||
href={`${BLOG.SUB_PATH}/article/${post.slug}`}
|
||||
href={`${BLOG.SUB_PATH}/${post.slug}`}
|
||||
passHref
|
||||
>
|
||||
<a className="dark:text-gray-400 dark:hover:text-gray-300 overflow-x-hidden hover:underline cursor-pointer text-gray-600">
|
||||
|
||||
@@ -10,12 +10,12 @@ export default function ArticleAround ({ prev, next }) {
|
||||
return <></>
|
||||
}
|
||||
return <section className='text-gray-800 h-12 flex items-center justify-between space-x-5 my-4'>
|
||||
<Link href={`/article/${prev.slug}`} passHref>
|
||||
<Link href={`/${prev.slug}`} passHref>
|
||||
<a className='text-sm cursor-pointer justify-start items-center flex hover:underline duration-300'>
|
||||
<i className='mr-1 fas fa-angle-double-left' />{prev.title}
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`/article/${next.slug}`} passHref>
|
||||
<Link href={`/${next.slug}`} passHref>
|
||||
<a className='text-sm cursor-pointer justify-end items-center flex hover:underline duration-300'>{next.title}
|
||||
<i className='ml-1 my-1 fas fa-angle-double-right' />
|
||||
</a>
|
||||
|
||||
@@ -16,7 +16,7 @@ const BlogPostCard = ({ post, showSummary }) => {
|
||||
className="animate__animated animate__fadeIn duration-300 mb-6 max-w-7xl border-b dark:border-gray-800 "
|
||||
>
|
||||
<div className="lg:p-8 p-4 flex flex-col w-full">
|
||||
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`} passHref>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref>
|
||||
<a
|
||||
className={
|
||||
'cursor-pointer font-bold font-sans hover:underline text-3xl leading-tight text-gray-700 dark:text-gray-100 hover:text-green-500 dark:hover:text-green-400'
|
||||
@@ -54,7 +54,7 @@ const BlogPostCard = ({ post, showSummary }) => {
|
||||
<NotionPage post={post} />
|
||||
<div className="pointer-events-none border-t pt-8 border-dashed">
|
||||
<div className="w-full justify-start flex">
|
||||
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`} passHref>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref>
|
||||
<a className="hover:bg-opacity-100 hover:scale-105 duration-200 pointer-events-auto transform font-bold text-green-500 cursor-pointer">
|
||||
{locale.COMMON.ARTICLE_DETAIL}
|
||||
<i className="ml-1 fas fa-angle-right" />
|
||||
|
||||
@@ -10,12 +10,12 @@ export default function BlogAround ({ prev, next }) {
|
||||
return <></>
|
||||
}
|
||||
return <section className='text-gray-800 border-t dark:text-gray-300 flex flex-wrap lg:flex-nowrap lg:space-x-10 justify-between py-2'>
|
||||
{prev && <Link href={`/article/${prev.slug}`} passHref>
|
||||
{prev && <Link href={`/${prev.slug}`} passHref>
|
||||
<a className='text-sm py-3 text-gray-400 hover:underline cursor-pointer'>
|
||||
<i className='mr-1 fas fa-angle-double-left' />{prev.title}
|
||||
</a>
|
||||
</Link>}
|
||||
{next && <Link href={`/article/${next.slug}`} passHref>
|
||||
{next && <Link href={`/${next.slug}`} passHref>
|
||||
<a className='text-sm flex py-3 text-gray-400 hover:underline cursor-pointer'>{next.title}
|
||||
<i className='ml-1 my-1 fas fa-angle-double-right' />
|
||||
</a>
|
||||
|
||||
@@ -29,7 +29,7 @@ const BlogPostArchive = ({ posts = [], archiveTitle }) => {
|
||||
<div id={post?.date?.start_date}>
|
||||
<span className="text-gray-400">{post.date?.start_date}</span>{' '}
|
||||
|
||||
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`} passHref>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref>
|
||||
<a className="dark:text-gray-400 dark:hover:text-gray-300 overflow-x-hidden hover:underline cursor-pointer text-gray-600">
|
||||
{post.title}
|
||||
</a>
|
||||
|
||||
@@ -18,7 +18,7 @@ const BlogPostCard = ({ post, showSummary }) => {
|
||||
className="flex flex-col-reverse justify-between duration-300"
|
||||
>
|
||||
<div className="lg:p-8 p-4 flex flex-col w-full">
|
||||
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`} passHref>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref>
|
||||
<a
|
||||
className={`cursor-pointer font-bold hover:underline text-3xl ${showPreview ? 'text-center' : ''
|
||||
} leading-tight text-gray-700 dark:text-gray-100 hover:text-blue-500 dark:hover:text-blue-400`}
|
||||
@@ -84,7 +84,7 @@ const BlogPostCard = ({ post, showSummary }) => {
|
||||
)}
|
||||
|
||||
<div className="text-right border-t pt-8 border-dashed">
|
||||
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`}>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`}>
|
||||
<a className="hover:bg-opacity-100 hover:underline transform duration-300 p-3 text-white bg-gray-800 dark:bg-black cursor-pointer">
|
||||
{locale.COMMON.ARTICLE_DETAIL}
|
||||
<i className="ml-1 fas fa-angle-right" />
|
||||
@@ -94,7 +94,7 @@ const BlogPostCard = ({ post, showSummary }) => {
|
||||
</div>
|
||||
|
||||
{CONFIG_NEXT.POST_LIST_COVER && post?.page_cover && (
|
||||
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`} passHref>
|
||||
<Link href={`${BLOG.SUB_PATH}/${post.slug}`} passHref>
|
||||
<div className="h-72 w-full relative duration-200 cursor-pointer transform overflow-hidden">
|
||||
<Image
|
||||
className="hover:scale-105 transform duration-500"
|
||||
|
||||
@@ -26,12 +26,12 @@ const LatestPostsGroup = ({ latestPosts }) => {
|
||||
</div>
|
||||
</div>
|
||||
{latestPosts.map(post => {
|
||||
const selected = currentPath === `${BLOG.SUB_PATH}/article/${post.slug}`
|
||||
const selected = currentPath === `${BLOG.SUB_PATH}/${post.slug}`
|
||||
return (
|
||||
<Link
|
||||
key={post.id}
|
||||
title={post.title}
|
||||
href={`${BLOG.SUB_PATH}/article/${post.slug}`}
|
||||
href={`${BLOG.SUB_PATH}/${post.slug}`}
|
||||
passHref
|
||||
>
|
||||
<a className={'my-1 flex font-light'}>
|
||||
|
||||
@@ -18,7 +18,7 @@ const RecommendPosts = ({ recommendPosts }) => {
|
||||
<ul className="font-light text-sm">
|
||||
{recommendPosts.map(post => (
|
||||
<li className="py-1" key={post.id}>
|
||||
<Link href={`/article/${post.slug}`}>
|
||||
<Link href={`/${post.slug}`}>
|
||||
<a className="cursor-pointer hover:underline">
|
||||
{post.title}
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user