Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add url_for and full_url_for tag plugins #5198

Merged
merged 2 commits into from
Jun 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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');
});
});