由於整合了多個設定並更改了部分設定名稱,升級到 5.0 版本時,請重新設定 _config.yml 文件。

1. 新增 macstyle 設定,取消 mac / mac light 主題設定
2. 整合搜索相關設定
3. 修改程式碼區塊設定
4. 主頁文章新增多種版面配置
5. 新增說說頁面
6. 適配 hexo-blog-encrypt 加密插件
7. 改善手機端目錄的開啟效果
8. 新增平滑滾動功能
9. 支持以程式碼區塊方式撰寫 mermaid 圖表
10. 可自訂文章標題位置
11. 新增程式碼全螢幕按鈕
12. 友情連結頭像改為圓角設計
13. 優化程式碼,使用 hexo-util 的參數和 hexo 內建參數
14. 可自訂搜索框提示文字
15. 未設定選單時,不顯示側邊欄目錄和按鈕
16. 螢幕寬度超過 2000px 時,增加卡片高度
17. 根據語言設定調整字體:簡體中文使用雅黑,其他使用正黑體
18. 更新 plugins.yml
19. 全新的側邊欄界面設計
20. 新增 giscus 的 js 設定
21. 調整 utterances js 的設定位置
22. 新增 utterances option 設定
23. 修改 giscus 的主題設定
24. 多個界面元素改為圓角設計
25. 可選擇圓角或直角界面風格
26. 圖庫加載按鈕新增圖標
27. 改善標籤頁面的滑鼠懸停效果
28. 調整側邊欄的滑鼠懸停效果
29. 微調部分界面元素

1. 修復 Hexo 新版本下 Prism.js 無法正確高亮的問題
2. 修復文章標籤為空時可能出現的錯誤
3. 修正 mermaid 圖表可能出現的錯誤
4. 解決未設定選單時控制台報錯的問題
5. 修復 Algolia 搜索的每頁顯示數量設定無效的問題
6. 解決 Algolia 搜索結果出現滾動條的問題
7. 修正滾動條出現上下按鈕的問題
8. 修復圖庫遠程連結未加前綴的問題
9. 修正 label 標籤外掛右側多餘空格的問題
10. 解決 APlayer 報告內存洩漏的問題

1. 優化 PJAX 下的函數調用
2. 整體代碼優化
3. 提升兼容性
4. 改善 Lighthouse 評分
5. 在 PJAX 關閉時減少不必要的全局變量
6. 優化 Waline 的 import 兼容性
7. 改善頁面進入效果
8. 優化程式碼區塊工具列顯示邏輯
9. 改善不同螢幕寬度下文章標題位置的顯示
10. 優化標籤顏色生成算法,避免過暗或過亮
11. 調整 Artalk 和 Waline 在夜間模式下的字體顏色,與主題保持一致
12. 調整 Algolia 搜索加載動畫位置,避免換行
13. 優化 Algolia 搜索結果為空時的處理
14. 改善系列文章的滑鼠懸停效果
15. 優化 404 頁面代碼
16. 解決搜索和側邊欄開啟時窗口抖動的問題
17. 優化 tabs 標籤外掛的代碼和效能
18. 改善 tabs 中使用 gallery 標籤外掛時的圖片加載邏輯
19. 優化目錄滾動效果,使當前標題保持在中間
20. 調整螢幕寬度超過 1024px 時 gallerygroup 的顯示數量
This commit is contained in:
Jerry
2024-08-03 19:05:57 +08:00
Unverified
parent 0d52505331
commit 06f543ed96
123 changed files with 2226 additions and 1792 deletions

View File

@@ -1,12 +0,0 @@
- var top_img_404 = theme.error_404.background || theme.default_top_img
#body-wrap.error404
include ./header/index.pug
#error-wrap
.error-content
.error-img
img(src=url_for(top_img_404) alt='Page not found')
.error-info
h1.error_title= '404'
.error_subtitle= theme.error_404.subtitle || _p('error404')

View File

@@ -5,9 +5,9 @@ div
if theme.translate.enable
script(src=url_for(theme.asset.translate))
if theme.medium_zoom
if theme.lightbox === 'medium_zoom'
script(src=url_for(theme.asset.medium_zoom))
else if theme.fancybox
else if theme.lightbox === 'fancybox'
script(src=url_for(theme.asset.fancybox))
if theme.instantpage
@@ -38,7 +38,7 @@ div
!= partial("includes/third-party/prismjs", {}, { cache: true })
if theme.aside.enable && theme.newest_comments.enable
if theme.aside.enable && theme.aside.card_newest_comments.enable
if theme.pjax.enable
!= partial("includes/third-party/newest-comments/index", {}, { cache: true })
else if (!is_post() && page.aside !== false)

View File

@@ -45,7 +45,7 @@ link(rel='stylesheet', href=url_for(theme.asset.fontawesome))
if (theme.snackbar && theme.snackbar.enable)
link(rel='stylesheet', href=url_for(theme.asset.snackbar_css) media="print" onload="this.media='all'")
if theme.fancybox
if theme.lightbox === 'fancybox'
link(rel='stylesheet' href=url_for(theme.asset.fancybox_css) media="print" onload="this.media='all'")
!=fragment_cache('injectHeadJs', function(){return inject_head_js()})

View File

@@ -10,5 +10,7 @@ if theme.Open_Graph_meta.enable
-
!= open_graph(ogOption)
else
meta(name="description" content=page_description())
- const description = page.description || page.content || page.title || config.description
if description
meta(name="description" content=truncate(description, 150))

View File

