Update urlFor to handle 'nav' contexts

needed for #4852
Before this, calling `{{url}}` with a nav context from #4541 would
output `/`. This adds a check in `urlFor` that looks for keys in a
nav context object, namely `slug`, `current`, `label`, & `url`.

This change allows for a url to pass through if used in a nav context.

* adds `schema.isNav()`
* adds tests to `url_spec.js`
* handles absolute urls correctly even if `absolute=true`
This commit is contained in:
Marcos Ojeda 2015-01-27 21:57:19 -08:00
parent c764503224
commit 6f457768a2
4 changed files with 76 additions and 2 deletions

View File

@ -102,7 +102,8 @@ function urlPathForPost(post, permalinks) {
function urlFor(context, data, absolute) {
var urlPath = '/',
secure, imagePathRe,
knownObjects = ['post', 'tag', 'author', 'image'], baseUrl,
knownObjects = ['post', 'tag', 'author', 'image', 'nav'], baseUrl,
hostname,
// this will become really big
knownPaths = {
@ -151,6 +152,20 @@ function urlFor(context, data, absolute) {
} else if (context === 'sitemap-xsl') {
absolute = true;
urlPath = '/sitemap.xsl';
} else if (context === 'nav' && data.nav) {
urlPath = data.nav.url;
baseUrl = (secure && ghostConfig.urlSSL) ? ghostConfig.urlSSL : ghostConfig.url;
hostname = baseUrl.split('//')[1] + ghostConfig.paths.subdir;
if (urlPath.indexOf(hostname) > -1) {
// make link relative to account for possible
// mismatch in http/https etc, force absolute
urlPath = '/' + urlPath.split(hostname)[1];
absolute = true;
} else { // not hosted on this ghost instance, so
// urls with protocols are already absolute
// and otherwise respect the passed in value
absolute = (urlPath.indexOf('://') === -1) && absolute;
}
}
// other objects are recognised but not yet supported
} else if (_.isString(context) && _.indexOf(_.keys(knownPaths), context) !== -1) {

View File

@ -198,9 +198,15 @@ function isUser(jsonData) {
jsonData.hasOwnProperty('status') && jsonData.hasOwnProperty('location');
}
function isNav(jsonData) {
return jsonData.hasOwnProperty('label') && jsonData.hasOwnProperty('url') &&
jsonData.hasOwnProperty('slug') && jsonData.hasOwnProperty('current');
}
module.exports.tables = db;
module.exports.checks = {
isPost: isPost,
isTag: isTag,
isUser: isUser
isUser: isUser,
isNav: isNav
};

View File

@ -23,6 +23,10 @@ url = function (options) {
return config.urlFor('author', {author: this}, absolute);
}
if (schema.isNav(this)) {
return config.urlFor('nav', {nav: this}, absolute);
}
return config.urlFor(this, absolute);
};

View File

@ -93,4 +93,53 @@ describe('{{url}} helper', function () {
should.exist(rendered);
rendered.should.equal('/');
});
it('should return a relative url if passed through a nav context', function () {
var rendered = helpers.url.call(
{url: '/foo', label: 'Foo', slug: 'foo', current: true});
should.exist(rendered);
rendered.should.equal('/foo');
});
it('should return an absolute url if passed through a nav context', function () {
var rendered = helpers.url.call(
{url: '/bar', label: 'Bar', slug: 'bar', current: true},
{hash: {absolute: 'true'}});
should.exist(rendered);
rendered.should.equal('http://testurl.com/bar');
});
it('external urls should be retained in a nav context', function () {
var rendered = helpers.url.call(
{url: 'http://casper.website/baz', label: 'Baz', slug: 'baz', current: true},
{hash: {absolute: 'true'}});
should.exist(rendered);
rendered.should.equal('http://casper.website/baz');
});
it('should handle hosted urls in a nav context', function () {
var rendered = helpers.url.call(
{url: 'http://testurl.com/qux', label: 'Qux', slug: 'qux', current: true},
{hash: {absolute: 'true'}});
should.exist(rendered);
rendered.should.equal('http://testurl.com/qux');
});
it('should handle hosted urls with the wrong protocol in a nav context', function () {
var rendered = helpers.url.call(
{url: 'https://testurl.com/quux', label: 'Quux', slug: 'quux', current: true},
{hash: {absolute: 'true'}});
should.exist(rendered);
rendered.should.equal('http://testurl.com/quux');
});
it('should handle subdir being set in nav context', function () {
utils.overrideConfig({url: 'http://testurl.com/blog'});
var rendered = helpers.url.call(
{url: '/xyzzy', label: 'xyzzy', slug: 'xyzzy', current: true},
{hash: {absolute: 'true'}});
should.exist(rendered);
rendered.should.equal('http://testurl.com/blog/xyzzy');
});
});