diff --git a/README.md b/README.md index 1b3bc74..11df54e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
A simple, delicate, and modern theme for the static site generator Hexo.
-Preview | +Preview | Documentation | Download
@@ -51,6 +51,13 @@ Share plugins - [Share.js](http://ppoffice.github.io/hexo-theme-icarus/Plugins/Share/share-js-share-plugin/) - [ShareThis](http://ppoffice.github.io/hexo-theme-icarus/Plugins/Share/sharethis-share-plugin/) +Donation Buttons + +- [Alipay](http://ppoffice.github.io/hexo-theme-icarus/Plugins/Donation/making-money-off-your-blog-with-donation-buttons/#Alipay) +- [Wechat](http://ppoffice.github.io/hexo-theme-icarus/Plugins/Donation/making-money-off-your-blog-with-donation-buttons/#Wechat) +- [Paypal](http://ppoffice.github.io/hexo-theme-icarus/Plugins/Donation/making-money-off-your-blog-with-donation-buttons/#Paypal) +- [Patreon](http://ppoffice.github.io/hexo-theme-icarus/Plugins/Donation/making-money-off-your-blog-with-donation-buttons/#Patreon) + Other plugins - [Hexo Tag Plugin](http://ppoffice.github.io/hexo-theme-icarus/Configuration/Posts/hexo-built-in-tag-helpers/) @@ -60,7 +67,7 @@ Other plugins **Rich Code Highlight Theme Choices** -Icarus directly import code highlight themes from the [highlight.js](https://highlightjs.org/) package, and makes more than +Icarus directly import code highlight themes from the [highlight.js](https://highlightjs.org/) package, and makes more than 70 highlight themes available to you. @@ -73,7 +80,7 @@ Icarus directly import code highlight themes from the [highlight.js](https://hig **Elastic Theme Configuration** -In addition to the minimalistic and easy-to-understand configuration design, Icarus allows you to set configurations on a +In addition to the minimalistic and easy-to-understand configuration design, Icarus allows you to set configurations on a per-page basis with the ability to merge and override partial configurations.
diff --git a/includes/common/ConfigGenerator.js b/includes/common/ConfigGenerator.js index ab218be..961b09e 100644 --- a/includes/common/ConfigGenerator.js +++ b/includes/common/ConfigGenerator.js @@ -32,6 +32,28 @@ const YAML_SCHEMA = new Schema({ ] }); +function appendDoc(spec, defaults) { + if (defaults === null) { + return null; + } + if (is.array(defaults) && spec.hasOwnProperty('*')) { + return defaults.map(value => appendDoc(spec['*'], value)); + } else if (is.object(defaults)) { + const _defaults = {}; + for (let key in defaults) { + if (spec.hasOwnProperty(key) && spec[key].hasOwnProperty(doc)) { + let i = 0; + for (let line of spec[key][doc].split('\n')) { + _defaults['#' + key + i++] = line; + } + } + _defaults[key] = appendDoc(spec.hasOwnProperty(key) ? spec[key] : {}, defaults[key]); + } + return _defaults; + } + return defaults; +} + function generate(spec, parentConfig = null) { if (!is.spec(spec)) { return UNDEFINED; @@ -40,7 +62,7 @@ function generate(spec, parentConfig = null) { return UNDEFINED; } if (spec.hasOwnProperty(defaultValue)) { - return spec[defaultValue]; + return appendDoc(spec, spec[defaultValue]); } const types = is.array(spec[type]) ? spec[type] : [spec[type]]; if (types.includes('object')) { @@ -54,16 +76,10 @@ function generate(spec, parentConfig = null) { if (defaults === UNDEFINED) { defaults = {}; } - if (spec[key].hasOwnProperty(doc)) { - let i = 0; - for (let line of spec[key][doc].split('\n')) { - defaults['#' + key + i++] = line; - } - } defaults[key] = value; } } - return defaults; + return appendDoc(spec, defaults); } else if (types.includes('array') && spec.hasOwnProperty('*')) { return [generate(spec['*'], {})]; } diff --git a/includes/specs/config.spec.js b/includes/specs/config.spec.js index 8812794..57ce280 100644 --- a/includes/specs/config.spec.js +++ b/includes/specs/config.spec.js @@ -17,6 +17,7 @@ module.exports = { article: require('./article.spec'), search: require('./search.spec'), comment: require('./comment.spec'), + donate: require('./donate.spec'), share: require('./share.spec'), sidebar: require('./sidebar.spec'), widgets: require('./widgets.spec'), diff --git a/includes/specs/donate.spec.js b/includes/specs/donate.spec.js new file mode 100644 index 0000000..ed13e5f --- /dev/null +++ b/includes/specs/donate.spec.js @@ -0,0 +1,72 @@ +const { doc, type, defaultValue, required, requires, format } = require('../common/utils').descriptors; + +const DEFAULT_DONATE = [ + { + type: 'alipay', + qrcode: '' + }, + { + type: 'wechat', + qrcode: '' + }, + { + type: 'paypal', + business: '', + currency_code: 'USD' + }, + { + type: 'patreon', + url: '' + } +]; + +const QrcodeSpec = { + qrcode: { + [type]: 'string', + [doc]: 'Qrcode image URL', + [required]: true, + [requires]: donate => donate.type === 'alipay' || donate.type === 'wechat' + } +}; + +const PaypalSpec = { + business: { + [type]: 'string', + [doc]: 'Paypal business ID or email address', + [required]: true, + [requires]: donate => donate.type === 'paypal' + }, + currency_code: { + [type]: 'string', + [doc]: 'Currency code', + [required]: true, + [requires]: donate => donate.type === 'paypal' + } +}; + +const PatreonSpec = { + url: { + [type]: 'string', + [doc]: 'URL to the Patreon page', + [required]: true, + [requires]: donate => donate.type === 'patreon' + } +}; + +module.exports = { + [type]: 'array', + [doc]: 'Donation entries\nhttp://ppoffice.github.io/hexo-theme-icarus/categories/Donation/', + [defaultValue]: DEFAULT_DONATE, + '*': { + [type]: 'object', + [doc]: 'Single donation entry settings', + type: { + [type]: 'string', + [doc]: 'Donation entry name', + [required]: true + }, + ...QrcodeSpec, + ...PaypalSpec, + ...PatreonSpec + } +} \ No newline at end of file diff --git a/languages/en.yml b/languages/en.yml index 401bc45..816fe2c 100644 --- a/languages/en.yml +++ b/languages/en.yml @@ -25,6 +25,12 @@ article: read: 'read' about: 'About' words: 'words' +donate: + title: 'Like this article? Support the author with' + alipay: 'Alipay' + wechat: 'Wechat' + paypal: 'Paypal' + patreon: 'Patreon' plugin: backtotop: 'Back to Top' search: diff --git a/languages/zh-CN.yml b/languages/zh-CN.yml index 99ec4f5..5ca1fc7 100644 --- a/languages/zh-CN.yml +++ b/languages/zh-CN.yml @@ -25,6 +25,10 @@ article: read: '读完' about: '大约' words: '个字' +donate: + title: '喜欢这篇文章?打赏一下作者吧' + alipay: '支付宝' + wechat: '微信' plugin: backtotop: '回到顶端' search: diff --git a/layout/common/article.ejs b/layout/common/article.ejs index fe97d17..d3149f2 100644 --- a/layout/common/article.ejs +++ b/layout/common/article.ejs @@ -70,6 +70,23 @@
+<% const services = has_config('donate') ? get_config('donate') : []; %> +<% if (!index && services.length > 0) { %> +
+
+ +
+ <% for (let service of services) { + const type = get_config_from_obj(service, 'type'); + if (type !== null) { %> + <%- partial('donate/' + type, { type, service }) %> + <% } + } %> +
+
+
+<% } %> + <% if (!index && (post.prev || post.next)) { %>
diff --git a/layout/donate/alipay.ejs b/layout/donate/alipay.ejs new file mode 100644 index 0000000..5ced298 --- /dev/null +++ b/layout/donate/alipay.ejs @@ -0,0 +1,14 @@ +<% const qrcode = get_config_from_obj(service, 'qrcode'); + if (qrcode) { %> + +<% } else { %> +
+ You forgot to set the qrcode for Alipay. Please set it in _config.yml. +
+<% } %> \ No newline at end of file diff --git a/layout/donate/patreon.ejs b/layout/donate/patreon.ejs new file mode 100644 index 0000000..16de91a --- /dev/null +++ b/layout/donate/patreon.ejs @@ -0,0 +1,13 @@ +<% const url = get_config_from_obj(service, 'url'); + if (url) { %> + +<% } else { %> +
+ You forgot to set the url Patreon. Please set it in _config.yml. +
+<% } %> \ No newline at end of file diff --git a/layout/donate/paypal.ejs b/layout/donate/paypal.ejs new file mode 100644 index 0000000..f4cb854 --- /dev/null +++ b/layout/donate/paypal.ejs @@ -0,0 +1,20 @@ + +<% const business = get_config_from_obj(service, 'business'); + const currency_code = get_config_from_obj(service, 'currency_code'); + if (business && currency_code) { %> + +
+ + + + +<% } else { %> +
+ You forgot to set the business and currency_code for Paypal. Please set it in _config.yml. +
+<% } %> \ No newline at end of file diff --git a/layout/donate/wechat.ejs b/layout/donate/wechat.ejs new file mode 100644 index 0000000..a1a6faa --- /dev/null +++ b/layout/donate/wechat.ejs @@ -0,0 +1,14 @@ +<% const qrcode = get_config_from_obj(service, 'qrcode'); + if (qrcode) { %> + +<% } else { %> +
+ You forgot to set the qrcode for Wechat. Please set it in _config.yml. +
+<% } %> \ No newline at end of file diff --git a/package.json b/package.json index 183c998..da63e1a 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { "name": "hexo-theme-icarus", - "version": "2.0.0", + "version": "2.3.0", "private": true } diff --git a/source/css/style.styl b/source/css/style.styl index ef01c5f..d3e9956 100644 --- a/source/css/style.styl +++ b/source/css/style.styl @@ -50,14 +50,12 @@ body, button, input, select, textarea top: 1.5rem .card - overflow: hidden border-radius: 4px box-shadow: 0 4px 10px rgba(0,0,0,0.05), 0 0 1px rgba(0,0,0,0.1) & + .card, & + .column-right-shadow margin-top: 1.5rem &.card-transparent - overflow: visible box-shadow: none background: transparent @@ -181,6 +179,30 @@ img.thumbnail margin-left: 0.75rem margin-right: 0 +.donate + position: relative + .qrcode + display: none + position: absolute + z-index: 99 + bottom: 2.5em + line-height: 0 + overflow: hidden + border-radius: 4px + box-shadow: 0 4px 10px rgba(0,0,0,.1), 0 0 1px rgba(0,0,0,.2) + overflow: hidden + img + max-width: 280px + &:hover + .qrcode + display: block + &:first-child + .qrcode + left: -0.75rem + &:last-child + .qrcode + right: -0.75rem + @media screen and (max-width: screen-tablet - 1) #toc display: none