diff --git a/README.md b/README.md index e0189ba..2dfcfab 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ npm i hexo-theme-butterfly - [x] WordCount - [x] Related articles - [x] Displays outdated notice for a post -- [x] Share (AddThis/Sharejs/Addtoany) +- [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/messenger) diff --git a/README_CN.md b/README_CN.md index 441cd79..2b3c3b6 100644 --- a/README_CN.md +++ b/README_CN.md @@ -76,7 +76,7 @@ theme: butterfly - [x] 顯示字數統計 - [x] 顯示相關文章 - [x] 過期文章提醒 -- [x] 多種分享系統(AddThis/Sharejs/Addtoany) +- [x] 多種分享系統(Sharejs/Addtoany) - [X] 多種評論系統(Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/artalk) - [x] 支持雙評論部署 - [x] 多種在線聊天(Chatra/Tidio/Daovoice/Crisp/messenger) diff --git a/_config.yml b/_config.yml index 5c1b8d1..3c4f5c5 100644 --- a/_config.yml +++ b/_config.yml @@ -264,6 +264,10 @@ aside: post_count: true last_push_date: true sort_order: # Don't modify the setting unless you know how it works + card_post_series: + enable: true + orderBy: 'date' # Order by title or date + order: -1 # Sort of order. 1, asc for ascending; -1, desc for descending # busuanzi count for PV / UV in site # 訪問人數 @@ -381,12 +385,6 @@ docsearch: # Share System (分享) # -------------------------------------- -# AddThis -# https://www.addthis.com/ -addThis: - enable: false - pubid: - # Share.js # https://github.com/overtrue/share.js sharejs: @@ -651,7 +649,7 @@ mask: footer: true # the position of bottom right button/default unit: px (右下角按鈕距離底部的距離/默認單位為px) -rightside-bottom: +rightside_bottom: # Enter transitions (開啓網頁進入效果) enter_transitions: true @@ -796,6 +794,13 @@ fancybox: true # Tag Plugins settings (標籤外掛) # -------------------------------------- +# series (系列文章) +series: + enable: true + orderBy: 'title' # Order by title or date + order: 1 # Sort of order. 1, asc for ascending; -1, desc for descending + number: true + # abcjs (樂譜渲染) # See https://github.com/paulrosen/abcjs abcjs: diff --git a/languages/default.yml b/languages/default.yml index fea921e..0f80672 100644 --- a/languages/default.yml +++ b/languages/default.yml @@ -15,7 +15,6 @@ page: card_post_count: comments -sticky: Sticky no_title: No title post: @@ -83,6 +82,7 @@ aside: link: link code: code card_toc: Catalog + card_post_series: Series date_suffix: just: Just diff --git a/languages/en.yml b/languages/en.yml index 1cc937c..3c14a5d 100644 --- a/languages/en.yml +++ b/languages/en.yml @@ -15,7 +15,6 @@ page: card_post_count: comments -sticky: Sticky no_title: No title post: @@ -83,6 +82,7 @@ aside: link: link code: code card_toc: Catalog + card_post_series: Series date_suffix: just: Just diff --git a/languages/zh-CN.yml b/languages/zh-CN.yml index 94f85cd..3cd8964 100644 --- a/languages/zh-CN.yml +++ b/languages/zh-CN.yml @@ -15,7 +15,6 @@ page: card_post_count: 条评论 -sticky: 置顶 no_title: 无题 post: @@ -84,6 +83,7 @@ aside: link: 链接 code: 代码 card_toc: 目录 + card_post_series: 系列文章 date_suffix: just: 刚刚 diff --git a/languages/zh-TW.yml b/languages/zh-TW.yml index 9801d16..b2f8f68 100644 --- a/languages/zh-TW.yml +++ b/languages/zh-TW.yml @@ -15,7 +15,6 @@ page: card_post_count: 條評論 -sticky: 置頂 no_title: 無題 post: @@ -84,6 +83,7 @@ aside: link: 連結 code: 程式碼 card_toc: 目錄 + card_post_series: 系列文章 date_suffix: just: 剛剛 diff --git a/layout/includes/mixins/post-ui.pug b/layout/includes/mixins/post-ui.pug index 970b5fc..200e900 100644 --- a/layout/includes/mixins/post-ui.pug +++ b/layout/includes/mixins/post-ui.pug @@ -19,13 +19,11 @@ mixin postUI(posts) else div.post-bg(style=`background: ${post_cover}`) .recent-post-info(class=no_cover) - a.article-title(href=url_for(link) title=title)= title - .article-meta-wrap + a.article-title(href=url_for(link) title=title) if (is_home() && (article.top || article.sticky > 0)) - span.article-meta - i.fas.fa-thumbtack.sticky - span.sticky= _p('sticky') - span.article-meta-separator | + 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') diff --git a/layout/includes/post/reward.pug b/layout/includes/post/reward.pug index 71daa98..fb55946 100644 --- a/layout/includes/post/reward.pug +++ b/layout/includes/post/reward.pug @@ -1,7 +1,7 @@ .post-reward .reward-button i.fas.fa-qrcode - = ' ' + _p('donate') + = theme.reward.text || _p('donate') .reward-main ul.reward-all each item in theme.reward.QR_code diff --git a/layout/includes/third-party/share/add-this.pug b/layout/includes/third-party/share/add-this.pug deleted file mode 100644 index ab44267..0000000 --- a/layout/includes/third-party/share/add-this.pug +++ /dev/null @@ -1,2 +0,0 @@ -.addthis_inline_share_toolbox -script(src=`//s7.addthis.com/js/300/addthis_widget.js#pubid=${theme.addThis.pubid}` async) \ No newline at end of file diff --git a/layout/includes/third-party/share/index.pug b/layout/includes/third-party/share/index.pug index f28ceab..f8122c0 100644 --- a/layout/includes/third-party/share/index.pug +++ b/layout/includes/third-party/share/index.pug @@ -1,7 +1,5 @@ .post_share - if theme.addThis.enable - !=partial('includes/third-party/share/add-this', {}, {cache: true}) - else if theme.sharejs.enable + if theme.sharejs.enable include ./share-js.pug else if theme.addtoany.enable !=partial('includes/third-party/share/addtoany', {}, {cache: true}) diff --git a/layout/includes/widget/card_post_series.pug b/layout/includes/widget/card_post_series.pug new file mode 100644 index 0000000..c216929 --- /dev/null +++ b/layout/includes/widget/card_post_series.pug @@ -0,0 +1,21 @@ +if theme.aside.card_post_series.enable + - const array = fragment_cache('seriesArr', groupPosts) + .card-widget.card-post-series + .item-headline + i.fa-solid.fa-layer-group + span= _p('aside.card_post_series') + .aside-list + each item in array[page.series] + - const { path, title = _p('no_title'), cover, cover_type, date:dateA } = item + - let link = url_for(path) + - let no_cover = cover === false || !theme.cover.aside_enable ? 'no-cover' : '' + .aside-list-item(class=no_cover) + if cover && theme.cover.aside_enable + a.thumbnail(href=link title=title) + if cover_type === 'img' + img(src=url_for(cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title) + else + div(style=`background: ${cover}`) + .content + a.title(href=link title=title)= title + time(datetime=date_xml(dateA) title=_p('post.created') + ' ' + full_date(dateA)) #[=date(dateA, config.date_format)] diff --git a/layout/includes/widget/index.pug b/layout/includes/widget/index.pug index 175fcdc..388ea1c 100644 --- a/layout/includes/widget/index.pug +++ b/layout/includes/widget/index.pug @@ -13,6 +13,8 @@ .sticky_layout if showToc include ./card_post_toc.pug + if page.series + include ./card_post_series.pug !=partial('includes/widget/card_recent_post', {}, {cache: true}) !=partial('includes/widget/card_ad', {}, {cache: true}) else diff --git a/plugins.yml b/plugins.yml index ef96ad0..e006d32 100644 --- a/plugins.yml +++ b/plugins.yml @@ -1,11 +1,11 @@ algolia_search: name: algoliasearch file: dist/algoliasearch-lite.umd.js - version: 4.17.1 + version: 4.18.0 instantsearch: name: instantsearch.js file: dist/instantsearch.production.min.js - version: 4.56.1 + version: 4.56.3 pjax: name: pjax file: pjax.min.js @@ -64,16 +64,16 @@ katex: name: katex file: dist/katex.min.css other_name: KaTeX - version: 0.16.7 + version: 0.16.8 katex_copytex: name: katex file: dist/contrib/copy-tex.min.js other_name: KaTeX - version: 0.16.7 + version: 0.16.8 mermaid: name: mermaid file: dist/mermaid.min.js - version: 10.2.2 + version: 10.2.3 canvas_ribbon: name: butterfly-extsrc file: dist/canvas-ribbon.min.js @@ -202,12 +202,12 @@ docsearch_js: name: '@docsearch/js' other_name: docsearch-js file: dist/umd/index.js - version: 3.4.0 + version: 3.5.1 docsearch_css: name: '@docsearch/css' other_name: docsearch-css file: dist/style.css - version: 3.4.0 + version: 3.5.1 abcjs_basic_js: name: abcjs file: dist/abcjs-basic-min.js diff --git a/scripts/helpers/series.js b/scripts/helpers/series.js new file mode 100644 index 0000000..e1c9338 --- /dev/null +++ b/scripts/helpers/series.js @@ -0,0 +1,22 @@ +'use strict' + +hexo.extend.helper.register('groupPosts', function () { + const getGroupArray = array => { + const groups = {} + array.forEach(item => { + const Key = item.series + if (!Key) return + groups[Key] = groups[Key] || [] + groups[Key].push(item) + }) + return groups + } + + const sortPosts = posts => { + const { orderBy = 'date', order = 1 } = this.theme.aside.card_post_series + if (orderBy === 'title') return posts.sort('title', order) + return posts.sort('date', order) + } + + return getGroupArray(sortPosts(this.site.posts)) +}) diff --git a/scripts/tag/button.js b/scripts/tag/button.js index 33a0e53..624cdd3 100644 --- a/scripts/tag/button.js +++ b/scripts/tag/button.js @@ -9,17 +9,9 @@ const urlFor = require('hexo-util').url_for.bind(hexo) -function btn (args) { +const btn = args => { args = args.join(' ').split(',') - let url = args[0] || '' - let text = args[1] || '' - let icon = args[2] || '' - let option = args[3] || '' - - url = url.trim() - text = text.trim() - icon = icon.trim() - option = option.trim() + const [url = '', text = '', icon = '', option = ''] = args.map(arg => arg.trim()) return `${icon.length ? `` : ''}${text.length ? `${text}` : ''}` diff --git a/scripts/tag/gallery.js b/scripts/tag/gallery.js index 632c514..14cdee3 100644 --- a/scripts/tag/gallery.js +++ b/scripts/tag/gallery.js @@ -10,7 +10,7 @@ const urlFor = require('hexo-util').url_for.bind(hexo) -function gallery (args, content) { +const gallery = (args, content) => { const { data, languages } = hexo.theme.i18n args = args.join(' ').split(',') let rowHeight, limit, lazyload, type, dataStr @@ -47,19 +47,18 @@ function gallery (args, content) { ` } -function galleryGroup (args) { - const name = args[0] - const descr = args[1] - const url = urlFor(args[2]) - const img = urlFor(args[3]) +const galleryGroup = args => { + const [name, descr, url, img] = args + const imgUrl = urlFor(img) + const urlLink = urlFor(url) return ` ` diff --git a/scripts/tag/hide.js b/scripts/tag/hide.js index ccf9365..a788172 100644 --- a/scripts/tag/hide.js +++ b/scripts/tag/hide.js @@ -16,51 +16,46 @@ 'use strict' -function hideInline (args) { - args = args.join(' ').split(',') - const content = args[0] - const display = args[1] || 'Click' - const bg = args[2] || false - const color = args[3] || false - let group = 'style="' +const parseArgs = args => { + return args.join(' ').split(',') +} - if (bg) group += `background-color: ${bg};` - if (color) group += `color: ${color}` - group += '"' +const generateStyle = (bg, color) => { + let style = 'style="' + if (bg) { + style += `background-color: ${bg};` + } + if (color) { + style += `color: ${color}` + } + style += '"' + return style +} + +const hideInline = args => { + const [content, display = 'Click', bg = false, color = false] = parseArgs(args) + const group = generateStyle(bg, color) return `${content}` } -function hideBlock (args, content) { - args = args.join(' ').split(',') - const display = args[0] || 'Click' - const bg = args[1] || false - const color = args[2] || false - let group = 'style="' - - if (bg) group += `background-color: ${bg};` - if (color) group += `color: ${color}` - group += '"' +const hideBlock = (args, content) => { + const [display = 'Click', bg = false, color = false] = parseArgs(args) + const group = generateStyle(bg, color) return `
${hexo.render.renderSync({ text: content, engine: 'markdown' })}
` } -function hideToggle (args, content) { - args = args.join(' ').split(',') - const display = args[0] - const bg = args[1] || false - const color = args[2] || false - let group = 'style="' +const hideToggle = (args, content) => { + const [display, bg = false, color = false] = parseArgs(args) + const group = generateStyle(bg, color) let border = '' if (bg) { border = `style="border: 1px solid ${bg}"` - group += `background-color: ${bg};` } - if (color) group += `color: ${color}` - group += '"' return `
${display}
${hexo.render.renderSync({ text: content, engine: 'markdown' })}
` } diff --git a/scripts/tag/inlineImg.js b/scripts/tag/inlineImg.js index 9bcbfdb..753add0 100644 --- a/scripts/tag/inlineImg.js +++ b/scripts/tag/inlineImg.js @@ -1,17 +1,19 @@ /** * inlineImg 圖片 - * {% inlineImg src height %} + * @param {Array} args 圖片名稱和高度 + * @param {string} args[0] 圖片名稱 + * @param {number} args[1] 圖片高度 + * @returns {string} 圖片標籤 */ 'use strict' const urlFor = require('hexo-util').url_for.bind(hexo) -function inlineImg (args) { - const img = args[0] - const height = args[1] ? `style="height:${args[1]}"` : '' - - return `` +const inlineImg = ([img, height = '']) => { + const heightStyle = height ? `style="height:${height}"` : '' + const src = urlFor(img) + return `` } hexo.extend.tag.register('inlineImg', inlineImg, { ends: false }) diff --git a/scripts/tag/label.js b/scripts/tag/label.js index 877c909..4c9e692 100644 --- a/scripts/tag/label.js +++ b/scripts/tag/label.js @@ -6,10 +6,8 @@ 'use strict' -function addLabel (args, content) { - const text = args[0] - const className = args[1] || 'default' - +const addLabel = args => { + const [text, className = 'default'] = args return `${text} ` } diff --git a/scripts/tag/mermaid.js b/scripts/tag/mermaid.js index 237b7ee..ba25c0f 100644 --- a/scripts/tag/mermaid.js +++ b/scripts/tag/mermaid.js @@ -8,7 +8,7 @@ const { escapeHTML } = require('hexo-util') -function mermaid (args, content) { +const mermaid = (args, content) => { return `
` diff --git a/scripts/tag/note.js b/scripts/tag/note.js index aa19129..125bc61 100644 --- a/scripts/tag/note.js +++ b/scripts/tag/note.js @@ -6,10 +6,10 @@ 'use strict' -function postNote (args, content) { +const postNote = (args, content) => { const styleConfig = hexo.theme.config.note.style - const lastArgs = args[args.length - 1] - if (!(lastArgs === 'flat' || lastArgs === 'modern' || lastArgs === 'simple' || lastArgs === 'disabled')) { + const noteTag = ['flat', 'modern', 'simple', 'disabled'] + if (!noteTag.includes(args[args.length - 1])) { args.push(styleConfig) } diff --git a/scripts/tag/score.js b/scripts/tag/score.js index 3157245..441247b 100644 --- a/scripts/tag/score.js +++ b/scripts/tag/score.js @@ -3,20 +3,20 @@ * {% score %} */ -'use strict'; +'use strict' -function score(args, content) { - function escapeHtmlTags(s) { - let lookup = { - '&': "&", - '"': """, - '\'': "'", - '<': "<", - '>': ">" - }; - return s.replace(/[&"'<>]/g, c => lookup[c]); +const score = (args, content) => { + const escapeHtmlTags = s => { + const lookup = { + '&': '&', + '"': '"', + '\'': ''', + '<': '<', + '>': '>' } - return `
${escapeHtmlTags(content)}
`; + return s.replace(/[&"'<>]/g, c => lookup[c]) + } + return `
${escapeHtmlTags(content)}
` } -hexo.extend.tag.register('score', score, {ends: true}); +hexo.extend.tag.register('score', score, { ends: true }) diff --git a/scripts/tag/series.js b/scripts/tag/series.js new file mode 100644 index 0000000..4a901df --- /dev/null +++ b/scripts/tag/series.js @@ -0,0 +1,69 @@ +/** + * series plugin + * Syntax: + * {% series [series name] %} + * Usage: + * {% series %} + * {% series series1 %} + */ + +'use strict' + +const urlFor = require('hexo-util').url_for.bind(hexo) +const groups = {} + +hexo.extend.filter.register('before_post_render', data => { + if (!hexo.theme.config.series.enable) return data + const { layout, series } = data + if (layout === 'post' && series) { + groups[series] = groups[series] || [] + groups[series].push({ + title: data.title, + path: data.path, + date: data.date.unix() + }) + } + return data +}) + +function series (args) { + const { series } = hexo.theme.config + if (!series.enable) { + hexo.log.warn('Series plugin is disabled in the theme config') + return '' + } + + const seriesArr = args.length ? groups[args[0]] : groups[this.series] + + if (!seriesArr) { + hexo.log.warn(`There is no series named "${args[0]}"`) + return '' + } + + const isAsc = (series.order || 1) === 1 // 1: asc, -1: desc + const isSortByTitle = series.orderBy === 'title' + + const compareFn = (a, b) => { + const itemA = isSortByTitle ? a.title.toUpperCase() : a.date + const itemB = isSortByTitle ? b.title.toUpperCase() : b.date + + if (itemA < itemB) { + return isAsc ? -1 : 1 + } + if (itemA > itemB) { + return isAsc ? 1 : -1 + } + return 0 + } + + seriesArr.sort(compareFn) + + let result = '' + seriesArr.forEach(ele => { + result += `
  • ${ele.title}
  • ` + }) + + return series.number ? `
      ${result}
    ` : `` +} + +hexo.extend.tag.register('series', series, { ends: false }) diff --git a/scripts/tag/tabs.js b/scripts/tag/tabs.js index 050aeee..6dc8bfa 100644 --- a/scripts/tag/tabs.js +++ b/scripts/tag/tabs.js @@ -6,13 +6,11 @@ 'use strict' -function postTabs (args, content) { +const postTabs = (args, content) => { const tabBlock = /\n([\w\W\s\S]*?)/g - args = args.join(' ').split(',') const tabName = args[0] const tabActive = Number(args[1]) || 0 - const matches = [] let match let tabId = 0 @@ -22,8 +20,7 @@ function postTabs (args, content) { !tabName && hexo.log.warn('Tabs block must have unique name!') while ((match = tabBlock.exec(content)) !== null) { - matches.push(match[1]) - matches.push(match[2]) + matches.push(match[1], match[2]) } for (let i = 0; i < matches.length; i += 2) { diff --git a/scripts/tag/timeline.js b/scripts/tag/timeline.js index 6c87a6b..6dde854 100644 --- a/scripts/tag/timeline.js +++ b/scripts/tag/timeline.js @@ -5,15 +5,15 @@ 'use strict' -function timeLineFn (args, content) { +const timeLineFn = (args, content) => { const tlBlock = /\n([\w\W\s\S]*?)/g let result = '' let color = '' + let text = '' if (args.length) { - args = args.join(' ').split(',') - color = args[1] - const mdContent = hexo.render.renderSync({ text: args[0], engine: 'markdown' }) + [text, color] = args.join(' ').split(',') + const mdContent = hexo.render.renderSync({ text, engine: 'markdown' }) result += `
    ${mdContent}
    ` } diff --git a/source/css/_layout/reward.styl b/source/css/_layout/reward.styl index e570967..4043aa2 100644 --- a/source/css/_layout/reward.styl +++ b/source/css/_layout/reward.styl @@ -15,6 +15,9 @@ color: var(--btn-color) cursor: pointer + i + margin-right: 5px + &:hover .reward-button background: var(--btn-hover-color) diff --git a/source/css/_page/homepage.styl b/source/css/_page/homepage.styl index 9269f97..e81311a 100644 --- a/source/css/_page/homepage.styl +++ b/source/css/_page/homepage.styl @@ -62,6 +62,11 @@ transition: all .2s ease-in-out -webkit-line-clamp: 2 + .sticky + margin-right: 10px + color: $sticky-color + transform: rotate(45deg) + +maxWidth768() font-size: 1.43em @@ -76,9 +81,6 @@ & > .post-meta-date cursor: default - .sticky - color: $sticky-color - i margin: 0 4px 0 0 diff --git a/source/css/_tags/tabs.styl b/source/css/_tags/tabs.styl index 90ede9c..a4a30be 100644 --- a/source/css/_tags/tabs.styl +++ b/source/css/_tags/tabs.styl @@ -61,9 +61,9 @@ animation: tabshow .5s .tab-to-top - position: relative + position: absolute + right: 15px display: block - margin: 0 0 0 auto color: $tab-to-top-color @keyframes tabshow diff --git a/source/css/var.styl b/source/css/var.styl index 04d4326..4c27eeb 100644 --- a/source/css/var.styl +++ b/source/css/var.styl @@ -101,7 +101,7 @@ $tag-hide-toggle-bg = #f0f0f0 $preloader-bg = #37474f $preloader-word-color = #fff // rightside -$rightside-bottom = hexo-config('rightside-bottom') ? convert(hexo-config('rightside-bottom')) : 40px +$rightside-bottom = hexo-config('rightside_bottom') ? convert(hexo-config('rightside_bottom')) : 40px // fireworks $fireworks-zIndex = hexo-config('fireworks.zIndex') ? hexo-config('fireworks.zIndex') : 99999 // Tag Plugins - Note