diff --git a/README.md b/README.md index 97ff4e5..ed0dfc9 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,12 @@ You can configure this plugin in `_config.yml`. sitemap: path: sitemap.xml template: ./sitemap_template.xml + rel: false ``` - **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`) ## Excluding Posts diff --git a/index.js b/index.js index a6f3c12..087189a 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,8 @@ const { extname } = require('path'); const config = hexo.config.sitemap = Object.assign({ - path: 'sitemap.xml' + path: 'sitemap.xml', + rel: false }, hexo.config.sitemap); if (!extname(config.path)) { @@ -12,3 +13,7 @@ if (!extname(config.path)) { } hexo.extend.generator.register('sitemap', require('./lib/generator')); + +if (config.rel === true) { + hexo.extend.filter.register('after_render:html', require('./lib/rel')); +} diff --git a/lib/rel.js b/lib/rel.js new file mode 100644 index 0000000..9ed7085 --- /dev/null +++ b/lib/rel.js @@ -0,0 +1,15 @@ +'use strict'; + +const { url_for } = require('hexo-util'); + +function relSitemapInject(data) { + const { path, rel } = this.config.sitemap; + + if (!rel || data.match(/rel=['|"]?sitemap['|"]?/i)) return; + + const relSitemap = ``; + + return data.replace(/(?!<\/head>).+?<\/head>/, (str) => str.replace('', `${relSitemap}`)); +} + +module.exports = relSitemapInject; diff --git a/package.json b/package.json index 92ec42f..6b13d8b 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ ], "license": "MIT", "dependencies": { + "hexo-util": "^1.3.0", "micromatch": "^4.0.2", "nunjucks": "^3.1.6" }, diff --git a/test/index.js b/test/index.js index 316788f..2c44b08 100644 --- a/test/index.js +++ b/test/index.js @@ -68,3 +68,84 @@ describe('Sitemap generator', () => { }); }); }); + +describe('Rel-Sitemap', () => { + const hexo = new Hexo(); + hexo.config.sitemap = { + path: 'sitemap.xml', + rel: true + }; + const relSitemap = require('../lib/rel').bind(hexo); + + it('default', () => { + const content = ''; + const result = relSitemap(content); + + const $ = cheerio.load(result); + $('link[rel="sitemap"]').length.should.eql(1); + $('link[rel="sitemap"]').attr('href').should.eql(hexo.config.root + hexo.config.sitemap.path); + + result.should.eql(''); + }); + + it('prepend root', () => { + hexo.config.root = '/root/'; + const content = ''; + const result = relSitemap(content); + + const $ = cheerio.load(result); + $('link[rel="sitemap"]').attr('href').should.eql(hexo.config.root + hexo.config.sitemap.path); + + result.should.eql(''); + hexo.config.root = '/'; + }); + + it('disable', () => { + hexo.config.sitemap.rel = false; + const content = ''; + const result = relSitemap(content); + + const resultType = typeof result; + resultType.should.eql('undefined'); + hexo.config.sitemap.rel = true; + }); + + it('no duplicate tag', () => { + const content = '' + + ''; + const result = relSitemap(content); + + const resultType = typeof result; + resultType.should.eql('undefined'); + }); + + it('ignore empty head tag', () => { + const content = '' + + '' + + ''; + const result = relSitemap(content); + + const $ = cheerio.load(result); + $('link[rel="sitemap"]').length.should.eql(1); + + const expected = '' + + '' + + ''; + result.should.eql(expected); + }); + + it('apply to first non-empty head tag only', () => { + const content = '' + + '' + + ''; + const result = relSitemap(content); + + const $ = cheerio.load(result); + $('link[rel="sitemap"]').length.should.eql(1); + + const expected = '' + + '' + + ''; + result.should.eql(expected); + }); +});