diff --git a/includes/helpers/override.js b/includes/helpers/override.js
index 77a2835..fd3af3d 100644
--- a/includes/helpers/override.js
+++ b/includes/helpers/override.js
@@ -5,11 +5,14 @@
* <%- _list_archives() %>
* <%- _list_categories() %>
* <%- _list_tags() %>
-* <%- _toc() %>
-* <%- _js() %>
-* <%- _css() %>
+* <%- _toc(content) %>
+* <%- _js(url, defer, async) %>
+* <%- _css(url) %>
+* <%- _partial(url) %>
*/
const cheerio = require('cheerio');
+const { existsSync } = require('fs');
+const { relative, dirname, join, extname } = require('path');
const __archives = [];
const __categories = [];
@@ -151,4 +154,35 @@ module.exports = function (hexo) {
}
return ``;
});
+
+ hexo.extend.helper.register('_partial', function (name, locals, options = {}) {
+ const { md5, partial, view_dir, page } = this;
+ const currentView = this.filename.substring(view_dir.length);
+ let _locals = Object.assign({}, locals, { layout: false });
+
+ let { path } = hexo.theme.getView(join(dirname(currentView), name)) || hexo.theme.getView(name);
+ path = join(view_dir, path.substring(0, path.length - extname(path).length) + '.locals.js');
+
+ if (!existsSync(path)) {
+ // fallback to default partial
+ return partial(name, locals, options);
+ }
+
+ _locals = require(path)(this, _locals);
+ if (_locals === null) {
+ // partial should be empty
+ return '';
+ }
+
+ if (_locals === false) {
+ // do not cache this fragment
+ return partial(name, locals, options);
+ }
+
+ const language = page.lang || page.language;
+ const fragment = relative(view_dir, path.substring(0, path.length - '.locals.js'.length));
+ const cacheId = [fragment, language, md5(JSON.stringify(_locals))].join('-');
+
+ return partial(name, _locals, { cache: cacheId, only: options.only || false });
+ });
}
\ No newline at end of file
diff --git a/layout/archive.ejs b/layout/archive.ejs
index 5347935..ace6b41 100644
--- a/layout/archive.ejs
+++ b/layout/archive.ejs
@@ -52,5 +52,5 @@ if (!page.year) {
<%- buildArchive(page.posts, page.year, page.month) %>
<% } %>
<% if (page.total > 1) { %>
- <%- partial('common/paginator') %>
+ <%- _partial('common/paginator') %>
<% } %>
\ No newline at end of file
diff --git a/layout/category.ejs b/layout/category.ejs
index 9114435..3822544 100644
--- a/layout/category.ejs
+++ b/layout/category.ejs
@@ -11,4 +11,4 @@
-<%- partial('index', { page }) %>
\ No newline at end of file
+<%- _partial('index', { page }) %>
\ No newline at end of file
diff --git a/layout/comment/changyan.ejs b/layout/comment/changyan.ejs
index eaddb6b..09c5266 100644
--- a/layout/comment/changyan.ejs
+++ b/layout/comment/changyan.ejs
@@ -3,7 +3,7 @@
You forgot to set the appid
or conf
for Changyan. Please set it in _config.yml
.
<% } else { %>
-
+
-
+
diff --git a/layout/comment/facebook.locals.js b/layout/comment/facebook.locals.js
new file mode 100644
index 0000000..d5d7ad8
--- /dev/null
+++ b/layout/comment/facebook.locals.js
@@ -0,0 +1,4 @@
+module.exports = (ctx, locals) => {
+ const { permalink } = ctx.page;
+ return Object.assign(locals, { permalink });
+}
\ No newline at end of file
diff --git a/layout/comment/gitalk.ejs b/layout/comment/gitalk.ejs
index 69f44fe..17cec81 100644
--- a/layout/comment/gitalk.ejs
+++ b/layout/comment/gitalk.ejs
@@ -12,7 +12,7 @@
var gitalk = new Gitalk({
clientID: '<%= get_config('comment.client_id') %>',
clientSecret: '<%= get_config('comment.client_secret') %>',
- id: '<%= md5(page.path) %>',
+ id: '<%= md5(path) %>',
repo: '<%= get_config('comment.repo') %>',
owner: '<%= get_config('comment.owner') %>',
admin: <%- JSON.stringify(get_config('comment.admin'))%>,
diff --git a/layout/comment/gitalk.locals.js b/layout/comment/gitalk.locals.js
new file mode 100644
index 0000000..145230a
--- /dev/null
+++ b/layout/comment/gitalk.locals.js
@@ -0,0 +1,4 @@
+module.exports = (ctx, locals) => {
+ const { path } = ctx.page;
+ return Object.assign(locals, { path });
+}
\ No newline at end of file
diff --git a/layout/comment/gitment.ejs b/layout/comment/gitment.ejs
index 1280512..affc597 100644
--- a/layout/comment/gitment.ejs
+++ b/layout/comment/gitment.ejs
@@ -10,7 +10,7 @@
-<% } %>
\ No newline at end of file
+
\ No newline at end of file
diff --git a/layout/plugin/baidu-analytics.locals.js b/layout/plugin/baidu-analytics.locals.js
new file mode 100644
index 0000000..6b60e89
--- /dev/null
+++ b/layout/plugin/baidu-analytics.locals.js
@@ -0,0 +1,7 @@
+module.exports = (ctx, locals) => {
+ const { head, plugin } = locals;
+ if (!head || !plugin.tracking_id) {
+ return null;
+ }
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/plugin/busuanzi.ejs b/layout/plugin/busuanzi.ejs
index 556c02b..f96adf2 100644
--- a/layout/plugin/busuanzi.ejs
+++ b/layout/plugin/busuanzi.ejs
@@ -1,5 +1 @@
-<% if (plugin !== false) { %>
- <% if (head) { %>
-
- <% } %>
-<% } %>
\ No newline at end of file
+
\ No newline at end of file
diff --git a/layout/plugin/busuanzi.locals.js b/layout/plugin/busuanzi.locals.js
new file mode 100644
index 0000000..189691f
--- /dev/null
+++ b/layout/plugin/busuanzi.locals.js
@@ -0,0 +1,7 @@
+module.exports = (ctx, locals) => {
+ const { head, plugin } = locals;
+ if (!head || !plugin) {
+ return null;
+ }
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/plugin/gallery.ejs b/layout/plugin/gallery.ejs
index f6b7e11..4a48ca2 100644
--- a/layout/plugin/gallery.ejs
+++ b/layout/plugin/gallery.ejs
@@ -1,10 +1,8 @@
-<% if (plugin !== false) { %>
- <% if (head) { %>
- <%- _css(cdn('lightgallery', '1.6.8', 'dist/css/lightgallery.min.css')) %>
- <%- _css(cdn('justifiedGallery', '3.7.0', 'dist/css/justifiedGallery.min.css')) %>
- <% } else { %>
- <%- _js(cdn('lightgallery', '1.6.8', 'dist/js/lightgallery.min.js'), true) %>
- <%- _js(cdn('justifiedGallery', '3.7.0', 'dist/js/jquery.justifiedGallery.min.js'), true) %>
- <%- _js('js/gallery', true) %>
- <% } %>
+<% if (head) { %>
+<%- _css(cdn('lightgallery', '1.6.8', 'dist/css/lightgallery.min.css')) %>
+<%- _css(cdn('justifiedGallery', '3.7.0', 'dist/css/justifiedGallery.min.css')) %>
+<% } else { %>
+<%- _js(cdn('lightgallery', '1.6.8', 'dist/js/lightgallery.min.js'), true) %>
+<%- _js(cdn('justifiedGallery', '3.7.0', 'dist/js/jquery.justifiedGallery.min.js'), true) %>
+<%- _js('js/gallery', true) %>
<% } %>
\ No newline at end of file
diff --git a/layout/plugin/gallery.locals.js b/layout/plugin/gallery.locals.js
new file mode 100644
index 0000000..9939266
--- /dev/null
+++ b/layout/plugin/gallery.locals.js
@@ -0,0 +1,6 @@
+module.exports = (ctx, locals) => {
+ if (!locals.plugin) {
+ return null;
+ }
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/plugin/google-analytics.ejs b/layout/plugin/google-analytics.ejs
index 853a52b..bd94d52 100644
--- a/layout/plugin/google-analytics.ejs
+++ b/layout/plugin/google-analytics.ejs
@@ -1,4 +1,3 @@
-<% if (head && get_config_from_obj(plugin, 'tracking_id')) { %>
-<% } %>
diff --git a/layout/plugin/google-analytics.locals.js b/layout/plugin/google-analytics.locals.js
new file mode 100644
index 0000000..6b60e89
--- /dev/null
+++ b/layout/plugin/google-analytics.locals.js
@@ -0,0 +1,7 @@
+module.exports = (ctx, locals) => {
+ const { head, plugin } = locals;
+ if (!head || !plugin.tracking_id) {
+ return null;
+ }
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/plugin/hotjar.ejs b/layout/plugin/hotjar.ejs
index 0d88940..669574c 100644
--- a/layout/plugin/hotjar.ejs
+++ b/layout/plugin/hotjar.ejs
@@ -1,4 +1,3 @@
-<% if (head && get_config_from_obj(plugin, 'site_id')) { %>
-<% } %>
+
\ No newline at end of file
diff --git a/layout/plugin/hotjar.locals.js b/layout/plugin/hotjar.locals.js
new file mode 100644
index 0000000..75fdf81
--- /dev/null
+++ b/layout/plugin/hotjar.locals.js
@@ -0,0 +1,7 @@
+module.exports = (ctx, locals) => {
+ const { head, plugin } = locals;
+ if (!head || !plugin.site_id) {
+ return null;
+ }
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/plugin/mathjax.ejs b/layout/plugin/mathjax.ejs
index a9585ee..7b4cd6d 100644
--- a/layout/plugin/mathjax.ejs
+++ b/layout/plugin/mathjax.ejs
@@ -1,4 +1,3 @@
-<% if (!head && plugin !== false) { %>
<%- _js(cdn('mathjax', '2.7.5', 'unpacked/MathJax.js?config=TeX-MML-AM_CHTML'), true) %>
-<% } %>
\ No newline at end of file
+
\ No newline at end of file
diff --git a/layout/plugin/mathjax.locals.js b/layout/plugin/mathjax.locals.js
new file mode 100644
index 0000000..d615cf5
--- /dev/null
+++ b/layout/plugin/mathjax.locals.js
@@ -0,0 +1,7 @@
+module.exports = (ctx, locals) => {
+ const { head, plugin } = locals;
+ if (head || !plugin) {
+ return null;
+ }
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/plugin/outdated-browser.ejs b/layout/plugin/outdated-browser.ejs
index 95833c3..c14aba9 100644
--- a/layout/plugin/outdated-browser.ejs
+++ b/layout/plugin/outdated-browser.ejs
@@ -1,4 +1,3 @@
-<% if (plugin !== false) { %>
<% if (head) { %>
<%- _css(cdn('outdatedbrowser', '1.1.5', 'outdatedbrowser/outdatedbrowser.min.css')) %>
<% } else { %>
@@ -18,5 +17,4 @@
});
});
-<% } %>
<% } %>
\ No newline at end of file
diff --git a/layout/plugin/outdated-browser.locals.js b/layout/plugin/outdated-browser.locals.js
new file mode 100644
index 0000000..9939266
--- /dev/null
+++ b/layout/plugin/outdated-browser.locals.js
@@ -0,0 +1,6 @@
+module.exports = (ctx, locals) => {
+ if (!locals.plugin) {
+ return null;
+ }
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/plugin/progressbar.ejs b/layout/plugin/progressbar.ejs
index 1750db1..e60a280 100644
--- a/layout/plugin/progressbar.ejs
+++ b/layout/plugin/progressbar.ejs
@@ -1,4 +1,2 @@
-<% if (head && plugin !== false) { %>
<%- _css('css/progressbar') %>
-<%- _js(cdn('pace-js', '1.0.2', 'pace.min.js')) %>
-<% } %>
\ No newline at end of file
+<%- _js(cdn('pace-js', '1.0.2', 'pace.min.js')) %>
\ No newline at end of file
diff --git a/layout/plugin/progressbar.locals.js b/layout/plugin/progressbar.locals.js
new file mode 100644
index 0000000..189691f
--- /dev/null
+++ b/layout/plugin/progressbar.locals.js
@@ -0,0 +1,7 @@
+module.exports = (ctx, locals) => {
+ const { head, plugin } = locals;
+ if (!head || !plugin) {
+ return null;
+ }
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/post.ejs b/layout/post.ejs
index 56fa8fb..8161cf1 100644
--- a/layout/post.ejs
+++ b/layout/post.ejs
@@ -1 +1 @@
-<%- partial('common/article', {post: page, index: false}) %>
\ No newline at end of file
+<%- _partial('common/article', {post: page, index: false}) %>
\ No newline at end of file
diff --git a/layout/search/baidu.locals.js b/layout/search/baidu.locals.js
new file mode 100644
index 0000000..bec3126
--- /dev/null
+++ b/layout/search/baidu.locals.js
@@ -0,0 +1,3 @@
+module.exports = (ctx, locals) => {
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/search/google-cse.locals.js b/layout/search/google-cse.locals.js
new file mode 100644
index 0000000..bec3126
--- /dev/null
+++ b/layout/search/google-cse.locals.js
@@ -0,0 +1,3 @@
+module.exports = (ctx, locals) => {
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/search/insight.locals.js b/layout/search/insight.locals.js
new file mode 100644
index 0000000..bec3126
--- /dev/null
+++ b/layout/search/insight.locals.js
@@ -0,0 +1,3 @@
+module.exports = (ctx, locals) => {
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/share/addthis.locals.js b/layout/share/addthis.locals.js
new file mode 100644
index 0000000..bec3126
--- /dev/null
+++ b/layout/share/addthis.locals.js
@@ -0,0 +1,3 @@
+module.exports = (ctx, locals) => {
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/share/addtoany.locals.js b/layout/share/addtoany.locals.js
new file mode 100644
index 0000000..bec3126
--- /dev/null
+++ b/layout/share/addtoany.locals.js
@@ -0,0 +1,3 @@
+module.exports = (ctx, locals) => {
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/share/bdshare.locals.js b/layout/share/bdshare.locals.js
new file mode 100644
index 0000000..bec3126
--- /dev/null
+++ b/layout/share/bdshare.locals.js
@@ -0,0 +1,3 @@
+module.exports = (ctx, locals) => {
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/share/sharejs.locals.js b/layout/share/sharejs.locals.js
new file mode 100644
index 0000000..705fadb
--- /dev/null
+++ b/layout/share/sharejs.locals.js
@@ -0,0 +1,9 @@
+module.exports = (ctx, locals) => {
+ const { get_config } = ctx;
+ return Object.assign(locals, {
+ // just for diff detection
+ _providers: {
+ _cdn: get_config('providers.cdn')
+ }
+ });
+}
\ No newline at end of file
diff --git a/layout/share/sharethis.locals.js b/layout/share/sharethis.locals.js
new file mode 100644
index 0000000..bec3126
--- /dev/null
+++ b/layout/share/sharethis.locals.js
@@ -0,0 +1,3 @@
+module.exports = (ctx, locals) => {
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/tag.ejs b/layout/tag.ejs
index 23f3a40..b2b2d04 100644
--- a/layout/tag.ejs
+++ b/layout/tag.ejs
@@ -8,4 +8,4 @@
-<%- partial('index', { page }) %>
\ No newline at end of file
+<%- _partial('index', { page }) %>
\ No newline at end of file
diff --git a/layout/widget/archive.locals.js b/layout/widget/archive.locals.js
new file mode 100644
index 0000000..bec3126
--- /dev/null
+++ b/layout/widget/archive.locals.js
@@ -0,0 +1,3 @@
+module.exports = (ctx, locals) => {
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/widget/category.ejs b/layout/widget/category.ejs
index a857b49..6aa4862 100644
--- a/layout/widget/category.ejs
+++ b/layout/widget/category.ejs
@@ -1 +1 @@
-<%- partial('categories') %>
\ No newline at end of file
+<%- _partial('categories') %>
\ No newline at end of file
diff --git a/layout/widget/category.locals.js b/layout/widget/category.locals.js
new file mode 100644
index 0000000..bec3126
--- /dev/null
+++ b/layout/widget/category.locals.js
@@ -0,0 +1,3 @@
+module.exports = (ctx, locals) => {
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/widget/links.ejs b/layout/widget/links.ejs
index 2a1e629..468f48b 100644
--- a/layout/widget/links.ejs
+++ b/layout/widget/links.ejs
@@ -1,5 +1,3 @@
-<% const links = get_config_from_obj(widget, 'links'); %>
-<% if (links !== null) { %>
-<% } %>
diff --git a/layout/widget/links.locals.js b/layout/widget/links.locals.js
new file mode 100644
index 0000000..3f76a55
--- /dev/null
+++ b/layout/widget/links.locals.js
@@ -0,0 +1,8 @@
+module.exports = (ctx, locals) => {
+ const { get_config_from_obj } = ctx;
+ const links = get_config_from_obj(locals.widget, 'links');
+ if (Object.keys(links).length == 0) {
+ return null;
+ }
+ return Object.assign(locals, { links });
+}
\ No newline at end of file
diff --git a/layout/widget/profile.locals.js b/layout/widget/profile.locals.js
new file mode 100644
index 0000000..bec3126
--- /dev/null
+++ b/layout/widget/profile.locals.js
@@ -0,0 +1,3 @@
+module.exports = (ctx, locals) => {
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/widget/recent_posts.ejs b/layout/widget/recent_posts.ejs
index 7ba28ed..bc4d87a 100644
--- a/layout/widget/recent_posts.ejs
+++ b/layout/widget/recent_posts.ejs
@@ -1,15 +1,14 @@
-<% if (site.posts.length) { %>
-<% } %>
\ No newline at end of file
+
\ No newline at end of file
diff --git a/layout/widget/recent_posts.locals.js b/layout/widget/recent_posts.locals.js
new file mode 100644
index 0000000..d245195
--- /dev/null
+++ b/layout/widget/recent_posts.locals.js
@@ -0,0 +1,18 @@
+module.exports = (ctx, locals) => {
+ const { has_config, get_config, get_thumbnail } = ctx;
+ const { posts } = ctx.site;
+ if (!posts.length) {
+ return null;
+ }
+ const thumbnail = !has_config('article.thumbnail') || get_config('article.thumbnail') !== false;
+ const _posts = posts.sort('date', -1).limit(5).map(post => ({
+ link: post.link,
+ path: post.path,
+ title: post.title,
+ date: post.date,
+ thumbnail: thumbnail ? get_thumbnail(post) : null,
+ // fix circular JSON serialization issue
+ categories: () => post.categories
+ }));
+ return Object.assign(locals, { thumbnail, posts: _posts });
+}
\ No newline at end of file
diff --git a/layout/widget/tag.ejs b/layout/widget/tag.ejs
index 7bcc18f..6fdbbcc 100644
--- a/layout/widget/tag.ejs
+++ b/layout/widget/tag.ejs
@@ -1 +1 @@
-<%- partial('tags') %>
\ No newline at end of file
+<%- _partial('tags') %>
\ No newline at end of file
diff --git a/layout/widget/tagcloud.ejs b/layout/widget/tagcloud.ejs
index daf4668..1c04236 100644
--- a/layout/widget/tagcloud.ejs
+++ b/layout/widget/tagcloud.ejs
@@ -1,4 +1,3 @@
-<% if (site.tags.length) { %>
-<% } %>
\ No newline at end of file
+
\ No newline at end of file
diff --git a/layout/widget/tagcloud.locals.js b/layout/widget/tagcloud.locals.js
new file mode 100644
index 0000000..f207e5e
--- /dev/null
+++ b/layout/widget/tagcloud.locals.js
@@ -0,0 +1,6 @@
+module.exports = (ctx, locals) => {
+ if (!ctx.site.tags.length) {
+ return null;
+ }
+ return locals;
+}
\ No newline at end of file
diff --git a/layout/widget/toc.ejs b/layout/widget/toc.ejs
index e0933d6..ceb2244 100644
--- a/layout/widget/toc.ejs
+++ b/layout/widget/toc.ejs
@@ -1,5 +1,4 @@
-<% if (get_config('toc') === true && (post.layout === 'page' || post.layout === 'post')) {
-function buildToc(toc) {
+<% function buildToc(toc) {
let result = '';
if (toc.hasOwnProperty('id') && toc.hasOwnProperty('index') && toc.hasOwnProperty('text')) {
result += `
@@ -24,16 +23,14 @@ function buildToc(toc) {
result += '';
}
return result;
-}
-%>
+} %>
-<% } %>
\ No newline at end of file
+
\ No newline at end of file
diff --git a/layout/widget/toc.locals.js b/layout/widget/toc.locals.js
new file mode 100644
index 0000000..0011f9a
--- /dev/null
+++ b/layout/widget/toc.locals.js
@@ -0,0 +1,8 @@
+module.exports = (ctx, locals) => {
+ const { layout, content } = ctx.page;
+ const { get_config } = ctx;
+ if (get_config('toc') !== true || (layout !== 'page' && layout !== 'post')) {
+ return null;
+ }
+ return Object.assign(locals, { content });
+}
\ No newline at end of file