mirror of
https://github.com/jerryc127/hexo-theme-butterfly.git
synced 2026-04-10 13:07:06 +08:00
breaking changes: 更改 rightside-bottom 為 rightside_bottom
feat: 置頂圖標改為在標題左側 feat: 可配置打賞按鈕的文字 feat: 側邊欄增加 系列文章顯示 feat: 增加 series 系列文章 標籤外掛 feat: 移除 addthis 分享 improvement: 代碼優化 improvement: tabs 標籤外掛的回到頂部箭頭位置調整 improvement: 更新 plugin.yml
This commit is contained in:
22
scripts/helpers/series.js
Normal file
22
scripts/helpers/series.js
Normal file
@@ -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))
|
||||
})
|
||||
@@ -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 `<a class="btn-beautify ${option}" href="${urlFor(url)}"
|
||||
title="${text}">${icon.length ? `<i class="${icon}"></i>` : ''}${text.length ? `<span>${text}</span>` : ''}</a>`
|
||||
|
||||
@@ -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) {
|
||||
</div>`
|
||||
}
|
||||
|
||||
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 `
|
||||
<figure class="gallery-group">
|
||||
<img class="gallery-group-img no-lightbox" src='${img}' alt="Group Image Gallery">
|
||||
<img class="gallery-group-img no-lightbox" src='${imgUrl}' alt="Group Image Gallery">
|
||||
<figcaption>
|
||||
<div class="gallery-group-name">${name}</div>
|
||||
<p>${descr}</p>
|
||||
<a href='${url}'></a>
|
||||
<a href='${urlLink}'></a>
|
||||
</figcaption>
|
||||
</figure>
|
||||
`
|
||||
|
||||
@@ -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 `<span class="hide-inline"><button type="button" class="hide-button" ${group}>${display}
|
||||
</button><span class="hide-content">${content}</span></span>`
|
||||
}
|
||||
|
||||
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 `<div class="hide-block"><button type="button" class="hide-button" ${group}>${display}
|
||||
</button><div class="hide-content">${hexo.render.renderSync({ text: content, engine: 'markdown' })}</div></div>`
|
||||
}
|
||||
|
||||
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 `<details class="toggle" ${border}><summary class="toggle-button" ${group}>${display}</summary><div class="toggle-content">${hexo.render.renderSync({ text: content, engine: 'markdown' })}</div></details>`
|
||||
}
|
||||
|
||||
@@ -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 `<img class="inline-img" src="${urlFor(img)}" ${height}/>`
|
||||
const inlineImg = ([img, height = '']) => {
|
||||
const heightStyle = height ? `style="height:${height}"` : ''
|
||||
const src = urlFor(img)
|
||||
return `<img class="inline-img" src="${src}" ${heightStyle} />`
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('inlineImg', inlineImg, { ends: false })
|
||||
|
||||
@@ -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 `<mark class="hl-label ${className}">${text}</mark> `
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
const { escapeHTML } = require('hexo-util')
|
||||
|
||||
function mermaid (args, content) {
|
||||
const mermaid = (args, content) => {
|
||||
return `<div class="mermaid-wrap"><pre class="mermaid-src" hidden>
|
||||
${escapeHTML(content)}
|
||||
</pre></div>`
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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 `<div class="abc-music-sheet">${escapeHtmlTags(content)}</div>`;
|
||||
return s.replace(/[&"'<>]/g, c => lookup[c])
|
||||
}
|
||||
return `<div class="abc-music-sheet">${escapeHtmlTags(content)}</div>`
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('score', score, {ends: true});
|
||||
hexo.extend.tag.register('score', score, { ends: true })
|
||||
|
||||
69
scripts/tag/series.js
Normal file
69
scripts/tag/series.js
Normal file
@@ -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 += `<li><a href="${urlFor(ele.path)}" title="${ele.title}">${ele.title}</a></li>`
|
||||
})
|
||||
|
||||
return series.number ? `<ol>${result}</ol>` : `<ul>${result}</ul>`
|
||||
}
|
||||
|
||||
hexo.extend.tag.register('series', series, { ends: false })
|
||||
@@ -6,13 +6,11 @@
|
||||
|
||||
'use strict'
|
||||
|
||||
function postTabs (args, content) {
|
||||
const postTabs = (args, content) => {
|
||||
const tabBlock = /<!--\s*tab (.*?)\s*-->\n([\w\W\s\S]*?)<!--\s*endtab\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) {
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
|
||||
'use strict'
|
||||
|
||||
function timeLineFn (args, content) {
|
||||
const timeLineFn = (args, content) => {
|
||||
const tlBlock = /<!--\s*timeline (.*?)\s*-->\n([\w\W\s\S]*?)<!--\s*endtimeline\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 += `<div class='timeline-item headline'><div class='timeline-item-title'><div class='item-circle'>${mdContent}</div></div></div>`
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user