From a5bab2240974e6f48664da1b9d222c4dbb4a805f Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Sun, 12 May 2024 17:39:47 +0800 Subject: [PATCH 1/6] =?UTF-8?q?url=E5=89=8D=E7=BC=80=20%category%=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/notion/getPageProperties.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/notion/getPageProperties.js b/lib/notion/getPageProperties.js index 83982e4e..f3a20ea2 100644 --- a/lib/notion/getPageProperties.js +++ b/lib/notion/getPageProperties.js @@ -224,6 +224,8 @@ function generateCustomizeSlug(postProperties, NOTION_CONFIG) { NOTION_CONFIG ).split('/') + const POST_URL_PREFIX_MAPPING_CATEGORY = siteConfig('POST_URL_PREFIX_MAPPING_CATEGORY',{},NOTION_CONFIG) + allSlugPatterns.forEach((pattern, idx) => { if (pattern === '%year%' && postProperties?.publishDay) { const formatPostCreatedDate = new Date(postProperties?.publishDay) @@ -240,7 +242,12 @@ function generateCustomizeSlug(postProperties, NOTION_CONFIG) { } else if (pattern === '%slug%') { fullPrefix += postProperties.slug ?? postProperties.id } else if (pattern === '%category%' && postProperties?.category) { - fullPrefix += postProperties.category + let categoryPrefix = postProperties.category + // 允许映射分类名,通常用来将中文分类映射成英文,美化url. + if(POST_URL_PREFIX_MAPPING_CATEGORY[postProperties?.category]){ + categoryPrefix = POST_URL_PREFIX_MAPPING_CATEGORY[postProperties?.category] + } + fullPrefix += categoryPrefix } else if (!pattern.includes('%')) { fullPrefix += pattern } else { From 2bff6993fff35eabfb6c606c1cc95a742676b7d4 Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Sun, 12 May 2024 17:44:12 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E5=86=85=E9=93=BE=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/NotionPage.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/components/NotionPage.js b/components/NotionPage.js index 1d1d9d0d..4c422774 100644 --- a/components/NotionPage.js +++ b/components/NotionPage.js @@ -47,7 +47,7 @@ const NotionPage = ({ post, className }) => { processDisableDatabaseUrl() } - // 若url是本站域名,则之间在当前窗口打开、不开新窗口 + // 处理页内的url processPageUrl() /** @@ -147,14 +147,20 @@ const processGalleryImg = zoom => { } /** - * 处理页面内连接跳转 - * 如果链接就是当网站,则不打开新窗口访问 + * 处理页面内连接跳转: + * 1. 若是本站域名,则在当前窗口打开、不开新窗口 + * 2. 若是Notion笔记中的内链,尝试转换成博客中现有的文章地址 */ const processPageUrl = () => { if (isBrowser) { const currentURL = window.location.origin + window.location.pathname const allAnchorTags = document.getElementsByTagName('a') // 或者使用 document.querySelectorAll('a') 获取 NodeList for (const anchorTag of allAnchorTags) { + // 检查url + if (anchorTag.href) { + // 如果是notion页面间的内链,尝试匹配成博客的文章链接 + } + if (anchorTag?.target === '_blank') { const hrefWithoutQueryHash = anchorTag.href.split('?')[0].split('#')[0] const hrefWithRelativeHash = From c337c063be279f5348a3d49fb11389f771ebe945 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 13 May 2024 11:36:53 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81=EF=BC=9A=20url=20=E5=89=8D=E7=BC=80=20%categ?= =?UTF-8?q?ory%=E4=B8=AD=E6=96=87=E5=88=86=E7=B1=BB=E5=90=8D=E6=98=A0?= =?UTF-8?q?=E5=B0=84=E6=88=90=E8=8B=B1=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/notion/getPageProperties.js | 21 +++++++++++++++------ lib/utils/index.js | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/notion/getPageProperties.js b/lib/notion/getPageProperties.js index f3a20ea2..39ebb97d 100644 --- a/lib/notion/getPageProperties.js +++ b/lib/notion/getPageProperties.js @@ -5,7 +5,11 @@ import formatDate from '../utils/formatDate' // import { createHash } from 'crypto' import md5 from 'js-md5' import { siteConfig } from '../config' -import { checkContainHttp, sliceUrlFromHttp } from '../utils' +import { + checkContainHttp, + convertUrlStartWithOneSlash, + sliceUrlFromHttp +} from '../utils' import { mapImgUrl } from './mapImage' /** @@ -191,10 +195,10 @@ export function adjustPageProperties(properties, NOTION_CONFIG) { } } - // 最终检查超链接 + // 检查处理外链 properties.href = checkContainHttp(properties?.href) ? sliceUrlFromHttp(properties?.href) - : `/${properties.href}` + : convertUrlStartWithOneSlash(properties?.href) // 设置链接在页内或新页面打开 if (properties.href?.indexOf('http') === 0) { @@ -224,7 +228,11 @@ function generateCustomizeSlug(postProperties, NOTION_CONFIG) { NOTION_CONFIG ).split('/') - const POST_URL_PREFIX_MAPPING_CATEGORY = siteConfig('POST_URL_PREFIX_MAPPING_CATEGORY',{},NOTION_CONFIG) + const POST_URL_PREFIX_MAPPING_CATEGORY = siteConfig( + 'POST_URL_PREFIX_MAPPING_CATEGORY', + {}, + NOTION_CONFIG + ) allSlugPatterns.forEach((pattern, idx) => { if (pattern === '%year%' && postProperties?.publishDay) { @@ -244,8 +252,9 @@ function generateCustomizeSlug(postProperties, NOTION_CONFIG) { } else if (pattern === '%category%' && postProperties?.category) { let categoryPrefix = postProperties.category // 允许映射分类名,通常用来将中文分类映射成英文,美化url. - if(POST_URL_PREFIX_MAPPING_CATEGORY[postProperties?.category]){ - categoryPrefix = POST_URL_PREFIX_MAPPING_CATEGORY[postProperties?.category] + if (POST_URL_PREFIX_MAPPING_CATEGORY[postProperties?.category]) { + categoryPrefix = + POST_URL_PREFIX_MAPPING_CATEGORY[postProperties?.category] } fullPrefix += categoryPrefix } else if (!pattern.includes('%')) { diff --git a/lib/utils/index.js b/lib/utils/index.js index b0652494..b3e5b2da 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -61,6 +61,26 @@ export function sliceUrlFromHttp(str) { } } +/** + * 将相对路径的url test 转为绝对路径 /test + * 判断url如果不是以 /开头,则拼接一个 / + * 同时如果开头有重复的多个 // ,则只保留一个 + * @param {*} str + */ +export function convertUrlStartWithOneSlash(str) { + if (!str) { + return '#' + } + // 判断url是否以 / 开头 + if (!str.startsWith('/')) { + // 如果不是,则在前面拼接一个 / + str = '/' + str + } + // 移除开头的多个连续斜杠,只保留一个 + str = str.replace(/\/+/g, '/') + return str +} + // 检查是否外链 export function checkContainHttp(str) { // 检查字符串是否包含http From 617cf1db4b44a41ae17ed4abf2acdf386af0307f Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 13 May 2024 11:39:01 +0800 Subject: [PATCH 4/6] v4.5.2 --- .env.local | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.local b/.env.local index 905e8d94..cd9d8216 100644 --- a/.env.local +++ b/.env.local @@ -1,5 +1,5 @@ # 环境变量 @see https://www.nextjs.cn/docs/basic-features/environment-variables -NEXT_PUBLIC_VERSION=4.5.1 +NEXT_PUBLIC_VERSION=4.5.2 # 可在此添加环境变量,去掉最左边的(# )注释即可 diff --git a/package.json b/package.json index 768f8344..3d24cecd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "notion-next", - "version": "4.5.1", + "version": "4.5.2", "homepage": "https://github.com/tangly1024/NotionNext.git", "license": "MIT", "repository": { From b663d984bab89409f4a1e7a5bc4033432fa66884 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 13 May 2024 12:15:15 +0800 Subject: [PATCH 5/6] =?UTF-8?q?Notion=E5=86=85=E9=93=BE=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ExternalPlugins.js | 130 ++++++++++++++++++---------------- components/NotionPage.js | 33 --------- lib/notion/mapPageUrl.js | 40 +++++++++++ lib/utils/index.js | 29 ++++++++ 4 files changed, 138 insertions(+), 94 deletions(-) create mode 100644 lib/notion/mapPageUrl.js diff --git a/components/ExternalPlugins.js b/components/ExternalPlugins.js index cecfae0e..da0b0fb3 100644 --- a/components/ExternalPlugins.js +++ b/components/ExternalPlugins.js @@ -6,71 +6,12 @@ import TianLiGPT from './TianliGPT' import WebWhiz from './Webwhiz' import { CUSTOM_EXTERNAL_CSS, CUSTOM_EXTERNAL_JS } from '@/blog.config' +import { mapPageUrl } from '@/lib/notion/mapPageUrl' import { isBrowser, loadExternalResource } from '@/lib/utils' +import { useRouter } from 'next/router' import { useEffect } from 'react' import { initGoogleAdsense } from './GoogleAdsense' -const TwikooCommentCounter = dynamic( - () => import('@/components/TwikooCommentCounter'), - { ssr: false } -) -const DebugPanel = dynamic(() => import('@/components/DebugPanel'), { - ssr: false -}) -const ThemeSwitch = dynamic(() => import('@/components/ThemeSwitch'), { - ssr: false -}) -const Fireworks = dynamic(() => import('@/components/Fireworks'), { - ssr: false -}) -const MouseFollow = dynamic(() => import('@/components/MouseFollow'), { - ssr: false -}) -const Nest = dynamic(() => import('@/components/Nest'), { ssr: false }) -const FlutteringRibbon = dynamic( - () => import('@/components/FlutteringRibbon'), - { ssr: false } -) -const Ribbon = dynamic(() => import('@/components/Ribbon'), { ssr: false }) -const Sakura = dynamic(() => import('@/components/Sakura'), { ssr: false }) -const StarrySky = dynamic(() => import('@/components/StarrySky'), { - ssr: false -}) -const DifyChatbot = dynamic(() => import('@/components/DifyChatbot'), { - ssr: false -}) -const Analytics = dynamic( - () => - import('@vercel/analytics/react').then(async m => { - return m.Analytics - }), - { ssr: false } -) -const MusicPlayer = dynamic(() => import('@/components/Player'), { ssr: false }) -const Ackee = dynamic(() => import('@/components/Ackee'), { ssr: false }) -const Gtag = dynamic(() => import('@/components/Gtag'), { ssr: false }) -const Busuanzi = dynamic(() => import('@/components/Busuanzi'), { ssr: false }) -const Messenger = dynamic(() => import('@/components/FacebookMessenger'), { - ssr: false -}) -const VConsole = dynamic(() => import('@/components/VConsole'), { ssr: false }) -const CustomContextMenu = dynamic( - () => import('@/components/CustomContextMenu'), - { ssr: false } -) -const DisableCopy = dynamic(() => import('@/components/DisableCopy'), { - ssr: false -}) -const AdBlockDetect = dynamic(() => import('@/components/AdBlockDetect'), { - ssr: false -}) -const LoadingProgress = dynamic(() => import('@/components/LoadingProgress'), { - ssr: false -}) -const AosAnimation = dynamic(() => import('@/components/AOSAnimation'), { - ssr: false -}) - /** * 各种插件脚本 * @param {*} props @@ -155,6 +96,7 @@ const ExternalPlugin = props => { } } + const router = useRouter() useEffect(() => { // 异步渲染谷歌广告 if (ADSENSE_GOOGLE_ID) { @@ -163,6 +105,11 @@ const ExternalPlugin = props => { }, 1000) } + // 映射url + mapPageUrl(props?.allNavPages) + }, [router]) + + useEffect(() => { // 执行注入脚本 // eslint-disable-next-line no-eval eval(GLOBAL_JS) @@ -389,4 +336,65 @@ const ExternalPlugin = props => { ) } +const TwikooCommentCounter = dynamic( + () => import('@/components/TwikooCommentCounter'), + { ssr: false } +) +const DebugPanel = dynamic(() => import('@/components/DebugPanel'), { + ssr: false +}) +const ThemeSwitch = dynamic(() => import('@/components/ThemeSwitch'), { + ssr: false +}) +const Fireworks = dynamic(() => import('@/components/Fireworks'), { + ssr: false +}) +const MouseFollow = dynamic(() => import('@/components/MouseFollow'), { + ssr: false +}) +const Nest = dynamic(() => import('@/components/Nest'), { ssr: false }) +const FlutteringRibbon = dynamic( + () => import('@/components/FlutteringRibbon'), + { ssr: false } +) +const Ribbon = dynamic(() => import('@/components/Ribbon'), { ssr: false }) +const Sakura = dynamic(() => import('@/components/Sakura'), { ssr: false }) +const StarrySky = dynamic(() => import('@/components/StarrySky'), { + ssr: false +}) +const DifyChatbot = dynamic(() => import('@/components/DifyChatbot'), { + ssr: false +}) +const Analytics = dynamic( + () => + import('@vercel/analytics/react').then(async m => { + return m.Analytics + }), + { ssr: false } +) +const MusicPlayer = dynamic(() => import('@/components/Player'), { ssr: false }) +const Ackee = dynamic(() => import('@/components/Ackee'), { ssr: false }) +const Gtag = dynamic(() => import('@/components/Gtag'), { ssr: false }) +const Busuanzi = dynamic(() => import('@/components/Busuanzi'), { ssr: false }) +const Messenger = dynamic(() => import('@/components/FacebookMessenger'), { + ssr: false +}) +const VConsole = dynamic(() => import('@/components/VConsole'), { ssr: false }) +const CustomContextMenu = dynamic( + () => import('@/components/CustomContextMenu'), + { ssr: false } +) +const DisableCopy = dynamic(() => import('@/components/DisableCopy'), { + ssr: false +}) +const AdBlockDetect = dynamic(() => import('@/components/AdBlockDetect'), { + ssr: false +}) +const LoadingProgress = dynamic(() => import('@/components/LoadingProgress'), { + ssr: false +}) +const AosAnimation = dynamic(() => import('@/components/AOSAnimation'), { + ssr: false +}) + export default ExternalPlugin diff --git a/components/NotionPage.js b/components/NotionPage.js index 4c422774..f8e8e396 100644 --- a/components/NotionPage.js +++ b/components/NotionPage.js @@ -47,9 +47,6 @@ const NotionPage = ({ post, className }) => { processDisableDatabaseUrl() } - // 处理页内的url - processPageUrl() - /** * 放大查看图片时替换成高清图像 */ @@ -146,36 +143,6 @@ const processGalleryImg = zoom => { }, 800) } -/** - * 处理页面内连接跳转: - * 1. 若是本站域名,则在当前窗口打开、不开新窗口 - * 2. 若是Notion笔记中的内链,尝试转换成博客中现有的文章地址 - */ -const processPageUrl = () => { - if (isBrowser) { - const currentURL = window.location.origin + window.location.pathname - const allAnchorTags = document.getElementsByTagName('a') // 或者使用 document.querySelectorAll('a') 获取 NodeList - for (const anchorTag of allAnchorTags) { - // 检查url - if (anchorTag.href) { - // 如果是notion页面间的内链,尝试匹配成博客的文章链接 - } - - if (anchorTag?.target === '_blank') { - const hrefWithoutQueryHash = anchorTag.href.split('?')[0].split('#')[0] - const hrefWithRelativeHash = - currentURL.split('#')[0] + anchorTag.href.split('#')[1] - - if ( - currentURL === hrefWithoutQueryHash || - currentURL === hrefWithRelativeHash - ) { - anchorTag.target = '_self' - } - } - } - } -} /** * 根据url参数自动滚动到指定区域 */ diff --git a/lib/notion/mapPageUrl.js b/lib/notion/mapPageUrl.js new file mode 100644 index 00000000..8a7bc73c --- /dev/null +++ b/lib/notion/mapPageUrl.js @@ -0,0 +1,40 @@ +import { uuidToId } from 'notion-utils' +import { checkStrIsNotionId, getLastPartOfUrl, isBrowser } from '../utils' + +/** + * 处理页面内连接跳转: + * 1. 若是本站域名,则在当前窗口打开、不开新窗口 + * 2. 若是Notion笔记中的内链,尝试转换成博客中现有的文章地址 + */ +export const mapPageUrl = allPages => { + if (isBrowser) { + const currentURL = window.location.origin + window.location.pathname + const allAnchorTags = document.getElementsByTagName('a') // 或者使用 document.querySelectorAll('a') 获取 NodeList + for (const anchorTag of allAnchorTags) { + // 检查url + if (anchorTag.href) { + // 如果url是一个Notion_id,尝试匹配成博客的文章内链 + const slug = getLastPartOfUrl(anchorTag.href) + if (checkStrIsNotionId(slug)) { + const slugPage = allPages.find(page => uuidToId(page.id) === slug) + if (slugPage) { + anchorTag.href = slugPage.href + } + } + } + + if (anchorTag?.target === '_blank') { + const hrefWithoutQueryHash = anchorTag.href.split('?')[0].split('#')[0] + const hrefWithRelativeHash = + currentURL.split('#')[0] + anchorTag.href.split('#')[1] + + if ( + currentURL === hrefWithoutQueryHash || + currentURL === hrefWithRelativeHash + ) { + anchorTag.target = '_self' + } + } + } + } +} diff --git a/lib/utils/index.js b/lib/utils/index.js index b0652494..204430d8 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -73,6 +73,35 @@ export function checkContainHttp(str) { } } +// 检查一个字符串是否notionid : 32位,仅由数字英文构成 +export function checkStrIsNotionId(str) { + if (!str) { + return false + } + // 使用正则表达式进行匹配 + const regex = /^[a-zA-Z0-9]{32}$/ + return regex.test(str) +} + +// 截取url中最后一个 / 后面的内容 +export function getLastPartOfUrl(url) { + if (!url) { + return '' + } + // 找到最后一个斜杠的位置 + const lastSlashIndex = url.lastIndexOf('/') + + // 如果找不到斜杠,则返回整个字符串 + if (lastSlashIndex === -1) { + return url + } + + // 截取最后一个斜杠后面的内容 + const lastPart = url.substring(lastSlashIndex + 1) + + return lastPart +} + /** * 加载外部资源 * @param url 地址 例如 https://xx.com/xx.js From 622594a307013313ff605f8c94272b69d33f1793 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 13 May 2024 12:15:54 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E5=86=85=E9=93=BE=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/notion/mapPageUrl.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/notion/mapPageUrl.js b/lib/notion/mapPageUrl.js index 8a7bc73c..80fe70d8 100644 --- a/lib/notion/mapPageUrl.js +++ b/lib/notion/mapPageUrl.js @@ -12,13 +12,13 @@ export const mapPageUrl = allPages => { const allAnchorTags = document.getElementsByTagName('a') // 或者使用 document.querySelectorAll('a') 获取 NodeList for (const anchorTag of allAnchorTags) { // 检查url - if (anchorTag.href) { + if (anchorTag?.href) { // 如果url是一个Notion_id,尝试匹配成博客的文章内链 const slug = getLastPartOfUrl(anchorTag.href) if (checkStrIsNotionId(slug)) { - const slugPage = allPages.find(page => uuidToId(page.id) === slug) + const slugPage = allPages?.find(page => uuidToId(page.id) === slug) if (slugPage) { - anchorTag.href = slugPage.href + anchorTag.href = slugPage?.href } } }