Skip to content

Commit 8d8ac72

Browse files
authored
Merge pull request #110 from curbengh/custom-template
feat: custom template
2 parents 6e5bb89 + 2e54192 commit 8d8ac72

File tree

5 files changed

+71
-8
lines changed

5 files changed

+71
-8
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ feed:
3636
order_by: -date
3737
icon: icon.png
3838
autodiscovery: true
39+
template:
3940
```
4041
4142
- **type** - Feed type. `atom` or `rss2`. Specify `['atom', 'rss2']` to output both types. (Default: `atom`)
@@ -63,3 +64,20 @@ feed:
6364
- **icon** - (optional) Custom feed icon. Defaults to a gravatar of email specified in the main config.
6465
- **autodiscovery** - Add feed [autodiscovery](http://www.rssboard.org/rss-autodiscovery). (Default: `true`)
6566
* Many themes already offer this feature, so you may also need to adjust the theme's config if you wish to disable it.
67+
- **template** - Custom template path(s). This file will be used to generate feed xml file, see the default templates: [atom.xml](atom.xml) and [rss2.xml](rss2.xml).
68+
* It is possible to specify just one custom template, even when this plugin is configured to output both feed types,
69+
``` yaml
70+
# (Optional) Exclude custom template from being copied into public/ folder
71+
# Alternatively, you could also prepend an underscore to its filename, e.g. _custom.xml
72+
# https://hexo.io/docs/configuration#Include-Exclude-Files-or-Folders
73+
exclude:
74+
- 'custom.xml'
75+
feed:
76+
type:
77+
- atom
78+
- rss2
79+
template:
80+
- ./source/custom.xml
81+
# atom will be generated using custom.xml
82+
# rss2 will be generated using the default template instead
83+
```

index.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* global hexo */
22
'use strict';
33

4-
const { extname } = require('path');
4+
const { extname, join } = require('path');
55

66
const config = hexo.config.feed = Object.assign({
77
type: 'atom',
@@ -11,11 +11,13 @@ const config = hexo.config.feed = Object.assign({
1111
content_limit: 140,
1212
content_limit_delim: '',
1313
order_by: '-date',
14-
autodiscovery: true
14+
autodiscovery: true,
15+
template: ''
1516
}, hexo.config.feed);
1617

1718
let type = config.type;
1819
let path = config.path;
20+
let template = config.template;
1921
const feedFn = require('./lib/generator');
2022

2123
if (!type || (typeof type !== 'string' && !Array.isArray(type))) {
@@ -67,8 +69,22 @@ if (typeof path === 'string') {
6769
if (!extname(path)) path += '.xml';
6870
}
6971

72+
if (typeof template !== 'string' && !Array.isArray(template)) {
73+
template = null;
74+
}
75+
76+
if (Array.isArray(template)) {
77+
if (template.length >= 1) {
78+
if (template.length > type.length) template = template.slice(0, type.length);
79+
else if (template.length < type.length) template.push(join(__dirname, `${type[1]}.xml`));
80+
} else {
81+
template = null;
82+
}
83+
}
84+
7085
config.type = type;
7186
config.path = path;
87+
config.template = template;
7288

7389
if (typeof type === 'string') {
7490
hexo.extend.generator.register(type, locals => {

lib/generator.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,16 @@ env.addFilter('noControlChars', str => {
1414
return str.replace(/[\x00-\x1F\x7F]/g, ''); // eslint-disable-line no-control-regex
1515
});
1616

17-
const atomTmplSrc = join(__dirname, '../atom.xml');
18-
const atomTmpl = nunjucks.compile(readFileSync(atomTmplSrc, 'utf8'), env);
19-
const rss2TmplSrc = join(__dirname, '../rss2.xml');
20-
const rss2Tmpl = nunjucks.compile(readFileSync(rss2TmplSrc, 'utf8'), env);
21-
2217
module.exports = function(locals, type, path) {
2318
const config = this.config;
2419
const feedConfig = config.feed;
25-
const template = type === 'atom' ? atomTmpl : rss2Tmpl;
20+
21+
let tmplSrc = join(__dirname, `../${type}.xml`);
22+
if (feedConfig.template) {
23+
if (typeof feedConfig.template === 'string') tmplSrc = feedConfig.template;
24+
else tmplSrc = feedConfig.template[feedConfig.type.indexOf(type)];
25+
}
26+
const template = nunjucks.compile(readFileSync(tmplSrc, 'utf8'), env);
2627

2728
let posts = locals.posts.sort(feedConfig.order_by || '-date');
2829
posts = posts.filter(post => {

test/custom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<aaa>
3+
{% for post in posts.toArray() %}
4+
<entry>
5+
<published>{{ post.date.toISOString() }}</published>
6+
</entry>
7+
{% endfor %}
8+
</aaa>

test/index.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ const atomTmplSrc = join(__dirname, '../atom.xml');
2121
const atomTmpl = nunjucks.compile(readFileSync(atomTmplSrc, 'utf8'), env);
2222
const rss2TmplSrc = join(__dirname, '../rss2.xml');
2323
const rss2Tmpl = nunjucks.compile(readFileSync(rss2TmplSrc, 'utf8'), env);
24+
const customTmplSrc = join(__dirname, 'custom.xml');
25+
const customTmlp = nunjucks.compile(readFileSync(customTmplSrc, 'utf8'), env);
2426

2527
const urlConfig = {
2628
url: 'http://localhost/',
@@ -320,6 +322,24 @@ describe('Feed generator', () => {
320322
const atom = generator(locals, feedCfg.type[1], feedCfg.path[1]);
321323
atom.path.should.eql(hexo.config.feed.path[1]);
322324
});
325+
326+
it('custom template', () => {
327+
hexo.config.feed = {
328+
type: ['atom'],
329+
path: 'atom.xml',
330+
template: ['test/custom.xml']
331+
};
332+
hexo.config = Object.assign(hexo.config, urlConfig);
333+
const feedCfg = hexo.config.feed;
334+
const result = generator(locals, feedCfg.type[0], feedCfg.path);
335+
336+
result.data.should.eql(customTmlp.render({
337+
config: hexo.config,
338+
url: urlConfig.url,
339+
posts,
340+
feed_url: hexo.config.root + feedCfg.path
341+
}));
342+
});
323343
});
324344

325345
it('No posts', () => {

0 commit comments

Comments
 (0)