feat(plugin): add donate buttons

This commit is contained in:
ppoffice 2018-12-23 15:12:01 -05:00
parent 51e291c615
commit b913e648f3
13 changed files with 220 additions and 14 deletions

View File

@ -2,7 +2,7 @@
<img class="not-gallery-item" height="48" src="http://ppoffice.github.io/hexo-theme-icarus/images/logo.svg">
<br> A simple, delicate, and modern theme for the static site generator Hexo.
<br>
<a href="http://ppoffice.github.io/hexo-theme-icarus/">Preview</a> |
<a href="http://ppoffice.github.io/hexo-theme-icarus/">Preview</a> |
<a href="http://ppoffice.github.io/hexo-theme-icarus/categories/">Documentation</a> |
<a href="https://github.com/ppoffice/hexo-theme-icarus/archive/master.zip">Download</a>
<br>
@ -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.
<table>
@ -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.
<div>

View File

@ -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['*'], {})];
}

View File

@ -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'),

View File

@ -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
}
}

View File

@ -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:

View File

@ -25,6 +25,10 @@ article:
read: '读完'
about: '大约'
words: '个字'
donate:
title: '喜欢这篇文章?打赏一下作者吧'
alipay: '支付宝'
wechat: '微信'
plugin:
backtotop: '回到顶端'
search:

View File

@ -70,6 +70,23 @@
</div>
</div>
<% const services = has_config('donate') ? get_config('donate') : []; %>
<% if (!index && services.length > 0) { %>
<div class="card">
<div class="card-content">
<h3 class="menu-label has-text-centered"><%= __('donate.title') %></h3>
<div class="buttons is-centered">
<% for (let service of services) {
const type = get_config_from_obj(service, 'type');
if (type !== null) { %>
<%- partial('donate/' + type, { type, service }) %>
<% }
} %>
</div>
</div>
</div>
<% } %>
<% if (!index && (post.prev || post.next)) { %>
<div class="card card-transparent">
<div class="level post-navigation is-flex-wrap is-mobile">

14
layout/donate/alipay.ejs Normal file
View File

@ -0,0 +1,14 @@
<% const qrcode = get_config_from_obj(service, 'qrcode');
if (qrcode) { %>
<a class="button is-info donate">
<span class="icon is-small">
<i class="fab fa-alipay"></i>
</span>
<span><%= __('donate.' + type) %></span>
<div class="qrcode"><img src="<%= url_for(qrcode) %>" alt="<%= __('donate.' + type) %>"></div>
</a>
<% } else { %>
<div class="notification is-danger">
You forgot to set the <code>qrcode</code> for Alipay. Please set it in <code>_config.yml</code>.
</div>
<% } %>

13
layout/donate/patreon.ejs Normal file
View File

@ -0,0 +1,13 @@
<% const url = get_config_from_obj(service, 'url');
if (url) { %>
<a class="button is-danger donate" href="<%= url_for(url) %>" target="_blank">
<span class="icon is-small">
<i class="fab fa-patreon"></i>
</span>
<span><%= __('donate.' + type) %></span>
</a>
<% } else { %>
<div class="notification is-danger">
You forgot to set the <code>url</code> Patreon. Please set it in <code>_config.yml</code>.
</div>
<% } %>

20
layout/donate/paypal.ejs Normal file
View File

@ -0,0 +1,20 @@
<!-- Visit https://www.paypal.com/donate/buttons/ to get your donate button -->
<% const business = get_config_from_obj(service, 'business');
const currency_code = get_config_from_obj(service, 'currency_code');
if (business && currency_code) { %>
<a class="button is-warning donate" onclick="<%= 'document.getElementById(\'paypal-donate-form\').submit()' %>">
<span class="icon is-small">
<i class="fab fa-paypal"></i>
</span>
<span><%= __('donate.' + type) %></span>
</a>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank" id="paypal-donate-form">
<input type="hidden" name="cmd" value="_donations" />
<input type="hidden" name="business" value="<%= business %>" />
<input type="hidden" name="currency_code" value="<%= currency_code %>" />
</form>
<% } else { %>
<div class="notification is-danger">
You forgot to set the <code>business</code> and <code>currency_code</code> for Paypal. Please set it in <code>_config.yml</code>.
</div>
<% } %>

14
layout/donate/wechat.ejs Normal file
View File

@ -0,0 +1,14 @@
<% const qrcode = get_config_from_obj(service, 'qrcode');
if (qrcode) { %>
<a class="button is-success donate">
<span class="icon is-small">
<i class="fab fa-weixin"></i>
</span>
<span><%= __('donate.' + type) %></span>
<div class="qrcode"><img src="<%= url_for(qrcode) %>" alt="<%= __('donate.' + type) %>"></div>
</a>
<% } else { %>
<div class="notification is-danger">
You forgot to set the <code>qrcode</code> for Wechat. Please set it in <code>_config.yml</code>.
</div>
<% } %>

View File

@ -1,5 +1,5 @@
{
"name": "hexo-theme-icarus",
"version": "2.0.0",
"version": "2.3.0",
"private": true
}

View File

@ -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