Skip to content

Commit 9584386

Browse files
committed
2 parents e89facf + 3e6cee1 commit 9584386

File tree

12 files changed

+201
-122
lines changed

12 files changed

+201
-122
lines changed

components/NotionPage.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const NotionPage = ({ post, className }) => {
3131
// 页面首次打开时执行的勾子
3232
useEffect(() => {
3333
// 检测当前的url并自动滚动到对应目标
34-
autoScrollToTarget()
34+
autoScrollToHash()
3535
}, [])
3636

3737
// 页面文章发生变化时会执行的勾子
@@ -144,9 +144,9 @@ const processGalleryImg = zoom => {
144144
}
145145

146146
/**
147-
* 根据url参数自动滚动到指定区域
147+
* 根据url参数自动滚动到锚位置
148148
*/
149-
const autoScrollToTarget = () => {
149+
const autoScrollToHash = () => {
150150
setTimeout(() => {
151151
// 跳转到指定标题
152152
const needToJumpToTitle = window.location.hash

lib/config.js

+44-26
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import BLOG from '@/blog.config'
44
import { useGlobal } from './global'
5-
import { deepClone } from './utils'
5+
import { deepClone, isUrl } from './utils'
66

77
/**
88
* 读取配置顺序
@@ -32,6 +32,8 @@ export const siteConfig = (key, defaultVal = null, extendConfig = {}) => {
3232
case 'POST_LIST_STYLE':
3333
case 'POST_LIST_PREVIEW':
3434
case 'POST_URL_PREFIX_MAPPING_CATEGORY':
35+
case 'IS_TAG_COLOR_DISTINGUISHED':
36+
case 'TAG_SORT_BY_COUNT':
3537
return convertVal(extendConfig[key] || defaultVal || BLOG[key])
3638
default:
3739
}
@@ -89,46 +91,62 @@ export const siteConfig = (key, defaultVal = null, extendConfig = {}) => {
8991
return defaultVal
9092
}
9193

92-
// 从Notion_CONFIG读取的配置通常都是字符串,适当转义
9394
return convertVal(val)
9495
}
9596

9697
/**
97-
* 配置默认都是string类型;
98-
* 识别配置的值是否数字、布尔、[]数组,若是则转成对应类型
98+
* 从环境变量和NotionConfig读取的配置都是string类型;
99+
* 这里识别出配置的字符值若为否 数字、布尔、[]数组,{}对象,若是则转成对应类型
100+
* 使用JSON和eval两个函数
99101
* @param {*} val
100102
* @returns
101103
*/
102104
export const convertVal = val => {
103-
if (typeof val === 'string') {
104-
// 解析布尔
105-
if (val === 'true' || val === 'false') {
106-
return JSON.parse(val)
107-
}
105+
// 如果传入参数本身就是obj、数组、boolean 就无需处理
106+
if (typeof val !== 'string' || !val) {
107+
return val
108+
}
108109

109-
// 解析数字,parseInt将字符串转换为数字
110-
if (/^\d+$/.test(val)) {
111-
return parseInt(val)
112-
}
113-
// 转移 [] , {} 这种json串为json对象
114-
try {
115-
const parsedJson = JSON.parse(val)
116-
// 检查解析后的结果是否是对象或数组
117-
if (typeof parsedJson === 'object' && parsedJson !== null) {
118-
return parsedJson
119-
}
120-
} catch (error) {
121-
// JSON 解析失败,返回原始字符串值
122-
return val
123-
}
110+
// 解析数字,parseInt将字符串转换为数字
111+
if (/^\d+$/.test(val)) {
112+
return parseInt(val)
124113
}
125114

126-
try {
115+
// 检测是否url
116+
if (isUrl(val)) {
117+
return val
118+
}
119+
// 检测是否url
120+
if (val === 'true' || val === 'false') {
127121
return JSON.parse(val)
122+
}
123+
124+
// 配置值前可能有污染的空格
125+
if (!val.indexOf('[') > 0 || val.indexOf('{')) {
126+
return val
127+
}
128+
129+
// 转换 [] , {} , true/false 这类字符串为对象
130+
try {
131+
// 尝试解析json
132+
const parsedJson = JSON.parse(val)
133+
if (parsedJson !== null) {
134+
return parsedJson
135+
}
128136
} catch (error) {
129-
// 如果值是一个字符串但不是有效的 JSON 格式,直接返回字符串
137+
// try {
138+
// // 尝试解析对象,对象解析能力不如上一步的json
139+
// const evalObj = eval('(' + val + ')')
140+
// if (evalObj !== null) {
141+
// return evalObj
142+
// }
143+
// } catch (error) {
144+
// // Ojbject 解析失败,返回原始字符串值
145+
// return val
146+
// }
130147
return val
131148
}
149+
return val
132150
}
133151

134152
/**

lib/notion/convertInnerUrl.js

+20-14
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,15 @@ import { checkStrIsNotionId, getLastPartOfUrl, isBrowser } from '../utils'
88
*/
99
export const convertInnerUrl = allPages => {
1010
if (isBrowser) {
11+
const allAnchorTags = document
12+
?.getElementById('notion-article')
13+
?.getElementsByTagName('a')
14+
15+
if (!allAnchorTags) {
16+
return
17+
}
1118
const currentURL = window.location.origin + window.location.pathname
12-
const allAnchorTags = document.getElementsByTagName('a') // 或者使用 document.querySelectorAll('a') 获取 NodeList
19+
// url替换成slug
1320
for (const anchorTag of allAnchorTags) {
1421
// 检查url
1522
if (anchorTag?.href) {
@@ -24,20 +31,19 @@ export const convertInnerUrl = allPages => {
2431
}
2532
}
2633
}
34+
}
2735

28-
for (const anchorTag of allAnchorTags) {
29-
if (anchorTag?.target === '_blank') {
30-
const hrefWithoutQueryHash = anchorTag.href
31-
.split('?')[0]
32-
.split('#')[0]
33-
const hrefWithRelativeHash =
34-
currentURL.split('#')[0] || '' + anchorTag.href.split('#')[1] || ''
35-
if (
36-
currentURL === hrefWithoutQueryHash ||
37-
currentURL === hrefWithRelativeHash
38-
) {
39-
anchorTag.target = '_self'
40-
}
36+
// 链接在当前页面打开
37+
for (const anchorTag of allAnchorTags) {
38+
if (anchorTag?.target === '_blank') {
39+
const hrefWithoutQueryHash = anchorTag.href.split('?')[0].split('#')[0]
40+
const hrefWithRelativeHash =
41+
currentURL.split('#')[0] || '' + anchorTag.href.split('#')[1] || ''
42+
if (
43+
currentURL === hrefWithoutQueryHash ||
44+
currentURL === hrefWithRelativeHash
45+
) {
46+
anchorTag.target = '_self'
4147
}
4248
}
4349
}

lib/notion/getPageProperties.js

+16-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import formatDate from '../utils/formatDate'
66
import md5 from 'js-md5'
77
import { siteConfig } from '../config'
88
import {
9-
checkContainHttp,
9+
checkStartWithHttp,
1010
convertUrlStartWithOneSlash,
11+
getLastSegmentFromUrl,
1112
sliceUrlFromHttp
1213
} from '../utils'
14+
import { extractLangPrefix } from '../utils/pageId'
1315
import { mapImgUrl } from './mapImage'
1416

1517
/**
@@ -197,7 +199,7 @@ export function adjustPageProperties(properties, NOTION_CONFIG) {
197199
}
198200

199201
// 检查处理外链
200-
properties.href = checkContainHttp(properties?.href)
202+
properties.href = checkStartWithHttp(properties?.href)
201203
? sliceUrlFromHttp(properties?.href)
202204
: convertUrlStartWithOneSlash(properties?.href)
203205

@@ -208,6 +210,18 @@ export function adjustPageProperties(properties, NOTION_CONFIG) {
208210
properties.target = '_self'
209211
}
210212

213+
// 如果跳转链接是多语言,则在新窗口打开
214+
if (BLOG.NOTION_PAGE_ID.indexOf(',') > 0) {
215+
const siteIds = BLOG.NOTION_PAGE_ID.split(',')
216+
for (let index = 0; index < siteIds.length; index++) {
217+
const siteId = siteIds[index]
218+
const prefix = extractLangPrefix(siteId)
219+
if (getLastSegmentFromUrl(properties.href) === prefix) {
220+
properties.target = '_blank'
221+
}
222+
}
223+
}
224+
211225
// 密码字段md5
212226
properties.password = properties.password
213227
? md5(properties.slug + properties.password)

lib/utils/index.js

+30-1
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,21 @@ export function convertUrlStartWithOneSlash(str) {
8181
return str
8282
}
8383

84+
/**
85+
* 是否是一个相对或绝对路径的ur类
86+
* @param {*} str
87+
* @returns
88+
*/
89+
export function isUrl(str) {
90+
if (!str) {
91+
return false
92+
}
93+
94+
return str?.indexOf('/') === 0 || checkStartWithHttp(str)
95+
}
96+
8497
// 检查是否外链
85-
export function checkContainHttp(str) {
98+
export function checkStartWithHttp(str) {
8699
// 检查字符串是否包含http
87100
if (str?.includes('http:') || str?.includes('https:')) {
88101
// 如果包含,找到http的位置
@@ -354,3 +367,19 @@ export const scanAndConvertToLinks = node => {
354367
}
355368
}
356369
}
370+
371+
/**
372+
* 获取url最后一个斜杆后面的内容
373+
* @param {*} url
374+
* @returns
375+
*/
376+
export function getLastSegmentFromUrl(url) {
377+
if (!url) {
378+
return ''
379+
}
380+
// 去掉 URL 中的查询参数部分
381+
const trimmedUrl = url.split('?')[0]
382+
// 获取最后一个斜杠后面的内容
383+
const segments = trimmedUrl.split('/')
384+
return segments[segments.length - 1]
385+
}

lib/utils/post.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* 文章相关工具
33
*/
4-
import { checkContainHttp } from '.'
4+
import { checkStartWithHttp } from '.'
55

66
/**
77
* 获取文章的关联推荐文章列表,目前根据标签关联性筛选
@@ -50,7 +50,7 @@ export function checkSlugHasNoSlash(row) {
5050
}
5151
return (
5252
(slug.match(/\//g) || []).length === 0 &&
53-
!checkContainHttp(slug) &&
53+
!checkStartWithHttp(slug) &&
5454
row.type.indexOf('Menu') < 0
5555
)
5656
}
@@ -67,7 +67,7 @@ export function checkSlugHasOneSlash(row) {
6767
}
6868
return (
6969
(slug.match(/\//g) || []).length === 1 &&
70-
!checkContainHttp(slug) &&
70+
!checkStartWithHttp(slug) &&
7171
row.type.indexOf('Menu') < 0
7272
)
7373
}
@@ -85,6 +85,6 @@ export function checkSlugHasMorThanTwoSlash(row) {
8585
return (
8686
(slug.match(/\//g) || []).length >= 2 &&
8787
row.type.indexOf('Menu') < 0 &&
88-
!checkContainHttp(slug)
88+
!checkStartWithHttp(slug)
8989
)
9090
}

themes/heo/components/Header.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,9 @@ const Header = props => {
144144
${fixedNav ? 'fixed' : 'relative bg-transparent'}
145145
${textWhite ? 'text-white ' : 'text-black dark:text-white'}
146146
${navBgWhite ? 'bg-white dark:bg-[#18171d] shadow' : 'bg-transparent'}`}>
147-
<div className='flex h-full mx-auto justify-between items-center max-w-[86rem] px-8'>
147+
<div className='flex h-full mx-auto justify-between items-center max-w-[86rem] px-6'>
148148
{/* 左侧logo */}
149-
<div className='flex'>
150-
<Logo {...props} />
151-
</div>
149+
<Logo {...props} />
152150

153151
{/* 中间菜单 */}
154152
<div

themes/heo/components/Hero.js

+13-6
Original file line numberDiff line numberDiff line change
@@ -162,24 +162,31 @@ function TagsGroupBar() {
162162
* @returns
163163
*/
164164
function GroupMenu() {
165+
const url_1 = siteConfig('HEO_HERO_CATEGORY_1', {}, CONFIG)?.url || ''
166+
const title_1 = siteConfig('HEO_HERO_CATEGORY_1', {}, CONFIG)?.title || ''
167+
const url_2 = siteConfig('HEO_HERO_CATEGORY_2', {}, CONFIG)?.url || ''
168+
const title_2 = siteConfig('HEO_HERO_CATEGORY_2', {}, CONFIG)?.title || ''
169+
const url_3 = siteConfig('HEO_HERO_CATEGORY_3', {}, CONFIG)?.url || ''
170+
const title_3 = siteConfig('HEO_HERO_CATEGORY_3', {}, CONFIG)?.title || ''
171+
165172
return (
166173
<div className='h-[165px] select-none xl:h-20 flex flex-col justify-between xl:space-y-0 xl:flex-row w-28 lg:w-48 xl:w-full xl:flex-nowrap xl:space-x-3'>
167174
<Link
168-
href={siteConfig('HEO_HERO_CATEGORY_1', null, CONFIG)?.url}
175+
href={url_1}
169176
className='group relative overflow-hidden bg-gradient-to-r from-blue-500 to-blue-400 flex h-20 justify-start items-center text-white rounded-xl xl:hover:w-1/2 xl:w-1/3 transition-all duration-500 ease-in'>
170177
<div className='font-bold lg:text-lg pl-5 relative -mt-2'>
171-
{siteConfig('HEO_HERO_CATEGORY_1', null, CONFIG)?.title}
178+
{title_1}
172179
<span className='absolute -bottom-0.5 left-5 w-5 h-0.5 bg-white rounded-full'></span>
173180
</div>
174181
<div className='hidden lg:block absolute right-6 duration-700 ease-in-out transition-all scale-[2] translate-y-6 rotate-12 opacity-20 group-hover:opacity-80 group-hover:scale-100 group-hover:translate-y-0 group-hover:rotate-0'>
175182
<i className='fa-solid fa-star text-4xl'></i>
176183
</div>
177184
</Link>
178185
<Link
179-
href={siteConfig('HEO_HERO_CATEGORY_2', null, CONFIG)?.url}
186+
href={url_2}
180187
className='group relative overflow-hidden bg-gradient-to-r from-red-500 to-yellow-500 flex h-20 justify-start items-center text-white rounded-xl xl:hover:w-1/2 xl:w-1/3 transition-all duration-500 ease-in'>
181188
<div className='font-bold lg:text-lg pl-5 relative -mt-2'>
182-
{siteConfig('HEO_HERO_CATEGORY_2', null, CONFIG)?.title}
189+
{title_2}
183190
<span className='absolute -bottom-0.5 left-5 w-5 h-0.5 bg-white rounded-full'></span>
184191
</div>
185192
<div className='hidden lg:block absolute right-6 duration-700 ease-in-out transition-all scale-[2] translate-y-6 rotate-12 opacity-20 group-hover:opacity-80 group-hover:scale-100 group-hover:translate-y-0 group-hover:rotate-0'>
@@ -188,10 +195,10 @@ function GroupMenu() {
188195
</Link>
189196
{/* 第三个标签在小屏上不显示 */}
190197
<Link
191-
href={siteConfig('HEO_HERO_CATEGORY_3', null, CONFIG)?.url}
198+
href={url_3}
192199
className='group relative overflow-hidden bg-gradient-to-r from-teal-300 to-cyan-300 hidden h-20 xl:flex justify-start items-center text-white rounded-xl xl:hover:w-1/2 xl:w-1/3 transition-all duration-500 ease-in'>
193200
<div className='font-bold text-lg pl-5 relative -mt-2'>
194-
{siteConfig('HEO_HERO_CATEGORY_3', null, CONFIG)?.title}
201+
{title_3}
195202
<span className='absolute -bottom-0.5 left-5 w-5 h-0.5 bg-white rounded-full'></span>
196203
</div>
197204
<div className='absolute right-6 duration-700 ease-in-out transition-all scale-[2] translate-y-6 rotate-12 opacity-20 group-hover:opacity-80 group-hover:scale-100 group-hover:translate-y-0 group-hover:rotate-0'>

0 commit comments

Comments
 (0)