diff --git a/README.md b/README.md index 7589930..d9ecfb9 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ npm i hexo-theme-butterfly - [x] Share (Sharejs/Addtoany) - [X] Comment (Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/artalk) - [x] Multiple Comment System Support -- [x] Online Chats (Chatra/Tidio/Daovoice/Crisp) +- [x] Online Chats (Chatra/Tidio/Crisp) - [x] Web analytics - [x] Google AdSense - [x] Webmaster Verification @@ -98,6 +98,7 @@ npm i hexo-theme-butterfly - [x] Busuanzi visitor counter - [x] Medium Zoom/Fancybox - [x] Mermaid +- [x] Chart.js - [x] Justified Gallery - [x] Lazyload images - [x] Instantpage/Pangu/Snackbar notification toast/PWA...... diff --git a/README_CN.md b/README_CN.md index 552205b..f1d7a5c 100644 --- a/README_CN.md +++ b/README_CN.md @@ -86,7 +86,7 @@ theme: butterfly - [x] 多種分享系統(Sharejs/Addtoany) - [X] 多種評論系統(Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/artalk) - [x] 支持雙評論部署 -- [x] 多種在線聊天(Chatra/Tidio/Daovoice/Crisp) +- [x] 多種在線聊天(Chatra/Tidio/Crisp) - [x] 多種分析系統 - [x] 谷歌廣告/手動廣告位置 - [x] 各種站長驗證 @@ -98,6 +98,7 @@ theme: butterfly - [x] 不蒜子訪問統計 - [x] 兩種大圖模式(Medium Zoom/Fancybox) - [x] Mermaid 圖表顯示 +- [x] Chart.js 圖表顯示 - [x] 照片牆 - [x] 圖片懶加載 - [x] Instantpage/Pangu/Snackbar彈窗/PWA...... diff --git a/_config.yml b/_config.yml index a448599..ac99d06 100644 --- a/_config.yml +++ b/_config.yml @@ -602,7 +602,7 @@ facebook_comments: pageSize: 10 # Choose: social / time / reverse_time order_by: social - lang: zh_TW + lang: en_US # Twikoo # https://github.com/imaegoo/twikoo @@ -645,7 +645,7 @@ artalk: # -------------------------------------- chat: - # Choose: chatra/tidio/daovoice/crisp + # Choose: chatra/tidio/crisp # Leave it empty if you don't need chat use: # Chat Button [recommend] @@ -662,10 +662,6 @@ chatra: tidio: public_key: -# http://dashboard.daovoice.io/app -daovoice: - app_id: - # https://crisp.chat/en/ crisp: website_id: @@ -924,6 +920,25 @@ mermaid: light: default dark: dark +# chartjs +# see https://www.chartjs.org/docs/latest/ +chartjs: + enable: false + # Do not modify unless you understand how they work. + # The default settings are only used when the MD syntax is not specified. + # General font color for the chart + fontColor: + light: "rgba(0, 0, 0, 0.8)" + dark: "rgba(255, 255, 255, 0.8)" + # General border color for the chart + borderColor: + light: "rgba(0, 0, 0, 0.1)" + dark: "rgba(255, 255, 255, 0.2)" + # Background color for scale labels on radar and polar area charts + scale_ticks_backdropColor: + light: "transparent" + dark: "transparent" + # Note - Bootstrap Callout note: # Note tag style values: @@ -1050,6 +1065,7 @@ CDN: # canvas_fluttering_ribbon: # canvas_nest: # canvas_ribbon: + # chartjs: # click_heart: # clickShowText: # disqusjs: diff --git a/layout/includes/header/post-info.pug b/layout/includes/header/post-info.pug index b75dc96..f346f83 100644 --- a/layout/includes/header/post-info.pug +++ b/layout/includes/header/post-info.pug @@ -60,39 +60,7 @@ if block block - - const commentUse = comments.use && comments.use[0] - if page.comments !== false && commentUse && !comments.lazyload - case commentUse - when 'Valine' - if theme.valine.visitor - +pvBlock(url_for(page.path), 'leancloud_visitors', page.title) - span.leancloud-visitors-count - i.fa-solid.fa-spinner.fa-spin - when 'Waline' - if theme.waline.pageview - +pvBlock('', '', '') - span.waline-pageview-count(data-path=url_for(page.path)) - i.fa-solid.fa-spinner.fa-spin - when 'Twikoo' - if theme.twikoo.visitor - +pvBlock('', '', '') - span#twikoo_visitors - i.fa-solid.fa-spinner.fa-spin - when 'Artalk' - if theme.artalk.visitor - +pvBlock('', '', '') - span#ArtalkPV - i.fa-solid.fa-spinner.fa-spin - default - if theme.umami_analytics.enable && theme.umami_analytics.UV_PV.page_pv - +pvBlock('', '', '') - span#umamiPV(data-path=url_for(page.path)) - i.fa-solid.fa-spinner.fa-spin - else if theme.busuanzi.page_pv - +pvBlock('', 'post-meta-pv-cv', '') - span#busuanzi_value_page_pv - i.fa-solid.fa-spinner.fa-spin - else + mixin otherPV() if theme.umami_analytics.enable && theme.umami_analytics.UV_PV.page_pv +pvBlock('', '', '') span#umamiPV(data-path=url_for(page.path)) @@ -102,6 +70,29 @@ span#busuanzi_value_page_pv i.fa-solid.fa-spinner.fa-spin + - const commentUse = comments.use && comments.use[0] + if page.comments !== false && commentUse && !comments.lazyload + if commentUse === 'Valine' && theme.valine.visitor + +pvBlock(url_for(page.path), 'leancloud_visitors', page.title) + span.leancloud-visitors-count + i.fa-solid.fa-spinner.fa-spin + else if commentUse === 'Waline' && theme.waline.pageview + +pvBlock('', '', '') + span.waline-pageview-count(data-path=url_for(page.path)) + i.fa-solid.fa-spinner.fa-spin + else if commentUse === 'Twikoo' && theme.twikoo.visitor + +pvBlock('', '', '') + span#twikoo_visitors + i.fa-solid.fa-spinner.fa-spin + else if commentUse === 'Artalk' && theme.artalk.visitor + +pvBlock('', '', '') + span#ArtalkPV + i.fa-solid.fa-spinner.fa-spin + else + +otherPV() + else + +otherPV() + if comments.count && !comments.lazyload && page.comments !== false && comments.use - var whichCount = comments.use[0] diff --git a/layout/includes/mixins/indexPostUI.pug b/layout/includes/mixins/indexPostUI.pug index 7e80df9..4c53704 100644 --- a/layout/includes/mixins/indexPostUI.pug +++ b/layout/includes/mixins/indexPostUI.pug @@ -105,15 +105,9 @@ mixin indexPostUI() 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) + - const content = postDesc(article) + if content + .content!=content if theme.ad && theme.ad.index if (index + 1) % 3 === 0 diff --git a/layout/includes/page/shuoshuo.pug b/layout/includes/page/shuoshuo.pug index 745b048..88b55cc 100644 --- a/layout/includes/page/shuoshuo.pug +++ b/layout/includes/page/shuoshuo.pug @@ -21,6 +21,8 @@ let start = 0 const container = document.getElementById('article-container') + const showDateAndTine = date => new Date(date).toLocaleString() + const addData = data => { const cLength = data.length const end = start + 10 > cLength ? cLength : start + 10 @@ -34,16 +36,19 @@
${item.author || '!{config.author}'}
-
${btf.diffDate(item.date, true)}
+
${item.content}
` @@ -94,10 +99,11 @@ 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) + time.shuoshuo-date(title=full_date(i.date))=date(i.date) .shuoshuo-content !=markdown(i.content) .shuoshuo-footer - .shuoshuo-tags - each tag in i.tags - span.shuoshuo-tag=tag \ No newline at end of file + if i.tags + .shuoshuo-tags + each tag in i.tags + span.shuoshuo-tag=tag \ No newline at end of file diff --git a/layout/includes/page/tags.pug b/layout/includes/page/tags.pug index b579112..b5b62cd 100644 --- a/layout/includes/page/tags.pug +++ b/layout/includes/page/tags.pug @@ -1,2 +1,2 @@ -.tag-cloud-list.is-center +.tag-cloud-list.text-center !=cloudTags({source: site.tags, orderby: page.orderby || 'random', order: page.order || 1, minfontsize: 1.2, maxfontsize: 1.5, limit: 0, unit: 'em'}) \ No newline at end of file diff --git a/layout/includes/pagination.pug b/layout/includes/pagination.pug index 7cbe946..ad2602b 100644 --- a/layout/includes/pagination.pug +++ b/layout/includes/pagination.pug @@ -7,30 +7,28 @@ } if is_post() - - let prev = theme.post_pagination === 1 ? page.prev : page.next - - let next = theme.post_pagination === 1 ? page.next : page.prev + - let paginationOrder = theme.post_pagination === 1 ? { prev: page.prev, next: page.next } : { prev: page.next, next: page.prev } + nav#pagination.pagination-post - if(prev) - - var hasPageNext = next ? 'pull-left' : 'pull-full' - 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 + each direction, key in paginationOrder + if direction + - const getPostDesc = direction.postDesc || postDesc(direction) + - let className = key === 'prev' ? (paginationOrder.next ? '' : 'full-width') : (paginationOrder.prev ? '' : 'full-width') + - className = getPostDesc ? className : className + ' no-desc' + + a.pagination-related(class=className href=url_for(direction.path) title=direction.title) + if direction.cover_type === 'img' + img.cover(src=url_for(direction.cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt=`cover of ${key === 'prev' ? 'previous' : 'next'} post`) + else + .cover(style=`background: ${direction.cover || 'var(--default-bg-color)'}`) - if(next) - - var hasPagePrev = prev ? 'pull-right' : 'pull-full' - 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 + .info(class=key === 'prev' ? '' : 'text-right') + .info-1 + .info-item-1=_p(`pagination.${key}`) + .info-item-2!=direction.title + if getPostDesc + .info-2 + .info-item-1!=getPostDesc else nav#pagination .pagination diff --git a/layout/includes/sidebar.pug b/layout/includes/sidebar.pug index 7eabbf1..42131cd 100644 --- a/layout/includes/sidebar.pug +++ b/layout/includes/sidebar.pug @@ -2,9 +2,9 @@ if theme.menu #sidebar #menu-mask #sidebar-menus - .avatar-img.is-center + .avatar-img.text-center img(src=url_for(theme.avatar.img) onerror=`onerror=null;src='${theme.error_img.flink}'` alt="avatar") - .site-data.is-center + .site-data.text-center a(href=url_for(config.archive_dir) + '/') .headline= _p('aside.articles') .length-num= site.posts.length diff --git a/layout/includes/third-party/abcjs/abcjs.pug b/layout/includes/third-party/abcjs/abcjs.pug index 089ee2b..a75c37b 100644 --- a/layout/includes/third-party/abcjs/abcjs.pug +++ b/layout/includes/third-party/abcjs/abcjs.pug @@ -1,12 +1,12 @@ script. (() => { const abcjsInit = () => { - const abcjsFn = () => { + const abcjsFn = () => setTimeout(() => { document.querySelectorAll(".abc-music-sheet").forEach(ele => { if (ele.children.length > 0) return ABCJS.renderAbc(ele, ele.innerHTML, {responsive: 'resize'}) }) - } + }, 100) typeof ABCJS === 'object' ? abcjsFn() : btf.getScript('!{url_for(theme.asset.abcjs_basic_js)}').then(abcjsFn) diff --git a/layout/includes/third-party/chat/daovoice.pug b/layout/includes/third-party/chat/daovoice.pug deleted file mode 100644 index 41ccfeb..0000000 --- a/layout/includes/third-party/chat/daovoice.pug +++ /dev/null @@ -1,40 +0,0 @@ -//- https://guide.daocloud.io/daovoice/javascript-api-5869833.html -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.rightside_button} - const isChatHideShow = !{theme.chat.button_hide_show} - - daovoice('init', { - app_id: '!{theme.daovoice.app_id}',},{ - launcher: { - disableLauncherIcon: isChatBtn - }, - }); - daovoice('update'); - - if (isChatBtn) { - window.chatBtnFn = () => { - const isShow = document.getElementById('daodream-messenger').classList.contains('daodream-messenger-active') - isShow ? daovoice('hide') : daovoice('show') - } - } else if (isChatHideShow) { - window.chatBtn = { - hide: () => { - daovoice('update', {},{ - launcher: { - disableLauncherIcon: true - } - }) - }, - show: () => { - daovoice('update', {}, { - launcher: { - disableLauncherIcon: false - } - }) - } - } - } - })() \ No newline at end of file diff --git a/layout/includes/third-party/chat/index.pug b/layout/includes/third-party/chat/index.pug index c534849..273d040 100644 --- a/layout/includes/third-party/chat/index.pug +++ b/layout/includes/third-party/chat/index.pug @@ -3,7 +3,5 @@ case theme.chat.use include ./chatra.pug when 'tidio' include ./tidio.pug - when 'daovoice' - include ./daovoice.pug when 'crisp' include ./crisp.pug \ No newline at end of file diff --git a/layout/includes/third-party/math/chartjs.pug b/layout/includes/third-party/math/chartjs.pug new file mode 100644 index 0000000..fb1554f --- /dev/null +++ b/layout/includes/third-party/math/chartjs.pug @@ -0,0 +1,91 @@ +- const { fontColor, borderColor, scale_ticks_backdropColor } = theme.chartjs + +script. + (() => { + const $chartjs = document.querySelectorAll('#article-container .chartjs-container') + if ($chartjs.length === 0) return + + const applyThemeDefaultsConfig = theme => { + if (theme === 'dark-mode') { + Chart.defaults.color = "!{fontColor.dark}" + Chart.defaults.borderColor = "!{borderColor.dark}" + Chart.defaults.scale.ticks.backdropColor = "!{scale_ticks_backdropColor.dark}" + } else { + Chart.defaults.color = "!{fontColor.light}" + Chart.defaults.borderColor = "!{borderColor.light}" + Chart.defaults.scale.ticks.backdropColor = "!{scale_ticks_backdropColor.light}" + } + } + + // Recursively traverse the config object and automatically apply theme-specific color schemes + const applyThemeConfig = (obj, theme) => { + if (typeof obj !== 'object' || obj === null) return + + Object.keys(obj).forEach(key => { + const value = obj[key] + // If the property is an object and has theme-specific options, apply them + if (typeof value === 'object' && value !== null) { + if (value[theme]) { + obj[key] = value[theme] // Apply the value for the current theme + } else { + // Recursively process child objects + applyThemeConfig(value, theme) + } + } + }) + } + + const runChartJS = () => { + window.loadChartJS = true + + Array.from($chartjs).forEach((item, index) => { + const chartSrc = item.firstElementChild + const chartID = item.getAttribute('data-chartjs-id') || ('chartjs-' + index) // Use custom ID or default ID + const width = item.getAttribute('data-width') + const existingCanvas = document.getElementById(chartID) + + // If a canvas already exists, remove it to avoid rendering duplicates + if (existingCanvas) { + existingCanvas.parentNode.remove() + } + + const chartDefinition = chartSrc.textContent + const canvas = document.createElement('canvas') + canvas.id = chartID + + const div = document.createElement('div') + div.className = 'chartjs-wrap' + + if (width) { + div.style.width = width + } + + div.appendChild(canvas) + chartSrc.insertAdjacentElement('afterend', div) + + const ctx = document.getElementById(chartID).getContext('2d') + + const config = JSON.parse(chartDefinition) + + const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark-mode' : 'light-mode' + + // Set default styles (initial setup) + applyThemeDefaultsConfig(theme) + + // Automatically traverse the config and apply dual-mode color schemes + applyThemeConfig(config, theme) + + new Chart(ctx, config) + }) + } + + const loadChartJS = () => { + window.loadChartJS ? runChartJS() : btf.getScript('!{url_for(theme.asset.chartjs)}').then(runChartJS) + } + + // Listen for theme change events + btf.addGlobalFn('themeChange', runChartJS, 'chartjs') + btf.addGlobalFn('encrypt', runChartJS, 'chartjs') + + window.pjax ? loadChartJS() : document.addEventListener('DOMContentLoaded', loadChartJS) + })() diff --git a/layout/includes/third-party/math/index.pug b/layout/includes/third-party/math/index.pug index 068a78f..217eb72 100644 --- a/layout/includes/third-party/math/index.pug +++ b/layout/includes/third-party/math/index.pug @@ -8,4 +8,7 @@ case theme.math.use include ./katex.pug if theme.mermaid.enable - include ./mermaid.pug \ No newline at end of file + include ./mermaid.pug + +if theme.chartjs.enable + include ./chartjs.pug \ No newline at end of file diff --git a/layout/includes/third-party/search/local-search.pug b/layout/includes/third-party/search/local-search.pug index af96ab0..e459a94 100644 --- a/layout/includes/third-party/search/local-search.pug +++ b/layout/includes/third-party/search/local-search.pug @@ -6,7 +6,7 @@ button.search-close-button i.fas.fa-times - #loading-database.is-center + #loading-database.text-center i.fas.fa-spinner.fa-pulse span= ' ' + _p("search.load_data") diff --git a/layout/includes/widget/card_author.pug b/layout/includes/widget/card_author.pug index c4f01d4..095f66f 100644 --- a/layout/includes/widget/card_author.pug +++ b/layout/includes/widget/card_author.pug @@ -1,5 +1,5 @@ if theme.aside.card_author.enable - .card-widget.card-info.is-center + .card-widget.card-info.text-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 diff --git a/package.json b/package.json index b03744e..29d5e6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hexo-theme-butterfly", - "version": "5.0.0", + "version": "5.1.0", "description": "A Simple and Card UI Design theme for Hexo", "main": "package.json", "scripts": { diff --git a/plugins.yml b/plugins.yml index 9b4bd9a..57930e0 100644 --- a/plugins.yml +++ b/plugins.yml @@ -8,8 +8,8 @@ activate_power_mode: version: 1.1.4 algolia_search: name: algoliasearch - file: dist/algoliasearch-lite.umd.js - version: 5.7.0 + file: dist/lite/builds/browser.umd.js + version: 5.9.1 aplayer_css: name: aplayer file: dist/APlayer.min.css @@ -42,6 +42,10 @@ canvas_ribbon: name: butterfly-extsrc file: dist/canvas-ribbon.min.js version: 1.1.4 +chartjs: + name: chart.js + file: dist/chart.umd.min.js + version: 4.4.5 clickShowText: name: butterfly-extsrc file: dist/click-show-text.min.js @@ -107,7 +111,7 @@ instantpage: instantsearch: name: instantsearch.js file: dist/instantsearch.production.min.js - version: 4.74.2 + version: 4.75.1 katex: name: katex file: dist/katex.min.css @@ -133,7 +137,7 @@ medium_zoom: mermaid: name: mermaid file: dist/mermaid.min.js - version: 11.2.1 + version: 11.3.0 meting_js: name: butterfly-extsrc file: metingjs/dist/Meting.min.js diff --git a/scripts/common/postDesc.js b/scripts/common/postDesc.js new file mode 100644 index 0000000..e20e86e --- /dev/null +++ b/scripts/common/postDesc.js @@ -0,0 +1,36 @@ +'use strict' + +const { stripHTML, truncate } = require('hexo-util') + +// Truncates the given content to a specified length, removing HTML tags and replacing newlines with spaces. +const truncateContent = (content, length) => { + return truncate(stripHTML(content), { length, separator: ' ' }).replace(/\n/g, ' ') +} + +// Generates a post description based on the provided data and theme configuration. +const postDesc = (data, hexo) => { + const { description, content, postDesc } = data + + if (postDesc) return postDesc + + const { length, method } = hexo.theme.config.index_post_content + + if (method === false) return + + let result + switch (method) { + case 1: + result = description + break + case 2: + result = description || truncateContent(content, length) + break + default: + result = truncateContent(content, length) + } + + data.postDesc = result + return result +} + +module.exports = { truncateContent, postDesc } diff --git a/scripts/events/merge_config.js b/scripts/events/merge_config.js index 07e8bce..fe04871 100644 --- a/scripts/events/merge_config.js +++ b/scripts/events/merge_config.js @@ -341,7 +341,7 @@ hexo.extend.filter.register('before_generate', () => { user_id: null, pageSize: 10, order_by: 'social', - lang: 'zh_TW' + lang: 'en_US' }, twikoo: { envId: null, @@ -380,9 +380,6 @@ hexo.extend.filter.register('before_generate', () => { tidio: { public_key: null }, - daovoice: { - app_id: null - }, crisp: { website_id: null }, @@ -512,6 +509,21 @@ hexo.extend.filter.register('before_generate', () => { dark: 'dark' } }, + chartjs: { + enable: false, + fontColor: { + light: 'rgba(0, 0, 0, 0.8)', + dark: 'rgba(255, 255, 255, 0.8)' + }, + borderColor: { + light: 'rgba(0, 0, 0, 0.1)', + dark: 'rgba(255, 255, 255, 0.2)' + }, + scale_ticks_backdropColor: { + light: 'transparent', + dark: 'transparent' + } + }, note: { style: 'flat', icons: true, diff --git a/scripts/helpers/page.js b/scripts/helpers/page.js index 2bdcffd..ae24746 100644 --- a/scripts/helpers/page.js +++ b/scripts/helpers/page.js @@ -1,10 +1,13 @@ 'use strict' -const { stripHTML, prettyUrls, truncate } = require('hexo-util') +const { truncateContent, postDesc } = require('../common/postDesc') +const { prettyUrls } = require('hexo-util') const crypto = require('crypto') -hexo.extend.helper.register('truncate', (content, length) => { - return truncate(stripHTML(content), { length, separator: ' ' }).replace(/\n/g, ' ') +hexo.extend.helper.register('truncate', truncateContent) + +hexo.extend.helper.register('postDesc', data => { + return postDesc(data, hexo) }) hexo.extend.helper.register('cloudTags', function (options = {}) { @@ -82,7 +85,7 @@ hexo.extend.helper.register('getBgPath', path => { const absoluteUrlPattern = /^(?:[a-z][a-z\d+.-]*:)?\/\//i const relativeUrlPattern = /^(\.\/|\.\.\/|\/|[^/]+\/).*$/ - const colorPattern = /^(#|rgb|rgba|hsl|hsla|linear-gradient|radial-gradient)/i + const colorPattern = /^(#|rgb|rgba|hsl|hsla)/i if (colorPattern.test(path)) { return `background-color: ${path};` diff --git a/scripts/helpers/related_post.js b/scripts/helpers/related_post.js index 46f4381..8059dbe 100644 --- a/scripts/helpers/related_post.js +++ b/scripts/helpers/related_post.js @@ -1,3 +1,4 @@ +/* eslint-disable camelcase */ /** * Butterfly * Related Posts @@ -6,12 +7,15 @@ 'use strict' +const { postDesc } = require('../common/postDesc') + hexo.extend.helper.register('related_posts', function (currentPost, allPosts) { let relatedPosts = [] const tagsData = currentPost.tags tagsData.length && tagsData.forEach(function (tag) { allPosts.forEach(function (post) { if (currentPost.path !== post.path && isTagRelated(tag.name, post.tags)) { + const getPostDesc = post.postDesc || postDesc(post, hexo) const relatedPost = { title: post.title, path: post.path, @@ -19,7 +23,8 @@ hexo.extend.helper.register('related_posts', function (currentPost, allPosts) { cover_type: post.cover_type, weight: 1, updated: post.updated, - created: post.date + created: post.date, + postDesc: getPostDesc } const index = findItem(relatedPosts, 'path', post.path) if (index !== -1) { @@ -50,20 +55,27 @@ hexo.extend.helper.register('related_posts', function (currentPost, allPosts) { result += '