From 7441aed6966237d8dcf821ccbeb489f18db035ad Mon Sep 17 00:00:00 2001
From: Elmore Cheng <9206414+ikeq@users.noreply.github.com>
Date: Sat, 31 Aug 2019 02:44:20 -0700
Subject: [PATCH] support custom permalink (#127)
---
README.md | 2 --
README_zh-Hans.md | 2 --
lib/config.js | 2 --
lib/filter/post.js | 6 ++---
lib/generator/config.js | 21 ++++++++++++++-
lib/generator/entries/pages.js | 6 ++---
lib/generator/entries/posts.js | 4 +--
lib/generator/index.js | 26 +++++++++---------
lib/helper/url_trim.js | 6 ++---
lib/utils.js | 27 +++++++++++--------
package.json | 2 +-
source/_resources.json | 2 +-
...66fcad.js => main.3c8fe2175e9d028e033b.js} | 2 +-
....ja.js => main.45d1e4209486560b00ce.ja.js} | 2 +-
...s => main.5f57ed8aacba80770b83.zh-Hans.js} | 2 +-
...s => main.dec5dcd89e85221e092e.zh-Hant.js} | 2 +-
test/scripts/filters/post.js | 5 +++-
test/scripts/utils/rest.js | 13 ++++-----
18 files changed, 77 insertions(+), 55 deletions(-)
rename source/{main.aa5336b38b728b66fcad.js => main.3c8fe2175e9d028e033b.js} (72%)
rename source/{main.c53a7c81fe2a67caf1e3.ja.js => main.45d1e4209486560b00ce.ja.js} (73%)
rename source/{main.5be06e990995039d250c.zh-Hans.js => main.5f57ed8aacba80770b83.zh-Hans.js} (73%)
rename source/{main.8afb50983316ecb0cc35.zh-Hant.js => main.dec5dcd89e85221e092e.zh-Hant.js} (73%)
diff --git a/README.md b/README.md
index b00e558..1e0cc6c 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,6 @@
- SPA built with [angular]
- Custom accent color, background, fonts, dark mode
- Custom code syntax highlighting
-- Sub-page
- Search
- Comments
- [Disqus]
@@ -54,7 +53,6 @@
2\. Config `HEXO/_config.yml` as follows:
```yml
-permalink: post/:title/
theme: inside
```
diff --git a/README_zh-Hans.md b/README_zh-Hans.md
index 306db87..9dcbc94 100644
--- a/README_zh-Hans.md
+++ b/README_zh-Hans.md
@@ -23,7 +23,6 @@
- SPA built with [angular]
- 自定义色调、背景、字体、暗色主题
- 自定义代码语法高亮
-- 可嵌套 page 路由
- 评论
- [Disqus]
- [LiveRe]
@@ -53,7 +52,6 @@
2\. 配置 `HEXO/_config.yml` 如下:
```yml
-permalink: post/:title/
theme: inside
```
diff --git a/lib/config.js b/lib/config.js
index 9a1023b..3a92d88 100644
--- a/lib/config.js
+++ b/lib/config.js
@@ -29,8 +29,6 @@ module.exports = function (hexo) {
// override default language
site.language = utils.localeId(site.language);
- // override default permalink
- site.permalink = 'post/:title/';
const __ = this.theme.i18n.__(site.language);
diff --git a/lib/filter/post.js b/lib/filter/post.js
index 7e527bc..296d016 100644
--- a/lib/filter/post.js
+++ b/lib/filter/post.js
@@ -2,7 +2,7 @@ const cheerio = require('cheerio');
const { date } = require('hexo/lib/plugins/helper/date');
const bounded = '
';
const table = '';
-const { snippet, getPagePath, parseToc, isObject, isEmptyObject, localeId, pick } = require('../utils');
+const { snippet, parseToc, isObject, isEmptyObject, localeId, pick, trimHtml } = require('../utils');
// cache
let hasComments, hasReward, hasToc, copyright, dateHelper, uriReplacer;
@@ -37,7 +37,7 @@ module.exports = function (data) {
s => s;
// relative link
- data.link = isPage ? getPagePath(data.source) : `post/${data.slug}`;
+ data.link = trimHtml(data.path);
// permalink link
data.plink = `${config.url}/${data.link}/`;
// type
@@ -47,7 +47,7 @@ module.exports = function (data) {
data.comments = hasComments && data.comments !== false;
// asset path
- const assetPath = isPage ? getPagePath(data.source, true) : data.link;
+ const assetPath = isPage ? trimHtml(data.path, true) : data.link;
// Make sure articles without titles are also accessible
if (!data.title) data.title = data.slug
diff --git a/lib/generator/config.js b/lib/generator/config.js
index 20ea75b..6240b1d 100644
--- a/lib/generator/config.js
+++ b/lib/generator/config.js
@@ -25,9 +25,28 @@ module.exports = function (locals) {
parseBackground(sidebar_background).color || accent_color]
.concat(parseBackground(background).color || (theme.pwa && theme.pwa.theme_color) || [])
+ // post routes
+ config.routes = {}
+ config.routes.posts = [...locals.posts
+ .reduce((set, post) => {
+ // convert `/path/to/path/` to `:a/:b/:c`
+ const link = post.link.split('/').filter(i => i)
+ .map((_, i) => ':' + String.fromCharCode(97 + i))
+ .join('/')
+ set.add(link)
+ return set
+ }, new Set)].sort()
// page routes
if (locals.pages.length)
- config.routes = locals.pages.map(page => page.link).sort();
+ config.routes.pages = [...locals.pages
+ .reduce((set, post) => {
+ // convert `/path/to/path/` to `path/:a/:b`
+ const link = post.link.split('/').filter(i => i)
+ .map((partial, i) => i === 0 ? partial : ':' + String.fromCharCode(97 + i))
+ .join('/')
+ set.add(link)
+ return set
+ }, new Set)].sort()
if (config.count.categories) config.firstCategory = locals.categories[0].name;
diff --git a/lib/generator/entries/pages.js b/lib/generator/entries/pages.js
index 273e450..e3485c1 100644
--- a/lib/generator/entries/pages.js
+++ b/lib/generator/entries/pages.js
@@ -1,16 +1,16 @@
const { flattenDeep } = require('lodash');
-const { getPagePath, pick } = require('../../utils');
+const { pick } = require('../../utils');
const { page: pageProps } = require('./properties');
module.exports = function ({ locals: { pages }, helpers }) {
return flattenDeep([
pages.map(page => [
helpers.generateJson({
- path: `page/${page.link}`,
+ path: page.link,
data: pick(page, pageProps)
}),
helpers.generateHtml({
- path: getPagePath(page.source),
+ path: page.link,
data: page
})
]),
diff --git a/lib/generator/entries/posts.js b/lib/generator/entries/posts.js
index 0824873..3020ea8 100644
--- a/lib/generator/entries/posts.js
+++ b/lib/generator/entries/posts.js
@@ -13,7 +13,7 @@ module.exports = function ({ theme, locals: { posts }, helpers }) {
return [
helpers.generateJson({
- path: `${post.link}`,
+ path: post.link,
data: pick(post, postProps)
}),
helpers.generateHtml({
@@ -31,7 +31,7 @@ module.exports = function ({ theme, locals: { posts }, helpers }) {
if (a.date === b.date) return 0;
return a.date > b.date ? -1 : 1;
}).map(pick(postListProps)), { perPage: config.per_page }, [
- { type: 'json', id: 'posts' },
+ { type: 'json', id: 'page' },
{ type: 'html', id: index => index === 1 ? '' : `page/${index}`, extend: { type: 'posts' } },
])
]);
diff --git a/lib/generator/index.js b/lib/generator/index.js
index 8b7826d..15dea9b 100644
--- a/lib/generator/index.js
+++ b/lib/generator/index.js
@@ -8,7 +8,7 @@ const generators = [
require('./manifest'),
require('./sw')
];
-const builtInRoutes = ['page', 'post', 'categories', 'tags', 'archives', 'search', '404'];
+const builtInRoutes = ['page', 'categories', 'tags', 'archives', 'search', '404'];
module.exports = function (hexo) {
// Remove hexo default generators
@@ -27,21 +27,21 @@ module.exports = function (hexo) {
return data;
}).filter(data => data.posts.length),
- pages: locals.pages
- // Filter built-in routes to improve compatibility
- .filter(page => {
- if (builtInRoutes.includes(page.path.split('/')[0])) {
- hexo.log.warn(page.path + ' won\'t be rendered.');
- return false;
- }
+ pages: locals.pages.filter(filterBuiltInRoutes).toArray(),
- return true;
- })
- .toArray(),
-
- posts: locals.posts.filter(published).sort('-date').toArray()
+ posts: locals.posts.filter(published).filter(filterBuiltInRoutes).sort('-date').toArray()
};
return flatten(generators.map(fn => fn.call(this, sLocals)));
});
+
+ // Filter built-in routes to improve compatibility
+ function filterBuiltInRoutes(post) {
+ if (builtInRoutes.includes(post.path.split('/')[0])) {
+ hexo.log.warn(post.path + ' won\'t be rendered.');
+ return false;
+ }
+
+ return true;
+ }
};
diff --git a/lib/helper/url_trim.js b/lib/helper/url_trim.js
index 2504222..e6c95de 100644
--- a/lib/helper/url_trim.js
+++ b/lib/helper/url_trim.js
@@ -1,5 +1,5 @@
-module.exports = function (url) {
- if (!url) return '';
+const { trimHtml } = require('../utils')
- return url.replace(/index.html$/, '');
+module.exports = function (url) {
+ return url ? trimHtml(url) + '/' : '';
}
diff --git a/lib/utils.js b/lib/utils.js
index e617e77..15de5ea 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -59,21 +59,26 @@ exports.base64 = function (str) {
}
/**
- * Align page path to support sub page
+ * Remove `/*.html`
*
- * source/page/index.md => /root/page
- * source/page/v2.md => /root/page/v2
- *
- * @param {string} source page.source
- * @param {boolean} keepIndex
+ * @param {string} url
+ * @param {boolean} keepIndex keep `index` for `index.html`, used for post_asset_folder
* @returns {string}
*/
-exports.getPagePath = function (source, keepIndex) {
- let [paths, md] = source.split(/\/(?=[^\/]*md$)/);
+exports.trimHtml = function (url, keepIndex) {
+ if (!url) return '';
+ url = url.split('/')
+
+ const last = url.pop()
+ if (last) {
+ if (last === 'index.html') {
+ if (keepIndex) url.push('index')
+ } else {
+ url.push(last.split('.')[0])
+ }
+ }
- if (md !== 'index.md') paths += '/' + md.substring(0, md.indexOf('.md'));
- else if (keepIndex) paths += '/index';
- return paths;
+ return url.join('/');
}
exports.Pagination = class {
diff --git a/package.json b/package.json
index 8327b39..49d06ab 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "hexo-theme-inside",
- "version": "2.4.0-beta.1",
+ "version": "2.4.0-beta.2",
"description": "❤️ SPA, flat and clean theme for Hexo.",
"scripts": {
"test": "jasmine --config=test/jasmine.json"
diff --git a/source/_resources.json b/source/_resources.json
index 70a3fc8..b065edd 100644
--- a/source/_resources.json
+++ b/source/_resources.json
@@ -1 +1 @@
-{"root":"is-a","styles":["styles.9477318680c7e6b720a2.css"],"scripts":["runtime.caef73fae70e33459c5a.js","polyfills.28555e618578fe61f50a.js"],"locales":{"zh-Hans":"main.5be06e990995039d250c.zh-Hans.js","zh-Hant":"main.8afb50983316ecb0cc35.zh-Hant.js","en":"main.aa5336b38b728b66fcad.js","ja":"main.c53a7c81fe2a67caf1e3.ja.js"}}
+{"root":"is-a","styles":["styles.9477318680c7e6b720a2.css"],"scripts":["runtime.caef73fae70e33459c5a.js","polyfills.28555e618578fe61f50a.js"],"locales":{"en":"main.3c8fe2175e9d028e033b.js","ja":"main.45d1e4209486560b00ce.ja.js","zh-Hans":"main.5f57ed8aacba80770b83.zh-Hans.js","zh-Hant":"main.dec5dcd89e85221e092e.zh-Hant.js"}}
diff --git a/source/main.aa5336b38b728b66fcad.js b/source/main.3c8fe2175e9d028e033b.js
similarity index 72%
rename from source/main.aa5336b38b728b66fcad.js
rename to source/main.3c8fe2175e9d028e033b.js
index a61f575..bd73f3b 100644
--- a/source/main.aa5336b38b728b66fcad.js
+++ b/source/main.3c8fe2175e9d028e033b.js
@@ -1 +1 @@
-(window.webpackJsonp=window.webpackJsonp||[]).push([[1],{0:function(t,e,n){t.exports=n("zUnb")},zUnb:function(t,e,n){"use strict";n.r(e);var r=function(t,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)};function o(t,e){function n(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}var i=function(){return(i=Object.assign||function(t){for(var e,n=1,r=arguments.length;n=0;u--)(o=t[u])&&(l=(i<3?o(l):i>3?o(e,n,l):o(e,n))||l);return i>3&&l&&Object.defineProperty(e,n,l),l}function u(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)}function a(t){var e="function"==typeof Symbol&&t[Symbol.iterator],n=0;return e?e.call(t):{next:function(){return t&&n>=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}}}function s(t,e){var n="function"==typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,o,i=n.call(t),l=[];try{for(;(void 0===e||e-- >0)&&!(r=i.next()).done;)l.push(r.value)}catch(u){o={error:u}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return l}function c(){for(var t=[],e=0;e0?this._next(e.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()},e}(W);function et(t){return t}function nt(t){return void 0===t&&(t=Number.POSITIVE_INFINITY),J(et,t)}function rt(t,e){return e?K(t,e):new O(F(t))}function ot(){return function(t){return t.lift(new it(t))}}var it=function(){function t(t){this.connectable=t}return t.prototype.call=function(t,e){var n=this.connectable;n._refCount++;var r=new lt(t,n),o=e.subscribe(r);return r.closed||(r.connection=n.connect()),o},t}(),lt=function(t){function e(e,n){var r=t.call(this,e)||this;return r.connectable=n,r}return o(e,t),e.prototype._unsubscribe=function(){var t=this.connectable;if(t){this.connectable=null;var e=t._refCount;if(e<=0)this.connection=null;else if(t._refCount=e-1,e>1)this.connection=null;else{var n=this.connection,r=t._connection;this.connection=null,!r||n&&r!==n||r.unsubscribe()}}else this.connection=null},e}(C),ut=function(t){function e(e,n){var r=t.call(this)||this;return r.source=e,r.subjectFactory=n,r._refCount=0,r._isComplete=!1,r}return o(e,t),e.prototype._subscribe=function(t){return this.getSubject().subscribe(t)},e.prototype.getSubject=function(){var t=this._subject;return t&&!t.isStopped||(this._subject=this.subjectFactory()),this._subject},e.prototype.connect=function(){var t=this._connection;return t||(this._isComplete=!1,(t=this._connection=new v).add(this.source.subscribe(new st(this.getSubject(),this))),t.closed&&(this._connection=null,t=v.EMPTY)),t},e.prototype.refCount=function(){return ot()(this)},e}(O).prototype,at={operator:{value:null},_refCount:{value:0,writable:!0},_subject:{value:null,writable:!0},_connection:{value:null,writable:!0},_subscribe:{value:ut._subscribe},_isComplete:{value:ut._isComplete,writable:!0},getSubject:{value:ut.getSubject},connect:{value:ut.connect},refCount:{value:ut.refCount}},st=function(t){function e(e,n){var r=t.call(this,e)||this;return r.connectable=n,r}return o(e,t),e.prototype._error=function(e){this._unsubscribe(),t.prototype._error.call(this,e)},e.prototype._complete=function(){this.connectable._isComplete=!0,this._unsubscribe(),t.prototype._complete.call(this)},e.prototype._unsubscribe=function(){var t=this.connectable;if(t){this.connectable=null;var e=t._connection;t._refCount=0,t._subject=null,t._connection=null,e&&e.unsubscribe()}},e}(D);function ct(){return new M}var ft="__parameters__",pt="__prop__metadata__";function ht(t){return function(){for(var e=[],n=0;n ");else if("object"==typeof e){var i=[];for(var l in e)if(e.hasOwnProperty(l)){var u=e[l];i.push(l+":"+("string"==typeof u?JSON.stringify(u):Et(u)))}o="{"+i.join(", ")+"}"}return n+(r?"("+r+")":"")+"["+o+"]: "+t.replace(Ut,"\n ")}var Zt=function(){return function(){}}(),Gt=function(){return function(){}}();function Qt(t,e,n){e>=t.length?t.push(n):t.splice(e,0,n)}function Kt(t,e){return e>=t.length-1?t.pop():t.splice(e,1)[0]}var Yt=function(t){return t[t.Emulated=0]="Emulated",t[t.Native=1]="Native",t[t.None=2]="None",t[t.ShadowDom=3]="ShadowDom",t}({}),Jt=function(){return("undefined"!=typeof requestAnimationFrame&&requestAnimationFrame||setTimeout).bind(Dt)}(),Xt="ngDebugContext",te="ngOriginalError",ee="ngErrorLogger";function ne(t){return t[Xt]}function re(t){return t[te]}function oe(t){for(var e=[],n=1;n',!this.inertBodyElement.querySelector||this.inertBodyElement.querySelector("svg")?(this.inertBodyElement.innerHTML='