@@ -1,28 +1,30 @@
-
let algolia = 'undefined';
let env = process.env;
if (theme.algolia_search.enable) {
let algolia = 'undefined'
if (theme.search.use === 'algolia_search') {
const { ALGOLIA_APP_ID, ALGOLIA_API_KEY, ALGOLIA_INDEX_NAME } = process.env
const { appId, applicationID, apiKey, indexName } = config.algolia
algolia = JSON.stringify({
appId: env.ALGOLIA_APP_ID || config.algolia.appId || config.algolia.applicationID,
apiKey: env.ALGOLIA_API_KEY || config.algolia.apiKey,
indexName: env.ALGOLIA_INDEX_NAME || config.algolia.indexName,
hits: theme.algolia_search.hits,
appId: ALGOLIA_APP_ID || appId || applicationID,
apiKey: ALGOLIA_API_KEY || apiKey,
indexName: ALGOLIA_INDEX_NAME || indexName,
hitsPerPage: theme.search.algolia_search.hitsPerPage,
// search languages
languages: {
input_placeholder: _p("search.algolia_search.input_placeholder"),
input_placeholder: theme.search.placeholder || _p("search.input_placeholder"),
hits_empty: _p("search.algolia_search.hits_empty"),
hits_stats: _p("search.algolia_search.hits_stats"),
}
})
}
let localSearch = 'undefined';
if (theme.local_search && theme.local_search.enable) {
let localSearch = 'undefined'
if (theme.search.use === 'local_search') {
const { CDN, preload, top_n_per_article, unescape } = theme.search.local_search
localSearch = JSON.stringify({
path: theme.local_search.CDN ? theme.local_search.CDN : config.root + config.search.path,
preload: theme.local_search.preload,
top_n_per_article: theme.local_search.top_n_per_article,
unescape: theme.local_search.unescape,
path: CDN || config.root + config.search.path,
preload,
top_n_per_article,
unescape,
languages: {
// search languages
hits_empty: _p("search.local_search.hits_empty"),
@@ -31,7 +33,7 @@
})
}
let translate = 'undefined';
let translate = 'undefined'
if (theme.translate && theme.translate.enable){
translate = JSON.stringify({
defaultEncoding: theme.translate.defaultEncoding,
@@ -41,7 +43,7 @@
})
}
let copyright = 'undefined';
let copyright = 'undefined'
if (theme.copy.enable && theme.copy.copyright.enable){
copyright = JSON.stringify({
limitCount: theme.copy.copyright.limit_count,
@@ -54,7 +56,7 @@
})
}
let Snackbar = 'undefined';
let Snackbar = 'undefined'
if (theme.snackbar && theme.snackbar.enable) {
Snackbar = JSON.stringify({
chs_to_cht: _p("Snackbar.chs_to_cht"),
@@ -67,7 +69,7 @@
})
}
let noticeOutdate = 'undefined';
let noticeOutdate = 'undefined'
if (theme.noticeOutdate && theme.noticeOutdate.enable) {
noticeOutdate = JSON.stringify({
limitDay: theme.noticeOutdate.limit_day,
@@ -77,17 +79,18 @@
})
}
let highlight = 'undefined';
let syntaxHighlighter = config.syntax_highlighter;
let highlightEnable = syntaxHighlighter ? ['highlight.js', 'prismjs'].includes(syntaxHighlighter) : (config.highlight.enable || config.prismjs.enable);
let highlight = 'undefined'
let syntaxHighlighter = config.syntax_highlighter
let highlightEnable = syntaxHighlighter ? ['highlight.js', 'prismjs'].includes(syntaxHighlighter) : (config.highlight.enable || config.prismjs.enable)
if (highlightEnable) {
const { copy, language, height_limit, fullpage, macStyle } = theme.code_blocks
highlight = JSON.stringify({
plugin: syntaxHighlighter ? syntaxHighlighter : config.highlight.enable ? 'highlight.js' : 'prismjs',
highlightCopy: theme.highlight_copy,
highlightLang: theme.highlight_lang,
highlightHeightLimit: theme.highlight_height_limit,
highlightFullpage: theme.highlight_fullpage,
highlightMacStyle: theme.highlight_theme_macStyle
highlightCopy: copy,
highlightLang: language,
highlightHeightLimit: height_limit,
highlightFullpage: fullpage,
highlightMacStyle: macStyle
})
}
@@ -108,7 +111,7 @@ script.
homepage: !{theme.post_meta.page.date_format === 'relative'},
post: !{theme.post_meta.post.date_format === 'relative'}
},
runtime: '!{theme.runtimeshow.enable ? _p("aside.card_webinfo.runtime.unit") : ""}',
runtime: '!{theme.aside.card_webinfo.runtime_date ? _p("aside.card_webinfo.runtime.unit") : ""}',
dateSuffix: {
just: '!{_p("date_suffix.just")}',
min: '!{_p("date_suffix.min")}',
@@ -117,7 +120,7 @@ script.
month: '!{_p("date_suffix.month")}'
},
copyright: !{copyright},
lightbox: '!{ theme.medium_zoom ? "mediumZoom" : (theme.fancybox ? "fancybox" : "null" )}',
lightbox: '!{ theme.lightbox || 'null' }',
Snackbar: !{Snackbar},
infinitegrid: {
js: '!{url_for(theme.asset.egjs_infinitegrid)}',

View File

@@ -2,20 +2,17 @@
const titleVal = pageTitle.replace(/'/ig,"\\'")
let isHighlightShrink
if (theme.highlight_shrink == 'none') isHighlightShrink = 'undefined'
else if (page.highlight_shrink === true || page.highlight_shrink === false) isHighlightShrink = page.highlight_shrink
else isHighlightShrink = theme.highlight_shrink
if (theme.code_blocks.shrink == 'none') isHighlightShrink = 'undefined'
else if (typeof page.highlight_shrink == 'boolean') isHighlightShrink = page.highlight_shrink
else isHighlightShrink = theme.code_blocks.shrink
var showToc = false
if (theme.aside.enable && page.aside !== false) {
let tocEnable = false
if (is_post()) {
if (theme.toc.post) tocEnable = true
} else if (is_page()) {
if (theme.toc.page) tocEnable = true
}
const pageToc = page.toc === true || page.toc === false ? page.toc : tocEnable
showToc = pageToc && (toc(page.content) !== '' || page.encrypt == true )
if (is_post() && theme.toc.post) tocEnable = true
else if (is_page() && theme.toc.page) tocEnable = true
const pageToc = typeof page.toc === 'boolean' ? page.toc : tocEnable
showToc = pageToc && (toc(page.content) !== '' || page.encrypt === true)
}
-

View File

@@ -4,7 +4,7 @@ if !theme.disable_top_img && page.top_img !== false
else if is_page()
- var top_img = page.top_img || theme.default_top_img
else if is_tag()
- var top_img = theme.tag_per_img && theme.tag_per_img[page.tag]
- var top_img = theme.tag_per_img && theme.tag_per_img[page.tag]
- top_img = top_img ? top_img : (theme.tag_img !== false ? theme.tag_img || theme.default_top_img : false)
else if is_category()
- var top_img = theme.category_per_img && theme.category_per_img[page.category]

View File

@@ -5,17 +5,18 @@ nav#nav
img.site-icon(src=url_for(theme.nav.logo) alt='Logo')
if theme.nav.display_title
span.site-name=config.title
#menus
if (theme.algolia_search.enable || theme.local_search.enable || theme.docsearch.enable)
if (theme.search.use)
#search-button
span.site-page.social-icon.search
i.fas.fa-search.fa-fw
span=' '+_p('search.title')
!=partial('includes/header/menu_item', {}, {cache: true})
if theme.menu
!=partial('includes/header/menu_item', {}, {cache: true})
#toggle-menu
span.site-page
i.fas.fa-bars.fa-fw
#toggle-menu
span.site-page
i.fas.fa-bars.fa-fw

View File

@@ -2,6 +2,7 @@
- page.aside = is_archive() ? theme.aside.display.archive: is_category() ? theme.aside.display.category : is_tag() ? theme.aside.display.tag : page.aside
- var hideAside = !theme.aside.enable || page.aside === false ? 'hide-aside' : ''
- var pageType = is_post() ? 'post' : 'page'
- pageType = page.type ? pageType + ' type-' + page.type : pageType
doctype html
html(lang=config.language data-theme=theme.display_mode class=htmlClassHideAside)
@@ -16,32 +17,28 @@ html(lang=config.language data-theme=theme.display_mode class=htmlClassHideAside
!=partial('includes/sidebar', {}, {cache: true})
if page.type !== '404'
#body-wrap(class=pageType)
include ./header/index.pug
#body-wrap(class=pageType)
include ./header/index.pug
main#content-inner.layout(class=hideAside)
if body
div!= body
else
block content
if theme.aside.enable && page.aside !== false
include widget/index.pug
- var footerBg = theme.footer_bg
if (footerBg)
if (footerBg === true)
- var footer_bg = bg_img
else
- var footer_bg = isImgOrUrl(theme.footer_bg) ? `background-image: url('${url_for(footerBg)}')` : `background: ${footerBg}`
main#content-inner.layout(class=hideAside)
if body
div!= body
else
- var footer_bg = ''
block content
if theme.aside.enable && page.aside !== false
include widget/index.pug
footer#footer(style=footer_bg)
!=partial('includes/footer', {}, {cache: true})
- var footerBg = theme.footer_img
if (footerBg)
if (footerBg === true)
- var footer_bg = bg_img
else
- var footer_bg = isImgOrUrl(theme.footer_bg) ? `background-image: url('${url_for(footerBg)}')` : `background: ${footerBg}`
else
- var footer_bg = ''
else
include ./404.pug
footer#footer(style=footer_bg)
!=partial('includes/footer', {}, {cache: true})
include ./rightside.pug
include ./additional-js.pug

View File

@@ -0,0 +1,125 @@
mixin indexPostUI()
- let indexLayout = theme.index_layout
- let masonryLayoutClass = (indexLayout === 6 || indexLayout === 7) ? 'masonry' : ''
#recent-posts.recent-posts.nc(class=masonryLayoutClass)
.recent-post-items
each article , index in page.posts.data
.recent-post-item
-
let link = article.link || article.path
let title = article.title || _p('no_title')
let leftOrRight = indexLayout === 3
? index%2 == 0 ? 'left' : 'right'
: indexLayout === 2 ? 'right' : ''
let post_cover = article.cover
let no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
-
if post_cover && theme.cover.index_enable
.post_cover(class=leftOrRight)
a(href=url_for(link) title=title)
if article.cover_type === 'img'
img.post-bg(src=url_for(post_cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
else
div.post-bg(style=`background: ${post_cover}`)
.recent-post-info(class=no_cover)
a.article-title(href=url_for(link) title=title)
if (is_home() && (article.top || article.sticky > 0))
i.fas.fa-thumbtack.sticky
= title
.article-meta-wrap
if (theme.post_meta.page.date_type)
span.post-meta-date
if (theme.post_meta.page.date_type === 'both')
i.far.fa-calendar-alt
span.article-meta-label=_p('post.created')
time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))=date(article.date, config.date_format)
span.article-meta-separator |
i.fas.fa-history
span.article-meta-label=_p('post.updated')
time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))=date(article.updated, config.date_format)
else
- let data_type_updated = theme.post_meta.page.date_type === 'updated'
- let date_type = data_type_updated ? 'updated' : 'date'
- let date_icon = data_type_updated ? 'fas fa-history' :'far fa-calendar-alt'
- let date_title = data_type_updated ? _p('post.updated') : _p('post.created')
i(class=date_icon)
span.article-meta-label=date_title
time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]))=date(article[date_type], config.date_format)
if (theme.post_meta.page.categories && article.categories.data.length > 0)
span.article-meta
span.article-meta-separator |
each item, index in article.categories.data
i.fas.fa-inbox
a(href=url_for(item.path)).article-meta__categories #[=item.name]
if (index < article.categories.data.length - 1)
i.fas.fa-angle-right.article-meta-link
if (theme.post_meta.page.tags && article.tags.length > 0)
span.article-meta.tags
span.article-meta-separator |
each item, index in article.tags.data
i.fas.fa-tag
a(href=url_for(item.path)).article-meta__tags #[=item.name]
if (index < article.tags.data.length - 1)
span.article-meta-link #[='•']
mixin countBlockInIndex
- needLoadCountJs = true
span.article-meta
span.article-meta-separator |
i.fas.fa-comments
if block
block
span.article-meta-label= ' ' + _p('card_post_count')
if theme.comments.card_post_count && theme.comments.use
case theme.comments.use[0]
when 'Disqus'
when 'Disqusjs'
+countBlockInIndex
a.disqus-count(href=full_url_for(link) + '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Valine'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.valine-comment-count(data-xid=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Waline'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.waline-comment-count(data-path=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Twikoo'
+countBlockInIndex
a.twikoo-count(href=url_for(link) + '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Facebook Comments'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.fb-comments-count(data-href=urlNoIndex(article.permalink))
when 'Remark42'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.remark42__counter(data-url=urlNoIndex(article.permalink))
i.fa-solid.fa-spinner.fa-spin
when 'Artalk'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.artalk-count(data-page-key=url_for(link))
i.fa-solid.fa-spinner.fa-spin
//- Display the article introduction on homepage
case theme.index_post_content.method
when false
- break
when 1
.content!= article.description
when 2
.content!= article.description || truncate(article.content, theme.index_post_content.length)
default
.content!= truncate(article.content, theme.index_post_content.length)
if theme.ad && theme.ad.index
if (index + 1) % 3 == 0
.recent-post-item.ads-wrap!=theme.ad.index
include ../pagination.pug

View File

@@ -1,129 +0,0 @@
mixin postUI(posts)
each article , index in page.posts.data
.recent-post-item
-
let link = article.link || article.path
let title = article.title || _p('no_title')
const position = theme.cover.position
let leftOrRight = position === 'both'
? index%2 == 0 ? 'left' : 'right'
: position === 'left' ? 'left' : 'right'
let post_cover = article.cover
let no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
-
if post_cover && theme.cover.index_enable
.post_cover(class=leftOrRight)
a(href=url_for(link) title=title)
if article.cover_type === 'img'
img.post-bg(src=url_for(post_cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
else
div.post-bg(style=`background: ${post_cover}`)
.recent-post-info(class=no_cover)
a.article-title(href=url_for(link) title=title)
if (is_home() && (article.top || article.sticky > 0))
i.fas.fa-thumbtack.sticky
= title
.article-meta-wrap
if (theme.post_meta.page.date_type)
span.post-meta-date
if (theme.post_meta.page.date_type === 'both')
i.far.fa-calendar-alt
span.article-meta-label=_p('post.created')
time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))=date(article.date, config.date_format)
span.article-meta-separator |
i.fas.fa-history
span.article-meta-label=_p('post.updated')
time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))=date(article.updated, config.date_format)
else
- let data_type_updated = theme.post_meta.page.date_type === 'updated'
- let date_type = data_type_updated ? 'updated' : 'date'
- let date_icon = data_type_updated ? 'fas fa-history' :'far fa-calendar-alt'
- let date_title = data_type_updated ? _p('post.updated') : _p('post.created')
i(class=date_icon)
span.article-meta-label=date_title
time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]))=date(article[date_type], config.date_format)
if (theme.post_meta.page.categories && article.categories.data.length > 0)
span.article-meta
span.article-meta-separator |
each item, index in article.categories.data
i.fas.fa-inbox
a(href=url_for(item.path)).article-meta__categories #[=item.name]
if (index < article.categories.data.length - 1)
i.fas.fa-angle-right.article-meta-link
if (theme.post_meta.page.tags && article.tags.data.length > 0)
span.article-meta.tags
span.article-meta-separator |
each item, index in article.tags.data
i.fas.fa-tag
a(href=url_for(item.path)).article-meta__tags #[=item.name]
if (index < article.tags.data.length - 1)
span.article-meta-link #[='•']
mixin countBlockInIndex
- needLoadCountJs = true
span.article-meta
span.article-meta-separator |
i.fas.fa-comments
if block
block
span.article-meta-label= ' ' + _p('card_post_count')
if theme.comments.card_post_count && theme.comments.use
case theme.comments.use[0]
when 'Disqus'
when 'Disqusjs'
+countBlockInIndex
a.disqus-count(href=full_url_for(link) + '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Valine'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.valine-comment-count(data-xid=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Waline'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.waline-comment-count(data-path=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Twikoo'
+countBlockInIndex
a.twikoo-count(href=url_for(link) + '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Facebook Comments'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.fb-comments-count(data-href=urlNoIndex(article.permalink))
when 'Remark42'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.remark42__counter(data-url=urlNoIndex(article.permalink))
i.fa-solid.fa-spinner.fa-spin
when 'Artalk'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.artalk-count(data-page-key=url_for(link))
i.fa-solid.fa-spinner.fa-spin
//- Display the article introduction on homepage
case theme.index_post_content.method
when false
- break
when 1
.content!= article.description
when 2
if article.description
.content!= article.description
else
- const content = strip_html(article.content)
- let expert = content.substring(0, theme.index_post_content.length)
- content.length > theme.index_post_content.length ? expert += ' ...' : ''
.content!= expert
default
- const content = strip_html(article.content)
- let expert = content.substring(0, theme.index_post_content.length)
- content.length > theme.index_post_content.length ? expert += ' ...' : ''
.content!= expert
if theme.ad && theme.ad.index
if (index + 1) % 3 == 0
.recent-post-item.ads-wrap!=theme.ad.index

View File

@@ -0,0 +1,8 @@
- var top_img_404 = theme.error_404.background || theme.default_top_img
.error-content
.error-img
img(src=url_for(top_img_404) alt='Page not found')
.error-info
h1.error_title= '404'
.error_subtitle= theme.error_404.subtitle || _p('error404')

View File

@@ -0,0 +1,103 @@
//- - author:
//- avatar:
//- date:
//- content:
//- tags:
//- - tag1
//- - tag2
- page.comments = false
- page.toc = false
#article-container
if page.shuoshuo_url
script.
(() => {
const loadShuoshuo = async () => {
try {
const fetchContent = await fetch('!{url_for(page.shuoshuo_url)}')
const shuoshuo = await fetchContent.json()
let start = 0
const container = document.getElementById('article-container')
const addData = data => {
const cLength = data.length
const end = start + 10 > cLength ? cLength : start + 10
let result = ''
data.slice(start, end).forEach((item) => {
result += `
<div class="shuoshuo-item">
<div class="shuoshuo-item-header">
<div class="shuoshuo-avatar">
<img class="no-lightbox" src="${item.avatar || '!{url_for(theme.avatar.img)}'}">
</div>
<div class="shuoshuo-info">
<div class="shuoshuo-author">${item.author || '!{config.author}'}</div>
<div class="shuoshuo-date">${btf.diffDate(item.date, true)}</div>
</div>
</div>
<div class="shuoshuo-content">
${item.content}
</div>
<div class="shuoshuo-footer">
<div class="shuoshuo-tags">
${item.tags.map(tag => `<span class="shuoshuo-tag">${tag}</span>`).join('')}
</div>
</div>
</div>
`
})
start = end
container.insertAdjacentHTML('beforeend', result)
if (start >= cLength) {
observer.disconnect()
} else {
setTimeout(() => observer.observe(container.lastElementChild), 100)
}
window.lazyLoadInstance.update()
btf.loadLightbox(document.querySelectorAll('#article-container img:not(.no-lightbox)'))
}
addData(shuoshuo)
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
observer.unobserve(entries[0].target)
addData(shuoshuo)
}
}, {
root: null,
rootMargin: '0px',
threshold: 1.0
})
if (container.lastElementChild) {
observer.observe(container.lastElementChild)
}
} catch (e) {
console.error(e)
}
}
window.pjax ? loadShuoshuo() : window.addEventListener('load', loadShuoshuo)
})()
else
if site.data.shuoshuo
each i in site.data.shuoshuo
.shuoshuo-item
.shuoshuo-item-header
.shuoshuo-avatar
img.no-lightbox(src=i.avatar || url_for(theme.avatar.img))
.shuoshuo-info
.shuoshuo-author=i.author || config.author
.shuoshuo-date=relative_date(i.date)
.shuoshuo-content
!=markdown(i.content)
.shuoshuo-footer
.shuoshuo-tags
each tag in i.tags
span.shuoshuo-tag=tag

