Skip to content

Commit

Permalink
feat: tags & categories (#26)
Browse files Browse the repository at this point in the history
* feat: small addition of tags and categories + home page

* test: tags & categories

* fix: extract date from datetime

* docs: remove unnecessary comment

Co-authored-by: MDLeom <[email protected]>
  • Loading branch information
achauvinhameau and curbengh authored Jul 1, 2020
1 parent b8fc737 commit abd17a4
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 21 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ sitemap:
path: sitemap.xml
template: ./sitemap_template.xml
rel: false
tags: true
categories: true
```
- **path** - Sitemap path. (Default: sitemap.xml)
- **template** - Custom template path. This file will be used to generate sitemap.xml (See [default template](/sitemap.xml))
- **rel** - Add [`rel-sitemap`](http://microformats.org/wiki/rel-sitemap) to the site's header. (Default: `false`)
- **tags** - Add site's tags
- **categories** - Add site's categories

## Exclude Posts/Pages

Expand Down
4 changes: 3 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ const { extname } = require('path');

hexo.config.sitemap = Object.assign({
path: 'sitemap.xml',
rel: false
rel: false,
tags: true,
categories: true
}, hexo.config.sitemap);

const config = hexo.config.sitemap;
Expand Down
25 changes: 15 additions & 10 deletions lib/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ const template = require('./template');

module.exports = function(locals) {
const { config } = this;
const { sitemap, skip_render } = config;
const { path, tags: tagsCfg, categories: catsCfg } = sitemap;
const skipRenderList = [
'**/*.js',
'**/*.css'
];

if (Array.isArray(config.skip_render)) {
skipRenderList.push(...config.skip_render);
} else if (typeof config.skip_render === 'string') {
if (config.skip_render.length > 0) {
skipRenderList.push(config.skip_render);
if (Array.isArray(skip_render)) {
skipRenderList.push(...skip_render);
} else if (typeof skip_render === 'string') {
if (skip_render.length > 0) {
skipRenderList.push(skip_render);
}
}

Expand All @@ -27,18 +29,21 @@ module.exports = function(locals) {
});

if (posts.length <= 0) {
config.sitemap.rel = false;
sitemap.rel = false;
return;
}

const xml = template(config).render({
const data = template(config).render({
config,
posts
posts,
sNow: new Date(),
tags: tagsCfg ? locals.tags.toArray() : [],
categories: catsCfg ? locals.categories.toArray() : []
});

return {
path: config.sitemap.path,
data: xml
path,
data
};
};

Expand Down
1 change: 1 addition & 0 deletions lib/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = function(config) {
return encodeURL(str);
});

// Extract date from datetime
env.addFilter('formatDate', input => {
return input.toISOString().substring(0, 10);
});
Expand Down
25 changes: 25 additions & 0 deletions sitemap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,29 @@
{% endif %}
</url>
{% endfor %}

<url>
<loc>{{ config.url | uriencode }}</loc>
<lastmod>{{ sNow | formatDate }}</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>

{% for tag in tags %}
<url>
<loc>{{ tag.permalink | uriencode }}</loc>
<lastmod>{{ sNow | formatDate }}</lastmod>
<changefreq>daily</changefreq>
<priority>0.6</priority>
</url>
{% endfor %}

{% for cat in categories %}
<url>
<loc>{{ cat.permalink | uriencode }}</loc>
<lastmod>{{ sNow | formatDate }}</lastmod>
<changefreq>daily</changefreq>
<priority>0.6</priority>
</url>
{% endfor %}
</urlset>
77 changes: 67 additions & 10 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
require('chai').should();
const Hexo = require('hexo');
const cheerio = require('cheerio');
const { encodeURL } = require('hexo-util');
const { deepMerge, encodeURL } = require('hexo-util');
const { ready, transform } = require('camaro');
const sitemapCfg = {
path: 'sitemap.xml',
rel: false,
tags: true,
categories: true
};

const p = async xml => {
await ready();
Expand All @@ -19,9 +25,11 @@ const p = async xml => {

describe('Sitemap generator', () => {
const hexo = new Hexo(__dirname, {silent: true});
hexo.config.sitemap = {
path: 'sitemap.xml'
};
hexo.config.sitemap = sitemapCfg;
const defaultCfg = deepMerge(hexo.config, {
sitemap: sitemapCfg
});

const Post = hexo.model('Post');
const Page = hexo.model('Page');
const generator = require('../lib/generator').bind(hexo);
Expand All @@ -36,6 +44,8 @@ describe('Sitemap generator', () => {
{source: 'bar', slug: 'bar', updated: 1e8 + 1},
{source: 'baz', slug: 'baz', updated: 1e8 - 1}
]);
await Promise.all(data.map(post => post.setTags(['lorem'])));
await Promise.all(data.map(post => post.setCategories(['ipsum'])));
posts = data;
data = await Page.insert([
{source: 'bio/index.md', path: 'bio/', updated: 1e8 - 3},
Expand All @@ -46,20 +56,67 @@ describe('Sitemap generator', () => {
locals = hexo.locals.toObject();
});

beforeEach(() => {
hexo.config = deepMerge(hexo.config, defaultCfg);
});

it('default', async () => {
const result = generator(locals);
const { items } = await p(result.data);

result.path.should.eql('sitemap.xml');
result.data.should.eql(sitemapTmpl.render({
config: hexo.config,
posts: posts
posts,
sNow: new Date(),
tags: locals.tags.toArray(),
categories: locals.categories.toArray()
}));

const { items } = await p(result.data);
items.forEach((element, index) => {
element.link.should.eql(posts[index].permalink);
element.date.should.eql(posts[index].updated.toISOString().substring(0, 10));
});
for (let i = 0; i < posts.length; i++) {
items[i].link.should.eql(posts[i].permalink);
items[i].date.should.eql(posts[i].updated.toISOString().substring(0, 10));
}
});

it('tags', async () => {
const { data } = generator(locals);
const { items } = await p(data);

const result = items.filter(({ link }) => link.includes('tags'));

const check = result.length > 0;
check.should.eql(true);
});

it('tags - disable', async () => {
hexo.config.sitemap.tags = false;
const { data } = generator(locals);
const { items } = await p(data);

const result = items.filter(({ link }) => link.includes('tags'));

result.length.should.eql(0);
});

it('categories', async () => {
const { data } = generator(locals);
const { items } = await p(data);

const result = items.filter(({ link }) => link.includes('categories'));

const check = result.length > 0;
check.should.eql(true);
});

it('categories - disable', async () => {
hexo.config.sitemap.categories = false;
const { data } = generator(locals);
const { items } = await p(data);

const result = items.filter(({ link }) => link.includes('categories'));

result.length.should.eql(0);
});

describe('skip_render', () => {
Expand Down

0 comments on commit abd17a4

Please sign in to comment.