Skip to content

Commit

Permalink
feat: add url_for and full_url_for tag plugins (#5198)
Browse files Browse the repository at this point in the history
* feat: add url_for and full_url_for tag plugins

* style: fix lint
  • Loading branch information
D-Sketon authored Jun 3, 2023
1 parent 5ee3e6d commit c9ad8c6
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 0 deletions.
17 changes: 17 additions & 0 deletions lib/plugins/tag/full_url_for.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { full_url_for, htmlTag } from 'hexo-util';

/**
* Full url for tag
*
* Syntax:
* {% full_url_for text path %}
*/
export = ctx => {
return function fullUrlForTag([text, path]) {
const url = full_url_for.call(ctx, path);
const attrs = {
href: url
};
return htmlTag('a', attrs, text);
};
};
3 changes: 3 additions & 0 deletions lib/plugins/tag/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export default (ctx: Hexo) => {
tag.register('asset_image', assetImg);

tag.register('pullquote', require('./pullquote')(ctx), true);

tag.register('url_for', require('./url_for')(ctx));
tag.register('full_url_for', require('./full_url_for')(ctx));
};

// Use WeakMap to track different ctx (in case there is any)
Expand Down
17 changes: 17 additions & 0 deletions lib/plugins/tag/url_for.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { url_for, htmlTag } from 'hexo-util';

/**
* Url for tag
*
* Syntax:
* {% url_for text path [relative] %}
*/
export = ctx => {
return function urlForTag([text, path, relative]) {
const url = url_for.call(ctx, path, relative ? { relative: relative !== 'false' } : undefined);
const attrs = {
href: url
};
return htmlTag('a', attrs, text);
};
};
62 changes: 62 additions & 0 deletions test/scripts/tags/full_url_for.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use strict';

const cheerio = require('cheerio');

describe('full_url_for', () => {
const ctx = {
config: { url: 'https://example.com' }
};

const fullUrlForTag = require('../../../dist/plugins/tag/full_url_for')(ctx);
const fullUrlFor = args => fullUrlForTag(args.split(' '));

it('no path input', () => {
const $ = cheerio.load(fullUrlFor('nopath'));
$('a').attr('href').should.eql(ctx.config.url + '/');
$('a').html().should.eql('nopath');
});

it('internal url', () => {
let $ = cheerio.load(fullUrlFor('index index.html'));
$('a').attr('href').should.eql(ctx.config.url + '/index.html');
$('a').html().should.eql('index');

$ = cheerio.load(fullUrlFor('index /'));
$('a').attr('href').should.eql(ctx.config.url + '/');
$('a').html().should.eql('index');

$ = cheerio.load(fullUrlFor('index /index.html'));
$('a').attr('href').should.eql(ctx.config.url + '/index.html');
$('a').html().should.eql('index');
});

it('internel url (pretty_urls.trailing_index disabled)', () => {
ctx.config.pretty_urls = { trailing_index: false };
let $ = cheerio.load(fullUrlFor('index index.html'));
$('a').attr('href').should.eql(ctx.config.url + '/');
$('a').html().should.eql('index');

$ = cheerio.load(fullUrlFor('index /index.html'));
$('a').attr('href').should.eql(ctx.config.url + '/');
$('a').html().should.eql('index');
});

it('external url', () => {
[
'https://hexo.io/',
'//google.com/',
// 'index.html' in external link should not be removed
'//google.com/index.html'
].forEach(url => {
const $ = cheerio.load(fullUrlFor(`external ${url}`));
$('a').attr('href').should.eql(url);
$('a').html().should.eql('external');
});
});

it('only hash', () => {
const $ = cheerio.load(fullUrlFor('hash #test'));
$('a').attr('href').should.eql(ctx.config.url + '/#test');
$('a').html().should.eql('hash');
});
});
2 changes: 2 additions & 0 deletions test/scripts/tags/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ describe('Tags', () => {
require('./asset_path');
require('./blockquote');
require('./code');
require('./full_url_for');
require('./iframe');
require('./img');
require('./include_code');
require('./link');
require('./post_link');
require('./post_path');
require('./pullquote');
require('./url_for');
});
121 changes: 121 additions & 0 deletions test/scripts/tags/url_for.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
'use strict';

const cheerio = require('cheerio');

describe('url_for', () => {
const ctx = {
config: { url: 'https://example.com' }
};

const urlForTag = require('../../../dist/plugins/tag/url_for')(ctx);
const urlFor = args => urlForTag(args.split(' '));

it('should encode path', () => {
ctx.config.root = '/';
let $ = cheerio.load(urlFor('foo fôo.html'));
$('a').attr('href').should.eql('/f%C3%B4o.html');
$('a').html().should.eql('foo');

ctx.config.root = '/fôo/';
$ = cheerio.load(urlFor('foo bár.html'));
$('a').attr('href').should.eql('/f%C3%B4o/b%C3%A1r.html');
$('a').html().should.eql('foo');
});

it('internal url (relative off)', () => {
ctx.config.root = '/';
let $ = cheerio.load(urlFor('index index.html'));
$('a').attr('href').should.eql('/index.html');
$('a').html().should.eql('index');

$ = cheerio.load(urlFor('index /'));
$('a').attr('href').should.eql('/');
$('a').html().should.eql('index');

$ = cheerio.load(urlFor('index /index.html'));
$('a').attr('href').should.eql('/index.html');
$('a').html().should.eql('index');

ctx.config.root = '/blog/';
$ = cheerio.load(urlFor('index index.html'));
$('a').attr('href').should.eql('/blog/index.html');
$('a').html().should.eql('index');

$ = cheerio.load(urlFor('index /'));
$('a').attr('href').should.eql('/blog/');
$('a').html().should.eql('index');

$ = cheerio.load(urlFor('index /index.html'));
$('a').attr('href').should.eql('/blog/index.html');
$('a').html().should.eql('index');
});

it('internal url (relative on)', () => {
ctx.config.relative_link = true;
ctx.config.root = '/';

ctx.path = '';
let $ = cheerio.load(urlFor('index index.html'));
$('a').attr('href').should.eql('index.html');
$('a').html().should.eql('index');

ctx.path = 'foo/bar/';
$ = cheerio.load(urlFor('index index.html'));
$('a').attr('href').should.eql('../../index.html');
$('a').html().should.eql('index');

ctx.config.relative_link = false;
});

it('internal url (options.relative)', () => {
ctx.path = '';
let $ = cheerio.load(urlFor('index index.html true'));
$('a').attr('href').should.eql('index.html');
$('a').html().should.eql('index');

ctx.config.relative_link = true;
$ = cheerio.load(urlFor('index index.html false'));
$('a').attr('href').should.eql('/index.html');
$('a').html().should.eql('index');
ctx.config.relative_link = false;
});

it('internel url (pretty_urls.trailing_index disabled)', () => {
ctx.config.pretty_urls = { trailing_index: false };
ctx.path = '';
ctx.config.root = '/';
let $ = cheerio.load(urlFor('index index.html'));
$('a').attr('href').should.eql('/');
$('a').html().should.eql('index');
$ = cheerio.load(urlFor('index /index.html'));
$('a').attr('href').should.eql('/');
$('a').html().should.eql('index');

ctx.config.root = '/blog/';
$ = cheerio.load(urlFor('index index.html'));
$('a').attr('href').should.eql('/blog/');
$('a').html().should.eql('index');
$ = cheerio.load(urlFor('index /index.html'));
$('a').attr('href').should.eql('/blog/');
$('a').html().should.eql('index');
});

it('external url', () => {
[
'https://hexo.io/',
'//google.com/',
// 'index.html' in external link should not be removed
'//google.com/index.html'
].forEach(url => {
const $ = cheerio.load(urlFor(`external ${url}`));
$('a').attr('href').should.eql(url);
$('a').html().should.eql('external');
});
});

it('only hash', () => {
const $ = cheerio.load(urlFor('hash #test'));
$('a').attr('href').should.eql('#test');
$('a').html().should.eql('hash');
});
});

0 comments on commit c9ad8c6

Please sign in to comment.