View File

@@ -1,2 +1,2 @@
.tag-cloud-list.is-center
!=cloudTags({source: site.tags, orderby: page.orderby || 'random', order: page.order || 1, minfontsize: 1.2, maxfontsize: 2.1, limit: 0, unit: 'em'})
!=cloudTags({source: site.tags, orderby: page.orderby || 'random', order: page.order || 1, minfontsize: 1.2, maxfontsize: 1.5, limit: 0, unit: 'em'})

View File

@@ -12,27 +12,25 @@ if is_post()
nav#pagination.pagination-post
if(prev)
- var hasPageNext = next ? 'pull-left' : 'pull-full'
.prev-post(class=hasPageNext)
a(href=url_for(prev.path) title=prev.title)
if prev.cover_type === 'img'
img.cover(src=url_for(prev.cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of previous post')
else
.cover(style=`background: ${prev.cover || 'var(--default-bg-color)'}`)
.pagination-info
.label=_p('pagination.prev')
.prev_info=prev.title
a.prev-post(class=hasPageNext href=url_for(prev.path) title=prev.title)
if prev.cover_type === 'img'
img.cover(src=url_for(prev.cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of previous post')
else
.cover(style=`background: ${prev.cover || 'var(--default-bg-color)'}`)
.pagination-info
.label=_p('pagination.prev')
.prev_info=prev.title
if(next)
- var hasPagePrev = prev ? 'pull-right' : 'pull-full'
.next-post(class=hasPagePrev)
a(href=url_for(next.path) title=next.title)
if next.cover_type === 'img'
img.cover(src=url_for(next.cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of next post')
else
.cover(style=`background: ${next.cover || 'var(--default-bg-color)'}`)
.pagination-info
.label=_p('pagination.next')
.next_info=next.title
a.next-post(class=hasPagePrev href=url_for(next.path) title=next.title)
if next.cover_type === 'img'
img.cover(src=url_for(next.cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of next post')
else
.cover(style=`background: ${next.cover || 'var(--default-bg-color)'}`)
.pagination-info
.label=_p('pagination.next')
.next_info=next.title
else
nav#pagination
.pagination

View File

@@ -1,4 +1,4 @@
- const { readmode, translate, darkmode, aside, chat_btn } = theme
- const { readmode, translate, darkmode, aside, chat } = theme
mixin rightsideItem(array)
each item in array
case item
@@ -22,9 +22,9 @@ mixin rightsideItem(array)
button#mobile-toc-button.close(type="button" title=_p("rightside.toc"))
i.fas.fa-list-ul
when 'chat'
if chat_btn
if chat.rightside_button && chat.use
button#chat-btn(type="button" title=_p("rightside.chat"))
i.fas.fa-sms
i.fas.fa-message
when 'comment'
if commentsJsLoad
a#to_comment(href="#post-comment" title=_p("rightside.scroll_to_comment"))

View File

@@ -1,18 +1,18 @@
#sidebar
#menu-mask
#sidebar-menus
.avatar-img.is-center
img(src=url_for(theme.avatar.img) onerror=`onerror=null;src='${theme.error_img.flink}'` alt="avatar")
.sidebar-site-data.site-data.is-center
a(href=url_for(config.archive_dir) + '/')
.headline= _p('aside.articles')
.length-num= site.posts.length
a(href=url_for(config.tag_dir) + '/' )
.headline= _p('aside.tags')
.length-num= site.tags.length
a(href=url_for(config.category_dir) + '/')
.headline= _p('aside.categories')
.length-num= site.categories.length
if theme.menu
#sidebar
#menu-mask
#sidebar-menus
.avatar-img.is-center
img(src=url_for(theme.avatar.img) onerror=`onerror=null;src='${theme.error_img.flink}'` alt="avatar")
.site-data.is-center
a(href=url_for(config.archive_dir) + '/')
.headline= _p('aside.articles')
.length-num= site.posts.length
a(href=url_for(config.tag_dir) + '/' )
.headline= _p('aside.tags')
.length-num= site.tags.length
a(href=url_for(config.category_dir) + '/')
.headline= _p('aside.categories')
.length-num= site.categories.length
hr.custom-hr
!=partial('includes/header/menu_item', {}, {cache: true})
!=partial('includes/header/menu_item', {}, {cache: true})

View File

@@ -14,10 +14,10 @@ if theme.pjax.enable
}
}
const loadMeting = () => {
const runMetingJS = () => {
typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()
}
btf.addGlobalFn('pjaxSend', destroyAplayer, 'destroyAplayer')
btf.addGlobalFn('pjaxComplete', loadMeting, 'loadMeting')
btf.addGlobalFn('pjaxComplete', loadMeting, 'runMetingJS')
})()

View File

@@ -1,5 +1,5 @@
- const fbSDKVer = 'v16.0'
- const fbSDK = theme.messenger.enable ? `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk/xfbml.customerchat.js#xfbml=1&version=${fbSDKVer}` : `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk.js#xfbml=1&version=${fbSDKVer}`
- const fbSDK = theme.chat.use === 'messenger' ? `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk/xfbml.customerchat.js#xfbml=1&version=${fbSDKVer}` : `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk.js#xfbml=1&version=${fbSDKVer}`
script.
(()=>{

View File

@@ -1,8 +1,8 @@
//- https://chatra.io/help/api/
script.
(() => {
const isChatBtn = !{theme.chat_btn}
const isChatHideShow = !{theme.chat_hide_show}
const isChatBtn = !{theme.chat.rightside_button}
const isChatHideShow = !{theme.chat.button_hide_show}
if (isChatBtn) {
const close = () => {

View File

@@ -11,8 +11,8 @@ script.
})();
$crisp.push(["safe", true])
const isChatBtn = !{theme.chat_btn}
const isChatHideShow = !{theme.chat_hide_show}
const isChatBtn = !{theme.chat.rightside_button}
const isChatHideShow = !{theme.chat.button_hide_show}
if (isChatBtn) {
const open = () => {

View File

@@ -3,8 +3,8 @@ script.
(() => {
(function(i,s,o,g,r,a,m){i["DaoVoiceObject"]=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;a.charset="utf-8";m.parentNode.insertBefore(a,m)})(window,document,"script",('https:' == document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/!{theme.daovoice.app_id}.js","daovoice")
const isChatBtn = !{theme.chat_btn}
const isChatHideShow = !{theme.chat_hide_show}
const isChatBtn = !{theme.chat.rightside_button}
const isChatHideShow = !{theme.chat.button_hide_show}
daovoice('init', {
app_id: '!{theme.daovoice.app_id}',},{

View File

@@ -1,10 +1,11 @@
if theme.chatra && theme.chatra.enable
include ./chatra.pug
else if theme.tidio && theme.tidio.enable
include ./tidio.pug
else if theme.daovoice && theme.daovoice.enable
include ./daovoice.pug
else if theme.crisp && theme.crisp.enable
include ./crisp.pug
else if theme.messenger && theme.messenger.enable
include ./messenger.pug
case theme.chat.use
when 'chatra'
include ./chatra.pug
when 'tidio'
include ./tidio.pug
when 'daovoice'
include ./daovoice.pug
when 'crisp'
include ./crisp.pug
when 'messenger'
include ./messenger.pug

View File

@@ -22,8 +22,8 @@ script.
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
const isChatBtn = !{theme.chat_btn}
const isChatHideShow = !{theme.chat_hide_show}
const isChatBtn = !{theme.chat.rightside_button}
const isChatHideShow = !{theme.chat.button_hide_show}
if (isChatBtn) {
window.chatBtnFn = () => {

View File

@@ -1,8 +1,8 @@
script(src=`//code.tidio.co/${theme.tidio.public_key}.js` async)
script.
(() => {
const isChatBtn = !{theme.chat_btn}
const isChatHideShow = !{theme.chat_hide_show}
const isChatBtn = !{theme.chat.rightside_button}
const isChatHideShow = !{theme.chat.button_hide_show}
if (isChatBtn) {
let isShow = false

View File

@@ -25,7 +25,7 @@ script.
artalkItem.destroy()
}
btf.addGlobalFn('pjax', destroyArtalk, 'destroyArtalk')
btf.addGlobalFn('pjaxSendOnce', destroyArtalk, 'destroyArtalk')
}
const loadArtalk = async () => {

View File

@@ -1,5 +1,5 @@
- const fbSDKVer = 'v16.0'
- const fbSDK = theme.messenger.enable ? `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk/xfbml.customerchat.js#xfbml=1&version=${fbSDKVer}` : `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk.js#xfbml=1&version=${fbSDKVer}`
- const fbSDK = theme.chat.use === 'messenger' ? `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk/xfbml.customerchat.js#xfbml=1&version=${fbSDKVer}` : `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk.js#xfbml=1&version=${fbSDKVer}`
script.
(()=>{

View File

@@ -1,13 +1,11 @@
- const { repo, repo_id, category_id, theme:themes, option } = theme.giscus
- const giscusUrl = theme.asset.giscus || 'https://giscus.app/client.js'
- const giscusOriginUrl = new URL(giscusUrl).origin
- const { use, lazyload } = theme.comments
- const { repo, repo_id, category_id, light_theme, dark_theme, js, option } = theme.giscus
- const giscusUrl = js || 'https://giscus.app/client.js'
- const giscusOriginUrl = new URL(giscusUrl).origin
script.
(()=>{
const getGiscusTheme = theme => {
return theme === 'dark' ? '!{themes.dark}' : '!{themes.light}'
}
const getGiscusTheme = theme => theme === 'dark' ? '!{dark_theme}' : '!{light_theme}'
const loadGiscus = () => {
const config = Object.assign({
@@ -30,17 +28,17 @@ script.
}
const changeGiscusTheme = theme => {
const sendMessage = message => {
const iframe = document.querySelector('iframe.giscus-frame')
if (!iframe) return
iframe.contentWindow.postMessage({ giscus: message }, '!{giscusOriginUrl}')
}
sendMessage({
setConfig: {
theme: getGiscusTheme(theme)
const iframe = document.querySelector('#giscus-wrap iframe')
if (iframe) {
const message = {
giscus: {
setConfig: {
theme: getGiscusTheme(theme)
}
}
}
});
iframe.contentWindow.postMessage(message, '!{giscusOriginUrl}')
}
}
btf.addGlobalFn('themeChange', changeGiscusTheme, 'giscus')

View File

@@ -1,34 +1,42 @@
- const { use, lazyload } = theme.comments
- const { repo, issue_term, light_theme, dark_theme } = theme.utterances
- const { repo, issue_term, light_theme, dark_theme, js, option } = theme.utterances
- const utterancesUrl = js || 'https://utteranc.es/client.js'
- const utterancesOriginUrl = new URL(utterancesUrl).origin
script.
(() => {
const getUtterancesTheme = theme => theme === 'dark' ? '#{dark_theme}' : '#{light_theme}'
const loadUtterances = () => {
let ele = document.createElement('script')
ele.id = 'utterances_comment'
ele.src = 'https://utteranc.es/client.js'
ele.setAttribute('repo', '!{repo}')
ele.setAttribute('issue-term', '!{issue_term}')
const nowTheme = document.documentElement.getAttribute('data-theme') === 'dark' ? '#{dark_theme}' : '#{light_theme}'
ele.setAttribute('theme', nowTheme)
ele.crossOrigin = 'anonymous'
ele.async = true
const config = Object.assign({
id: 'utterances_comment',
src: '!{utterancesUrl}',
repo: '!{repo}',
'issue-term': '!{issue_term}',
theme: getUtterancesTheme(document.documentElement.getAttribute('data-theme')),
crossorigin: 'anonymous',
async: true
},!{JSON.stringify(option)})
const ele = document.createElement('script')
for (let key in config) {
ele.setAttribute(key, config[key])
}
document.getElementById('utterances-wrap').appendChild(ele)
}
const utterancesTheme = theme => {
const iframe = document.querySelector('.utterances-frame')
const changeUtterancesTheme = theme => {
const iframe = document.querySelector('#utterances-wrap iframe')
if (iframe) {
const theme = theme === 'dark' ? '#{dark_theme}' : '#{light_theme}'
const message = {
type: 'set-theme',
theme: theme
theme: getUtterancesTheme(theme)
};
iframe.contentWindow.postMessage(message, 'https://utteranc.es');
iframe.contentWindow.postMessage(message, '!{utterancesOriginUrl}')
}
}
btf.addGlobalFn('themeChange', utterancesTheme, 'utterances')
btf.addGlobalFn('themeChange', changeUtterancesTheme, 'utterances')
if ('!{use[0]}' === 'Utterances' || !!{lazyload}) {
if (!{lazyload}) btf.loadComment(document.getElementById('utterances-wrap'), loadUtterances)

View File

@@ -19,7 +19,7 @@ script.
waline.destroy()
}
btf.addGlobalFn('pjax', destroyWaline, 'destroyWaline')
btf.addGlobalFn('pjaxSendOnce', destroyWaline, 'destroyWaline')
}
const loadWaline = () => {

View File

@@ -1,18 +1,19 @@
if theme.mathjax && theme.mathjax.enable
if theme.mathjax.per_page
if is_post() || is_page()
include ./mathjax.pug
else
if page.mathjax
include ./mathjax.pug
case theme.math.use
when 'mathjax'
if theme.math.per_page
if is_post() || is_page()
include ./mathjax.pug
else
if page.mathjax
include ./mathjax.pug
if theme.katex && theme.katex.enable
if theme.katex.per_page
if is_post() || is_page()
include ./katex.pug
else
if page.katex
include ./katex.pug
when 'katex'
if theme.math.per_page
if is_post() || is_page()
include ./katex.pug
else
if page.katex
include ./katex.pug
if theme.mermaid.enable
include ./mermaid.pug

View File

@@ -1,2 +1,16 @@
link(rel="stylesheet" type="text/css" href=url_for(theme.asset.katex))
script(src=url_for(theme.asset.katex_copytex))
script.
(async () => {
const showKatex = () => {
const mathElements = document.querySelectorAll('#article-container .katex')
mathElements.length && mathElements.forEach((el) => {
el.classList.add('katex-show')
})
}
if (!window.katex_js_css) {
window.katex_js_css = true
await btf.getCSS('!{url_for(theme.asset.katex)}')
if (!{theme.math.katex.copy_tex}) await btf.getScript('!{url_for(theme.asset.katex_copytex)}')
}
showKatex()
})()

View File

@@ -1,4 +1,5 @@
//- Mathjax 3
- const { tags, enableMenu } = theme.math.mathjax
script.
(() => {
const loadMathjax = () => {
@@ -6,12 +7,13 @@ script.
window.MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']],
tags: 'ams'
tags: '!{tags}',
},
chtml: {
scale: 1.1
},
options: {
enableMenu: !{enableMenu},
renderActions: {
findScript: [10, doc => {
for (const node of document.querySelectorAll('script[type^="math/tex"]')) {

View File

@@ -11,18 +11,12 @@ script.
const mermaidDefinition = mermaidThemeConfig + mermaidSrc.textContent
const renderFn = mermaid.render(mermaidID, mermaidDefinition)
const renderV10 = () => {
renderFn.then(({svg}) => {
mermaidSrc.insertAdjacentHTML('afterend', svg)
})
}
const renderV9 = svg => {
const renderMermaid = svg => {
mermaidSrc.insertAdjacentHTML('afterend', svg)
}
typeof renderFn === 'string' ? renderV9(renderFn) : renderV10()
// mermaid v9 and v10 compatibility
typeof renderFn === 'string' ? renderMermaid(renderFn) : renderFn.then(({svg}) => renderMermaid(svg))
})
}
@@ -31,9 +25,13 @@ script.
if (codeMermaidEle.length === 0) return
codeMermaidEle.forEach(ele => {
const preEle = document.createElement('pre')
preEle.className = 'mermaid-src'
preEle.hidden = true
preEle.textContent = ele.textContent
const newEle = document.createElement('div')
newEle.className = 'mermaid-wrap'
newEle.innerHTML = `<pre class="mermaid-src" hidden>${ele.textContent}</pre>`
newEle.appendChild(preEle)
ele.parentNode.replaceWith(newEle)
})
}

View File

@@ -1,6 +1,6 @@
- const { server, site, option } = theme.artalk
- const avatarCdn = option !== null && option.gravatar && option.gravatar.mirror
- const avatarDefault = option !== null && option.gravatar && (option.gravatar.params || option.gravatar.default)
- const avatarCdn = (option !== null && option.gravatar && option.gravatar.mirror) || ''
- const avatarDefault = (option !== null && option.gravatar && (option.gravatar.params || option.gravatar.default)) || ''
script.
window.addEventListener('load', () => {
@@ -25,7 +25,7 @@ script.
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (!{theme.newest_comments.avatar}) {
if (!{theme.aside.card_newest_comments.avatar}) {
const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}
@@ -60,7 +60,7 @@ script.
const searchParams = new URLSearchParams({
'site_name': '!{site}',
'limit': '!{theme.newest_comments.limit}',
'limit': '!{theme.aside.card_newest_comments.limit}',
})
const getComment = async () => {
@@ -69,8 +69,8 @@ script.
const result = await res.json()
const avatarStr = await getSetting()
const { mirror, params, default:defaults } = avatarStr.frontend_conf.gravatar
const avatarCdn = !{avatarCdn} || mirror
let avatarDefault = !{avatarDefault} || params || defaults
const avatarCdn = '!{avatarCdn}' || mirror
let avatarDefault = '!{avatarDefault}' || params || defaults
avatarDefault = avatarDefault.startsWith('d=') ? avatarDefault : `d=${avatarDefault}`
const artalk = result.data.map(function (e) {
return {
@@ -81,7 +81,7 @@ script.
'date': e.date,
}
})
btf.saveToLocal.set('artalk-newest-comments', JSON.stringify(artalk), !{theme.newest_comments.storage}/(60*24))
btf.saveToLocal.set('artalk-newest-comments', JSON.stringify(artalk), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(artalk)
} catch (e) {
console.log(e)

View File

@@ -15,7 +15,7 @@ script.
}
const getComment = () => {
fetch('https://disqus.com/api/3.0/forums/listPosts.json?forum=!{forum}&related=thread&limit=!{theme.newest_comments.limit}&api_key=!{apiKey}')
fetch('https://disqus.com/api/3.0/forums/listPosts.json?forum=!{forum}&related=thread&limit=!{theme.aside.card_newest_comments.limit}&api_key=!{apiKey}')
.then(response => response.json())
.then(data => {
const disqusArray = data.response.map(item => {
@@ -28,7 +28,7 @@ script.
}
})
btf.saveToLocal.set('disqus-newest-comments', JSON.stringify(disqusArray), !{theme.newest_comments.storage}/(60*24))
btf.saveToLocal.set('disqus-newest-comments', JSON.stringify(disqusArray), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(disqusArray)
}).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list')
@@ -43,7 +43,7 @@ script.
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (!{theme.newest_comments.avatar}) {
if (!{theme.aside.card_newest_comments.avatar}) {
const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}

View File

@@ -35,13 +35,13 @@ script.
}
})
btf.saveToLocal.set('github-newest-comments', JSON.stringify(array), !{theme.newest_comments.storage}/(60*24))
btf.saveToLocal.set('github-newest-comments', JSON.stringify(array), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(array)
});
}
const getComment = () => {
fetch('https://api.github.com/repos/!{userRepo}/issues/comments?sort=updated&direction=desc&per_page=!{theme.newest_comments.limit}&page=1',{
fetch('https://api.github.com/repos/!{userRepo}/issues/comments?sort=updated&direction=desc&per_page=!{theme.aside.card_newest_comments.limit}&page=1',{
"headers": {
Accept: 'application/vnd.github.v3.html+json'
}
@@ -72,7 +72,7 @@ script.
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (!{theme.newest_comments.avatar}) {
if (!{theme.aside.card_newest_comments.avatar}) {
const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}

View File

@@ -23,7 +23,7 @@ script.
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (!{theme.newest_comments.avatar}) {
if (!{theme.aside.card_newest_comments.avatar}) {
const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}
@@ -44,7 +44,7 @@ script.
}
const getComment = () => {
fetch('!{host}/api/v1/last/!{theme.newest_comments.limit}?site=!{siteId}')
fetch('!{host}/api/v1/last/!{theme.aside.card_newest_comments.limit}?site=!{siteId}')
.then(response => response.json())
.then(data => {
const remark42 = data.map(function (e) {
@@ -56,7 +56,7 @@ script.
'date': e.time,
}
})
btf.saveToLocal.set('remark42-newest-comments', JSON.stringify(remark42), !{theme.newest_comments.storage}/(60*24))
btf.saveToLocal.set('remark42-newest-comments', JSON.stringify(remark42), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(remark42)
}).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list')

View File

@@ -5,7 +5,7 @@ script.
content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link
content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url
content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_aside.card_aside.card_newest_comments.code")}]') // replace code
content = content.replace(/<[^>]+>/g,"") // remove html tag
if (content.length > 150) {
@@ -19,7 +19,7 @@ script.
twikoo.getRecentComments({
envId: '!{theme.twikoo.envId}',
region: '!{theme.twikoo.region}',
pageSize: !{theme.newest_comments.limit},
pageSize: !{theme.aside.card_newest_comments.limit},
includeReply: true
}).then(function (res) {
const twikooArray = res.map(e => {
@@ -32,7 +32,7 @@ script.
}
})
btf.saveToLocal.set('twikoo-newest-comments', JSON.stringify(twikooArray), !{theme.newest_comments.storage}/(60*24))
btf.saveToLocal.set('twikoo-newest-comments', JSON.stringify(twikooArray), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(twikooArray)
}).catch(function (err) {
const $dom = document.querySelector('#card-newest-comments .aside-list')
@@ -54,7 +54,7 @@ script.
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (!{theme.newest_comments.avatar}) {
if (!{theme.aside.card_newest_comments.avatar}) {
const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}

View File

@@ -31,7 +31,7 @@ script.
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (!{theme.newest_comments.avatar}) {
if (!{theme.aside.card_newest_comments.avatar}) {
const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}
@@ -63,7 +63,7 @@ script.
},
}
fetch(`${serverURL}/1.1/classes/Comment?limit=!{theme.newest_comments.limit}&order=-createdAt`,settings)
fetch(`${serverURL}/1.1/classes/Comment?limit=!{theme.aside.card_newest_comments.limit}&order=-createdAt`,settings)
.then(response => response.json())
.then(data => {
const valineArray = data.results.map(function (e) {
@@ -75,7 +75,7 @@ script.
'date': e.updatedAt,
}
})
btf.saveToLocal.set('valine-newest-comments', JSON.stringify(valineArray), !{theme.newest_comments.storage}/(60*24))
btf.saveToLocal.set('valine-newest-comments', JSON.stringify(valineArray), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(valineArray)
}).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list')

View File

@@ -23,7 +23,7 @@ script.
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (!{theme.newest_comments.avatar}) {
if (!{theme.aside.card_newest_comments.avatar}) {
const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}
@@ -45,7 +45,7 @@ script.
const getComment = async () => {
try {
const res = await fetch('!{serverURL}/api/comment?type=recent&count=!{theme.newest_comments.limit}', { method: 'GET' })
const res = await fetch('!{serverURL}/api/comment?type=recent&count=!{theme.aside.card_newest_comments.limit}', { method: 'GET' })
const result = await res.json()
const walineArray = result.data.map(e => {
return {
@@ -56,7 +56,7 @@ script.
'date': e.time || e.insertedAt
}
})
btf.saveToLocal.set('waline-newest-comments', JSON.stringify(walineArray), !{theme.newest_comments.storage}/(60*24))
btf.saveToLocal.set('waline-newest-comments', JSON.stringify(walineArray), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(walineArray)
} catch (err) {
console.error(err)

View File

@@ -32,7 +32,7 @@ script.
document.addEventListener('pjax:send', function () {
// removeEventListener
btf.removeGlobalFnEvent('pjax')
btf.removeGlobalFnEvent('pjaxSendOnce')
btf.removeGlobalFnEvent('themeChange')
//reset readmode
@@ -43,6 +43,7 @@ script.
})
document.addEventListener('pjax:complete', () => {
btf.removeGlobalFnEvent('pjaxCompleteOnce')
document.querySelectorAll('script[data-pjax]').forEach(item => {
const newScript = document.createElement('script')
const content = item.text || item.textContent || item.innerHTML || ""

View File

@@ -1,4 +1,4 @@
- const { appId, apiKey, indexName, option } = theme.docsearch
- const { placeholder, docsearch: { appId, apiKey, indexName, option } } = theme.search
.docsearch-wrap
#docsearch(style="display:none")
@@ -11,6 +11,7 @@
apiKey: '!{apiKey}',
indexName: '!{indexName}',
container: '#docsearch',
placeholder: '!{ placeholder || _p("search.input_placeholder")}',
}, !{JSON.stringify(option)}))
const handleClick = () => {

View File

@@ -1,6 +1,7 @@
if theme.algolia_search.enable
include ./algolia.pug
else if theme.local_search.enable
include ./local-search.pug
else if theme.docsearch.enable
include ./docsearch.pug
case theme.search.use
when 'algolia_search'
include ./algolia.pug
when 'local_search'
include ./local-search.pug
when 'docsearch'
include ./docsearch.pug

View File

@@ -13,7 +13,7 @@
.search-wrap
#local-search-input
.local-search-box
input(placeholder=_p("search.local_search.input_placeholder") type="text").local-search-box--input
input(placeholder=theme.search.placeholder || _p("search.input_placeholder") type="text").local-search-box--input
hr
#local-search-results
#local-search-stats-wrap

View File

@@ -1,5 +1,9 @@
.post_share
if theme.sharejs.enable
include ./share-js.pug
else if theme.addtoany.enable
!=partial('includes/third-party/share/addtoany', {}, {cache: true})
- const { use } = theme.share
if use
.post-share
case use
when 'addtoany'
!=partial('includes/third-party/share/addtoany', {}, {cache: true})
when 'sharejs'
include ./share-js.pug

View File

@@ -1,4 +1,4 @@
- const coverVal = page.cover_type === 'img' ? page.cover : theme.avatar.img
.social-share(data-image=url_for(coverVal) data-sites= theme.sharejs.sites)
.social-share(data-image=url_for(coverVal) data-sites= theme.share.sharejs.sites)
link(rel='stylesheet' href=url_for(theme.asset.sharejs_css) media="print" onload="this.media='all'")
script(src=url_for(theme.asset.sharejs) defer)

View File

@@ -3,7 +3,7 @@
script.
window.typedJSFn = {
init: (str) => {
init: str => {
window.typed = new Typed('#subtitle', Object.assign({
strings: str,
startDelay: 300,
@@ -12,7 +12,7 @@ script.
backSpeed: 50,
}, !{JSON.stringify(typed_option)}))
},
run: (subtitleType) => {
run: subtitleType => {
if (!{effect}) {
if (typeof Typed === 'function') {
subtitleType()
@@ -24,7 +24,7 @@ script.
}
}
}
btf.addGlobalFn('pjaxSend', () => { typed.destroy() }, 'typedDestroy')
btf.addGlobalFn('pjaxSendOnce', () => { typed.destroy() }, 'typedDestroy')
case source
when 1

View File

@@ -1,12 +1,11 @@
if theme.aside.card_author.enable
.card-widget.card-info
.is-center
.avatar-img
img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar")
.author-info__name= config.author
.author-info__description!= theme.aside.card_author.description || config.description
.card-widget.card-info.is-center
.avatar-img
img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar")
.author-info-name= config.author
.author-info-description!= theme.aside.card_author.description || config.description
.card-info-data.site-data.is-center
.site-data
a(href=url_for(config.archive_dir) + '/')
.headline= _p('aside.articles')
.length-num= site.posts.length
@@ -23,5 +22,5 @@ if theme.aside.card_author.enable
span=theme.aside.card_author.button.text
if(theme.social)
.card-info-social-icons.is-center
!=partial('includes/header/social', {}, {cache: true})
.card-info-social-icons
!=partial('includes/header/social', {}, {cache: true})

View File

@@ -1,4 +1,4 @@
if theme.newest_comments.enable && theme.comments.use && !['Livere','Facebook Comments','Giscus'].includes(theme.comments.use[0])
if theme.aside.card_newest_comments.enable && theme.comments.use && !['Livere','Facebook Comments','Giscus'].includes(theme.comments.use[0])
.card-widget#card-newest-comments
.item-headline
i.fas.fa-comment-dots

View File

@@ -8,10 +8,10 @@ if theme.aside.card_webinfo.enable
.webinfo-item
.item-name= _p('aside.card_webinfo.article_name') + " :"
.item-count= site.posts.length
if theme.runtimeshow.enable
if theme.aside.card_webinfo.runtime_date
.webinfo-item
.item-name= _p('aside.card_webinfo.runtime.name') + " :"
.item-count#runtimeshow(data-publishDate=date_xml(theme.runtimeshow.publish_date))
.item-count#runtimeshow(data-publishDate=date_xml(theme.aside.card_webinfo.runtime_date))
i.fa-solid.fa-spinner.fa-spin
if theme.wordcount.enable && theme.wordcount.total_wordcount
.webinfo-item