mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-06-03 07:26:45 +00:00
slug 兼容性优化,支持用任意前缀访问文章不限于article
This commit is contained in:
@@ -26,9 +26,12 @@ const Equation = dynamic(
|
|||||||
{ ssr: false }
|
{ ssr: false }
|
||||||
)
|
)
|
||||||
|
|
||||||
const Pdf = dynamic(() => import('react-notion-x/build/third-party/pdf').then(m => m.Pdf), {
|
const Pdf = dynamic(
|
||||||
ssr: false
|
() => import('react-notion-x/build/third-party/pdf').then(m => m.Pdf),
|
||||||
})
|
{
|
||||||
|
ssr: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// https://github.com/txs
|
// https://github.com/txs
|
||||||
// import PrismMac from '@/components/PrismMac'
|
// import PrismMac from '@/components/PrismMac'
|
||||||
@@ -46,13 +49,25 @@ const TweetEmbed = dynamic(() => import('react-tweet-embed'), {
|
|||||||
/**
|
/**
|
||||||
* 文内google广告
|
* 文内google广告
|
||||||
*/
|
*/
|
||||||
const AdEmbed = dynamic(() => import('@/components/GoogleAdsense').then(m => m.AdEmbed), { ssr: true })
|
const AdEmbed = dynamic(
|
||||||
|
() => import('@/components/GoogleAdsense').then(m => m.AdEmbed),
|
||||||
|
{ ssr: true }
|
||||||
|
)
|
||||||
|
|
||||||
const Collection = dynamic(() => import('react-notion-x/build/third-party/collection').then(m => m.Collection), {
|
const Collection = dynamic(
|
||||||
ssr: true
|
() =>
|
||||||
})
|
import('react-notion-x/build/third-party/collection').then(
|
||||||
|
m => m.Collection
|
||||||
|
),
|
||||||
|
{
|
||||||
|
ssr: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const Modal = dynamic(() => import('react-notion-x/build/third-party/modal').then(m => m.Modal), { ssr: false })
|
const Modal = dynamic(
|
||||||
|
() => import('react-notion-x/build/third-party/modal').then(m => m.Modal),
|
||||||
|
{ ssr: false }
|
||||||
|
)
|
||||||
|
|
||||||
const Tweet = ({ id }) => {
|
const Tweet = ({ id }) => {
|
||||||
return <TweetEmbed tweetId={id} />
|
return <TweetEmbed tweetId={id} />
|
||||||
@@ -83,19 +98,22 @@ const NotionPage = ({ post, className }) => {
|
|||||||
// 将相册gallery下的图片加入放大功能
|
// 将相册gallery下的图片加入放大功能
|
||||||
if (siteConfig('POST_DISABLE_GALLERY_CLICK')) {
|
if (siteConfig('POST_DISABLE_GALLERY_CLICK')) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (isBrowser) {
|
const imgList = document?.querySelectorAll(
|
||||||
const imgList = document?.querySelectorAll('.notion-collection-card-cover img')
|
'.notion-asset-wrapper-image img'
|
||||||
if (imgList && zoomRef.current) {
|
)
|
||||||
for (let i = 0; i < imgList.length; i++) {
|
|
||||||
zoomRef.current.attach(imgList[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const cards = document.getElementsByClassName('notion-collection-card')
|
console.log('放大', imgList)
|
||||||
for (const e of cards) {
|
|
||||||
e.removeAttribute('href')
|
if (imgList && zoomRef.current) {
|
||||||
|
for (let i = 0; i < imgList.length; i++) {
|
||||||
|
zoomRef.current.attach(imgList[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cards = document.getElementsByClassName('notion-collection-card')
|
||||||
|
for (const e of cards) {
|
||||||
|
e.removeAttribute('href')
|
||||||
|
}
|
||||||
}, 800)
|
}, 800)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,10 +126,16 @@ const NotionPage = ({ post, className }) => {
|
|||||||
const allAnchorTags = document.getElementsByTagName('a') // 或者使用 document.querySelectorAll('a') 获取 NodeList
|
const allAnchorTags = document.getElementsByTagName('a') // 或者使用 document.querySelectorAll('a') 获取 NodeList
|
||||||
for (const anchorTag of allAnchorTags) {
|
for (const anchorTag of allAnchorTags) {
|
||||||
if (anchorTag?.target === '_blank') {
|
if (anchorTag?.target === '_blank') {
|
||||||
const hrefWithoutQueryHash = anchorTag.href.split('?')[0].split('#')[0]
|
const hrefWithoutQueryHash = anchorTag.href
|
||||||
const hrefWithRelativeHash = currentURL.split('#')[0] + anchorTag.href.split('#')[1]
|
.split('?')[0]
|
||||||
|
.split('#')[0]
|
||||||
|
const hrefWithRelativeHash =
|
||||||
|
currentURL.split('#')[0] + anchorTag.href.split('#')[1]
|
||||||
|
|
||||||
if (currentURL === hrefWithoutQueryHash || currentURL === hrefWithRelativeHash) {
|
if (
|
||||||
|
currentURL === hrefWithoutQueryHash ||
|
||||||
|
currentURL === hrefWithRelativeHash
|
||||||
|
) {
|
||||||
anchorTag.target = '_self'
|
anchorTag.target = '_self'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,14 +145,20 @@ const NotionPage = ({ post, className }) => {
|
|||||||
// 放大图片:调整图片质量
|
// 放大图片:调整图片质量
|
||||||
const observer = new MutationObserver((mutationsList, observer) => {
|
const observer = new MutationObserver((mutationsList, observer) => {
|
||||||
mutationsList.forEach(mutation => {
|
mutationsList.forEach(mutation => {
|
||||||
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
|
if (
|
||||||
|
mutation.type === 'attributes' &&
|
||||||
|
mutation.attributeName === 'class'
|
||||||
|
) {
|
||||||
if (mutation.target.classList.contains('medium-zoom-image--opened')) {
|
if (mutation.target.classList.contains('medium-zoom-image--opened')) {
|
||||||
// 等待动画完成后替换为更高清的图像
|
// 等待动画完成后替换为更高清的图像
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 获取该元素的 src 属性
|
// 获取该元素的 src 属性
|
||||||
const src = mutation?.target?.getAttribute('src')
|
const src = mutation?.target?.getAttribute('src')
|
||||||
// 替换为更高清的图像
|
// 替换为更高清的图像
|
||||||
mutation?.target?.setAttribute('src', compressImage(src, siteConfig('IMAGE_ZOOM_IN_WIDTH', 1200)))
|
mutation?.target?.setAttribute(
|
||||||
|
'src',
|
||||||
|
compressImage(src, siteConfig('IMAGE_ZOOM_IN_WIDTH', 1200))
|
||||||
|
)
|
||||||
}, 800)
|
}, 800)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,21 +166,23 @@ const NotionPage = ({ post, className }) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 监视整个文档中的元素和属性的变化
|
// 监视整个文档中的元素和属性的变化
|
||||||
observer.observe(document.body, { attributes: true, subtree: true, attributeFilter: ['class'] })
|
observer.observe(document.body, {
|
||||||
|
attributes: true,
|
||||||
|
subtree: true,
|
||||||
|
attributeFilter: ['class']
|
||||||
|
})
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
observer.disconnect()
|
observer.disconnect()
|
||||||
}
|
}
|
||||||
}, [])
|
}, [post])
|
||||||
|
|
||||||
if (!post || !post.blockMap) {
|
|
||||||
return <>{post?.summary || ''}</>
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id='notion-article' className={`mx-auto overflow-hidden ${className || ''}`}>
|
<div
|
||||||
|
id='notion-article'
|
||||||
|
className={`mx-auto overflow-hidden ${className || ''}`}>
|
||||||
<NotionRenderer
|
<NotionRenderer
|
||||||
recordMap={post.blockMap}
|
recordMap={post?.blockMap}
|
||||||
mapPageUrl={mapPageUrl}
|
mapPageUrl={mapPageUrl}
|
||||||
mapImageUrl={mapImgUrl}
|
mapImageUrl={mapImgUrl}
|
||||||
components={{
|
components={{
|
||||||
|
|||||||
@@ -156,19 +156,11 @@ function getCustomNav({ allPages }) {
|
|||||||
if (allPages && allPages.length > 0) {
|
if (allPages && allPages.length > 0) {
|
||||||
allPages.forEach(p => {
|
allPages.forEach(p => {
|
||||||
p.to = p.slug
|
p.to = p.slug
|
||||||
if (p?.slug?.indexOf('http') === 0) {
|
|
||||||
p.target = '_blank'
|
|
||||||
} else {
|
|
||||||
p.target = '_self'
|
|
||||||
if (p?.slug?.indexOf('/') !== 0) {
|
|
||||||
p.to = '/' + p.slug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
customNav.push({
|
customNav.push({
|
||||||
icon: p.icon || null,
|
icon: p.icon || null,
|
||||||
name: p.title,
|
name: p.title,
|
||||||
to: p.slug,
|
href: p.href,
|
||||||
target: '_blank',
|
target: p.target,
|
||||||
show: true
|
show: true
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -192,15 +184,6 @@ function getCustomMenu({ collectionData, NOTION_CONFIG }) {
|
|||||||
if (menuPages && menuPages.length > 0) {
|
if (menuPages && menuPages.length > 0) {
|
||||||
menuPages.forEach(e => {
|
menuPages.forEach(e => {
|
||||||
e.show = true
|
e.show = true
|
||||||
if (e?.slug?.indexOf('http') === 0) {
|
|
||||||
e.target = '_blank'
|
|
||||||
e.to = e.slug
|
|
||||||
} else {
|
|
||||||
e.target = '_self'
|
|
||||||
if (e?.slug?.indexOf('http') !== 0 && e?.slug?.indexOf('/') !== 0) {
|
|
||||||
e.to = '/' + e.slug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (e.type === BLOG.NOTION_PROPERTY_NAME.type_menu) {
|
if (e.type === BLOG.NOTION_PROPERTY_NAME.type_menu) {
|
||||||
menus.push(e)
|
menus.push(e)
|
||||||
} else if (e.type === BLOG.NOTION_PROPERTY_NAME.type_sub_menu) {
|
} else if (e.type === BLOG.NOTION_PROPERTY_NAME.type_sub_menu) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { getDateValue, getTextContent } from 'notion-utils'
|
|||||||
import formatDate from '../utils/formatDate'
|
import formatDate from '../utils/formatDate'
|
||||||
// import { createHash } from 'crypto'
|
// import { createHash } from 'crypto'
|
||||||
import md5 from 'js-md5'
|
import md5 from 'js-md5'
|
||||||
|
import { checkContainHttp, sliceUrlFromHttp } from '../utils'
|
||||||
import { mapImgUrl } from './mapImage'
|
import { mapImgUrl } from './mapImage'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,7 +107,7 @@ export default async function getPageProperties(
|
|||||||
properties.pageCover = mapImgUrl(value?.format?.page_cover, value) ?? ''
|
properties.pageCover = mapImgUrl(value?.format?.page_cover, value) ?? ''
|
||||||
properties.pageCoverThumbnail =
|
properties.pageCoverThumbnail =
|
||||||
mapImgUrl(value?.format?.page_cover, value, 'block') ?? ''
|
mapImgUrl(value?.format?.page_cover, value, 'block') ?? ''
|
||||||
properties.ext = converToJSON(properties?.ext)
|
properties.ext = convertToJSON(properties?.ext)
|
||||||
properties.content = value.content ?? []
|
properties.content = value.content ?? []
|
||||||
properties.tagItems =
|
properties.tagItems =
|
||||||
properties?.tags?.map(tag => {
|
properties?.tags?.map(tag => {
|
||||||
@@ -117,28 +118,41 @@ export default async function getPageProperties(
|
|||||||
}) || []
|
}) || []
|
||||||
delete properties.content
|
delete properties.content
|
||||||
|
|
||||||
// 处理URL
|
// 处理URL ,为文章添加一个href字段,专门用来跳转访问
|
||||||
if (properties.type === 'Post') {
|
if (properties.type === 'Post') {
|
||||||
properties.slug = BLOG.POST_URL_PREFIX
|
properties.href = BLOG.POST_URL_PREFIX
|
||||||
? generateCustomizeUrl(properties)
|
? generateCustomizeUrl(properties)
|
||||||
: properties.slug ?? properties.id
|
: properties.slug ?? properties.id
|
||||||
} else if (properties.type === 'Page') {
|
} else if (properties.type === 'Page') {
|
||||||
properties.slug = properties.slug ?? properties.id
|
properties.href = properties.slug ?? properties.id
|
||||||
} else if (properties.type === 'Menu' || properties.type === 'SubMenu') {
|
} else if (properties.type === 'Menu' || properties.type === 'SubMenu') {
|
||||||
// 菜单路径为空、作为可展开菜单使用
|
// 菜单路径为空、作为可展开菜单使用
|
||||||
properties.to = properties.slug ?? '#'
|
properties.href = properties.slug ?? '#'
|
||||||
properties.name = properties.title ?? ''
|
properties.name = properties.title ?? ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开启伪静态路径
|
// 开启伪静态路径
|
||||||
if (JSON.parse(BLOG.PSEUDO_STATIC)) {
|
if (JSON.parse(BLOG.PSEUDO_STATIC)) {
|
||||||
if (
|
if (
|
||||||
!properties?.slug?.endsWith('.html') &&
|
!properties?.href?.endsWith('.html') &&
|
||||||
!properties?.slug?.startsWith('http')
|
!properties?.href?.startsWith('http')
|
||||||
) {
|
) {
|
||||||
properties.slug += '.html'
|
properties.href += '.html'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 最终检查超链接
|
||||||
|
properties.href = checkContainHttp(properties?.href)
|
||||||
|
? sliceUrlFromHttp(properties?.href)
|
||||||
|
: `/${properties.href}`
|
||||||
|
|
||||||
|
// 设置链接在页内或新页面打开
|
||||||
|
if (properties.href?.indexOf('http') === 0) {
|
||||||
|
properties.target = '_blank'
|
||||||
|
} else {
|
||||||
|
properties.target = '_self'
|
||||||
|
}
|
||||||
|
|
||||||
// 密码字段md5
|
// 密码字段md5
|
||||||
properties.password = properties.password
|
properties.password = properties.password
|
||||||
? md5(properties.slug + properties.password)
|
? md5(properties.slug + properties.password)
|
||||||
@@ -151,7 +165,7 @@ export default async function getPageProperties(
|
|||||||
* @param {*} str
|
* @param {*} str
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
function converToJSON(str) {
|
function convertToJSON(str) {
|
||||||
if (!str) {
|
if (!str) {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|||||||
90
lib/utils/post.js
Normal file
90
lib/utils/post.js
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/**
|
||||||
|
* 文章相关工具
|
||||||
|
*/
|
||||||
|
import { checkContainHttp } from '.'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文章的关联推荐文章列表,目前根据标签关联性筛选
|
||||||
|
* @param post
|
||||||
|
* @param {*} allPosts
|
||||||
|
* @param {*} count
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getRecommendPost(post, allPosts, count = 6) {
|
||||||
|
let recommendPosts = []
|
||||||
|
const postIds = []
|
||||||
|
const currentTags = post?.tags || []
|
||||||
|
for (let i = 0; i < allPosts.length; i++) {
|
||||||
|
const p = allPosts[i]
|
||||||
|
if (p.id === post.id || p.type.indexOf('Post') < 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let j = 0; j < currentTags.length; j++) {
|
||||||
|
const t = currentTags[j]
|
||||||
|
if (postIds.indexOf(p.id) > -1) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (p.tags && p.tags.indexOf(t) > -1) {
|
||||||
|
recommendPosts.push(p)
|
||||||
|
postIds.push(p.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recommendPosts.length > count) {
|
||||||
|
recommendPosts = recommendPosts.slice(0, count)
|
||||||
|
}
|
||||||
|
return recommendPosts
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认slug中不包含 / 符号
|
||||||
|
* @param {*} row
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function checkSlugHasNoSlash(row) {
|
||||||
|
let slug = row.slug
|
||||||
|
if (slug.startsWith('/')) {
|
||||||
|
slug = slug.substring(1)
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
(slug.match(/\//g) || []).length === 0 &&
|
||||||
|
!checkContainHttp(slug) &&
|
||||||
|
row.type.indexOf('Menu') < 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查url中包含一个 /
|
||||||
|
* @param {*} row
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function checkSlugHasOneSlash(row) {
|
||||||
|
let slug = row.slug
|
||||||
|
if (slug.startsWith('/')) {
|
||||||
|
slug = slug.substring(1)
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
(slug.match(/\//g) || []).length === 1 &&
|
||||||
|
!checkContainHttp(slug) &&
|
||||||
|
row.type.indexOf('Menu') < 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查url中包含两个及以上的 /
|
||||||
|
* @param {*} row
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function checkSlugHasMorThanTwoSlash(row) {
|
||||||
|
let slug = row.slug
|
||||||
|
if (slug.startsWith('/')) {
|
||||||
|
slug = slug.substring(1)
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
(slug.match(/\//g) || []).length >= 2 &&
|
||||||
|
row.type.indexOf('Menu') < 0 &&
|
||||||
|
!checkContainHttp(slug)
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -2,9 +2,9 @@ import BLOG from '@/blog.config'
|
|||||||
import { siteConfig } from '@/lib/config'
|
import { siteConfig } from '@/lib/config'
|
||||||
import { getGlobalData, getPost, getPostBlocks } from '@/lib/db/getSiteData'
|
import { getGlobalData, getPost, getPostBlocks } from '@/lib/db/getSiteData'
|
||||||
import { uploadDataToAlgolia } from '@/lib/plugins/algolia'
|
import { uploadDataToAlgolia } from '@/lib/plugins/algolia'
|
||||||
import { checkContainHttp } from '@/lib/utils'
|
import { checkSlugHasMorThanTwoSlash, getRecommendPost } from '@/lib/utils/post'
|
||||||
import { idToUuid } from 'notion-utils'
|
import { idToUuid } from 'notion-utils'
|
||||||
import Slug, { getRecommendPost } from '..'
|
import Slug from '..'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据notion的slug访问页面
|
* 根据notion的slug访问页面
|
||||||
@@ -33,7 +33,7 @@ export async function getStaticPaths() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
paths: allPages
|
paths: allPages
|
||||||
?.filter(row => checkSlug(row))
|
?.filter(row => checkSlugHasMorThanTwoSlash(row))
|
||||||
.map(row => ({
|
.map(row => ({
|
||||||
params: {
|
params: {
|
||||||
prefix: row.slug.split('/')[0],
|
prefix: row.slug.split('/')[0],
|
||||||
@@ -54,20 +54,15 @@ export async function getStaticProps({
|
|||||||
params: { prefix, slug, suffix },
|
params: { prefix, slug, suffix },
|
||||||
locale
|
locale
|
||||||
}) {
|
}) {
|
||||||
let fullSlug = prefix + '/' + slug + '/' + suffix.join('/')
|
const fullSlug = prefix + '/' + slug + '/' + suffix.join('/')
|
||||||
const from = `slug-props-${fullSlug}`
|
const from = `slug-props-${fullSlug}`
|
||||||
const props = await getGlobalData({ from, locale })
|
const props = await getGlobalData({ from, locale })
|
||||||
if (siteConfig('PSEUDO_STATIC', BLOG.PSEUDO_STATIC, props.NOTION_CONFIG)) {
|
|
||||||
if (!fullSlug.endsWith('.html')) {
|
|
||||||
fullSlug += '.html'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 在列表内查找文章
|
// 在列表内查找文章
|
||||||
props.post = props?.allPages?.find(p => {
|
props.post = props?.allPages?.find(p => {
|
||||||
return (
|
return (
|
||||||
p.type.indexOf('Menu') < 0 &&
|
p.type.indexOf('Menu') < 0 &&
|
||||||
(p.slug === fullSlug || p.id === idToUuid(fullSlug))
|
(p.slug === slug || p.slug === fullSlug || p.id === idToUuid(fullSlug))
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -132,16 +127,4 @@ export async function getStaticProps({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSlug(row) {
|
|
||||||
let slug = row.slug
|
|
||||||
if (slug.startsWith('/')) {
|
|
||||||
slug = slug.substring(1)
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
(slug.match(/\//g) || []).length >= 2 &&
|
|
||||||
row.type.indexOf('Menu') < 0 &&
|
|
||||||
!checkContainHttp(slug)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default PrefixSlug
|
export default PrefixSlug
|
||||||
|
|||||||
@@ -2,9 +2,13 @@ import BLOG from '@/blog.config'
|
|||||||
import { siteConfig } from '@/lib/config'
|
import { siteConfig } from '@/lib/config'
|
||||||
import { getGlobalData, getPost, getPostBlocks } from '@/lib/db/getSiteData'
|
import { getGlobalData, getPost, getPostBlocks } from '@/lib/db/getSiteData'
|
||||||
import { uploadDataToAlgolia } from '@/lib/plugins/algolia'
|
import { uploadDataToAlgolia } from '@/lib/plugins/algolia'
|
||||||
import { checkContainHttp } from '@/lib/utils'
|
import {
|
||||||
|
checkSlugHasNoSlash,
|
||||||
|
checkSlugHasOneSlash,
|
||||||
|
getRecommendPost
|
||||||
|
} from '@/lib/utils/post'
|
||||||
import { idToUuid } from 'notion-utils'
|
import { idToUuid } from 'notion-utils'
|
||||||
import Slug, { getRecommendPost } from '..'
|
import Slug from '..'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据notion的slug访问页面
|
* 根据notion的slug访问页面
|
||||||
@@ -26,12 +30,26 @@ export async function getStaticPaths() {
|
|||||||
|
|
||||||
const from = 'slug-paths'
|
const from = 'slug-paths'
|
||||||
const { allPages } = await getGlobalData({ from })
|
const { allPages } = await getGlobalData({ from })
|
||||||
|
|
||||||
// 根据slug中的 / 分割成prefix和slug两个字段 ; 例如 article/test
|
// 根据slug中的 / 分割成prefix和slug两个字段 ; 例如 article/test
|
||||||
|
// 最终用户可以通过 [domain]/[prefix]/[slug] 路径访问,即这里的 [domain]/article/test
|
||||||
const paths = allPages
|
const paths = allPages
|
||||||
?.filter(row => checkSlug(row))
|
?.filter(row => checkSlugHasOneSlash(row))
|
||||||
.map(row => ({
|
.map(row => ({
|
||||||
params: { prefix: row.slug.split('/')[0], slug: row.slug.split('/')[1] }
|
params: { prefix: row.slug.split('/')[0], slug: row.slug.split('/')[1] }
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// 增加一种访问路径 允许通过 [category]/[slug] 访问文章
|
||||||
|
// 例如文章slug 是 test ,然后文章的分类category是 production
|
||||||
|
// 则除了 [domain]/[slug] 以外,还支持分类名访问: [domain]/[category]/[slug]
|
||||||
|
console.log(
|
||||||
|
allPages
|
||||||
|
?.filter(row => checkSlugHasNoSlash(row) && row.category)
|
||||||
|
.map(row => ({
|
||||||
|
params: { prefix: row.category, slug: row.slug }
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
paths: paths,
|
paths: paths,
|
||||||
fallback: true
|
fallback: true
|
||||||
@@ -39,20 +57,15 @@ export async function getStaticPaths() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getStaticProps({ params: { prefix, slug }, locale }) {
|
export async function getStaticProps({ params: { prefix, slug }, locale }) {
|
||||||
let fullSlug = prefix + '/' + slug
|
const fullSlug = prefix + '/' + slug
|
||||||
const from = `slug-props-${fullSlug}`
|
const from = `slug-props-${fullSlug}`
|
||||||
const props = await getGlobalData({ from, locale })
|
const props = await getGlobalData({ from, locale })
|
||||||
|
|
||||||
if (siteConfig('PSEUDO_STATIC', BLOG.PSEUDO_STATIC, props.NOTION_CONFIG)) {
|
|
||||||
if (!fullSlug.endsWith('.html')) {
|
|
||||||
fullSlug += '.html'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 在列表内查找文章
|
// 在列表内查找文章
|
||||||
props.post = props?.allPages?.find(p => {
|
props.post = props?.allPages?.find(p => {
|
||||||
return (
|
return (
|
||||||
p.type.indexOf('Menu') < 0 &&
|
p.type.indexOf('Menu') < 0 &&
|
||||||
(p.slug === fullSlug || p.id === idToUuid(fullSlug))
|
(p.slug === slug || p.slug === fullSlug || p.id === idToUuid(fullSlug))
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -116,15 +129,5 @@ export async function getStaticProps({ params: { prefix, slug }, locale }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function checkSlug(row) {
|
|
||||||
let slug = row.slug
|
|
||||||
if (slug.startsWith('/')) {
|
|
||||||
slug = slug.substring(1)
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
(slug.match(/\//g) || []).length === 1 &&
|
|
||||||
!checkContainHttp(slug) &&
|
|
||||||
row.type.indexOf('Menu') < 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default PrefixSlug
|
export default PrefixSlug
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { siteConfig } from '@/lib/config'
|
|||||||
import { getGlobalData, getPost, getPostBlocks } from '@/lib/db/getSiteData'
|
import { getGlobalData, getPost, getPostBlocks } from '@/lib/db/getSiteData'
|
||||||
import { getPageTableOfContents } from '@/lib/notion/getPageTableOfContents'
|
import { getPageTableOfContents } from '@/lib/notion/getPageTableOfContents'
|
||||||
import { uploadDataToAlgolia } from '@/lib/plugins/algolia'
|
import { uploadDataToAlgolia } from '@/lib/plugins/algolia'
|
||||||
import { checkContainHttp } from '@/lib/utils'
|
import { checkSlugHasNoSlash, getRecommendPost } from '@/lib/utils/post'
|
||||||
import { getLayoutByTheme } from '@/themes/theme'
|
import { getLayoutByTheme } from '@/themes/theme'
|
||||||
import md5 from 'js-md5'
|
import md5 from 'js-md5'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
@@ -71,7 +71,7 @@ export async function getStaticPaths() {
|
|||||||
const from = 'slug-paths'
|
const from = 'slug-paths'
|
||||||
const { allPages } = await getGlobalData({ from })
|
const { allPages } = await getGlobalData({ from })
|
||||||
const paths = allPages
|
const paths = allPages
|
||||||
?.filter(row => checkSlug(row))
|
?.filter(row => checkSlugHasNoSlash(row))
|
||||||
.map(row => ({ params: { prefix: row.slug } }))
|
.map(row => ({ params: { prefix: row.slug } }))
|
||||||
return {
|
return {
|
||||||
paths: paths,
|
paths: paths,
|
||||||
@@ -158,51 +158,4 @@ export async function getStaticProps({ params: { prefix }, locale }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取文章的关联推荐文章列表,目前根据标签关联性筛选
|
|
||||||
* @param post
|
|
||||||
* @param {*} allPosts
|
|
||||||
* @param {*} count
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function getRecommendPost(post, allPosts, count = 6) {
|
|
||||||
let recommendPosts = []
|
|
||||||
const postIds = []
|
|
||||||
const currentTags = post?.tags || []
|
|
||||||
for (let i = 0; i < allPosts.length; i++) {
|
|
||||||
const p = allPosts[i]
|
|
||||||
if (p.id === post.id || p.type.indexOf('Post') < 0) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let j = 0; j < currentTags.length; j++) {
|
|
||||||
const t = currentTags[j]
|
|
||||||
if (postIds.indexOf(p.id) > -1) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if (p.tags && p.tags.indexOf(t) > -1) {
|
|
||||||
recommendPosts.push(p)
|
|
||||||
postIds.push(p.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recommendPosts.length > count) {
|
|
||||||
recommendPosts = recommendPosts.slice(0, count)
|
|
||||||
}
|
|
||||||
return recommendPosts
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkSlug(row) {
|
|
||||||
let slug = row.slug
|
|
||||||
if (slug.startsWith('/')) {
|
|
||||||
slug = slug.substring(1)
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
(slug.match(/\//g) || []).length === 0 &&
|
|
||||||
!checkContainHttp(slug) &&
|
|
||||||
row.type.indexOf('Menu') < 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Slug
|
export default Slug
|
||||||
|
|||||||
Reference in New Issue
Block a user