mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 20:03:12 +03:00
Started moving meta data fetching to functions.
issue #6186 - Moved asset helper logic to a asset url function. - Created author image function to be used in ghost_head helper. - Created author url function to be used in the ghost_head helper. - Created canonical url function to be used in the ghost_head helper. - Moved meta_description helper logic to a function. - Moved excerpt helper logic to a function. - Created an index in data/meta to be used in ghost_head helper to get all data. - Created keyword function to be used in the ghost_head helper. - Created modified data function to be used in the ghost_head helper. - Created next url function to be used in the ghost_head helper. - Created ogType function to be used in the ghost_head helper. - Created previous url function to be used in the ghost_head helper. - Created published data function to be used in the ghost_head helper. - Created rss url function to be used in the ghost_head helper. - Created schema function to be used in the ghost_head helper. - Created structured data function to be used in the ghost_head helper. - Moved meta_title helper logic to a title function. - Moved url helper logic to a url function. - Wrote tests for all the new functions This is just the first step. I plan on refactoring the ghost head to use these new functions.
This commit is contained in:
parent
57ae36ab21
commit
1f4c01d207
@ -196,6 +196,10 @@ var _ = require('lodash'),
|
||||
src: ['core/test/unit/server_helpers/*_spec.js']
|
||||
},
|
||||
|
||||
metadata: {
|
||||
src: ['core/test/unit/metadata/*_spec.js']
|
||||
},
|
||||
|
||||
middleware: {
|
||||
src: ['core/test/unit/middleware/*_spec.js']
|
||||
},
|
||||
|
33
core/server/data/meta/asset_url.js
Normal file
33
core/server/data/meta/asset_url.js
Normal file
@ -0,0 +1,33 @@
|
||||
var config = require('../../config');
|
||||
|
||||
function getAssetUrl(context, isAdmin, minify) {
|
||||
var output = '';
|
||||
|
||||
output += config.paths.subdir + '/';
|
||||
|
||||
if (!context.match(/^favicon\.ico$/) && !context.match(/^shared/) && !context.match(/^asset/)) {
|
||||
if (isAdmin) {
|
||||
output += 'ghost/';
|
||||
} else {
|
||||
output += 'assets/';
|
||||
}
|
||||
}
|
||||
|
||||
// Get rid of any leading slash on the context
|
||||
context = context.replace(/^\//, '');
|
||||
|
||||
// replace ".foo" with ".min.foo" in production
|
||||
if (minify) {
|
||||
context = context.replace(/\.([^\.]*)$/, '.min.$1');
|
||||
}
|
||||
|
||||
output += context;
|
||||
|
||||
if (!context.match(/^favicon\.ico$/)) {
|
||||
output = output + '?v=' + config.assetHash;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
module.exports = getAssetUrl;
|
14
core/server/data/meta/author_image.js
Normal file
14
core/server/data/meta/author_image.js
Normal file
@ -0,0 +1,14 @@
|
||||
var config = require('../../config');
|
||||
|
||||
function getAuthorImage(data, absolute) {
|
||||
var context = data.context ? data.context[0] : null,
|
||||
blog = config.theme,
|
||||
contextObject = data[context] || blog;
|
||||
|
||||
if (context === 'post' && contextObject.author && contextObject.author.image) {
|
||||
return config.urlFor('image', {image: contextObject.author.image}, absolute);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = getAuthorImage;
|
14
core/server/data/meta/author_url.js
Normal file
14
core/server/data/meta/author_url.js
Normal file
@ -0,0 +1,14 @@
|
||||
var config = require('../../config');
|
||||
|
||||
function getAuthorUrl(data, absolute) {
|
||||
var context = data.context ? data.context[0] : null;
|
||||
if (data.author) {
|
||||
return config.urlFor('author', {author: data.author}, absolute);
|
||||
}
|
||||
if (data[context] && data[context].author) {
|
||||
return config.urlFor('author', {author: data[context].author}, absolute);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = getAuthorUrl;
|
9
core/server/data/meta/canonical_url.js
Normal file
9
core/server/data/meta/canonical_url.js
Normal file
@ -0,0 +1,9 @@
|
||||
var config = require('../../config'),
|
||||
getUrl = require('./url');
|
||||
|
||||
function getCanonicalUrl(data) {
|
||||
return config.urlJoin(config.getBaseUrl(false),
|
||||
getUrl(data, false));
|
||||
}
|
||||
|
||||
module.exports = getCanonicalUrl;
|
20
core/server/data/meta/cover_image.js
Normal file
20
core/server/data/meta/cover_image.js
Normal file
@ -0,0 +1,20 @@
|
||||
var config = require('../../config');
|
||||
|
||||
function getCoverImage(data) {
|
||||
var context = data.context ? data.context[0] : null,
|
||||
blog = config.theme,
|
||||
contextObject = data[context] || blog;
|
||||
|
||||
if (context === 'home' || context === 'author') {
|
||||
if (contextObject.cover) {
|
||||
return config.urlFor('image', {image: contextObject.cover}, true);
|
||||
}
|
||||
} else {
|
||||
if (contextObject.image) {
|
||||
return config.urlFor('image', {image: contextObject.image}, true);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = getCoverImage;
|
25
core/server/data/meta/description.js
Normal file
25
core/server/data/meta/description.js
Normal file
@ -0,0 +1,25 @@
|
||||
var _ = require('lodash'),
|
||||
config = require('../../config');
|
||||
|
||||
function getDescription(data, root) {
|
||||
var description = '',
|
||||
context = root ? root.context : null;
|
||||
|
||||
if (data.meta_description) {
|
||||
description = data.meta_description;
|
||||
} else if (_.contains(context, 'paged')) {
|
||||
description = '';
|
||||
} else if (_.contains(context, 'home')) {
|
||||
description = config.theme.description;
|
||||
} else if (_.contains(context, 'author') && data.author) {
|
||||
description = data.author.bio;
|
||||
} else if (_.contains(context, 'tag') && data.tag) {
|
||||
description = data.tag.meta_description;
|
||||
} else if ((_.contains(context, 'post') || _.contains(context, 'page')) && data.post) {
|
||||
description = data.post.meta_description;
|
||||
}
|
||||
|
||||
return (description || '').trim();
|
||||
}
|
||||
|
||||
module.exports = getDescription;
|
19
core/server/data/meta/excerpt.js
Normal file
19
core/server/data/meta/excerpt.js
Normal file
@ -0,0 +1,19 @@
|
||||
var downsize = require('downsize');
|
||||
|
||||
function getExcerpt(html, truncateOptions) {
|
||||
// Strip inline and bottom footnotes
|
||||
var excerpt = html.replace(/<a href="#fn.*?rel="footnote">.*?<\/a>/gi, '');
|
||||
excerpt = excerpt.replace(/<div class="footnotes"><ol>.*?<\/ol><\/div>/, '');
|
||||
// Strip other html
|
||||
excerpt = excerpt.replace(/<\/?[^>]+>/gi, '');
|
||||
excerpt = excerpt.replace(/(\r\n|\n|\r)+/gm, ' ');
|
||||
/*jslint regexp:false */
|
||||
|
||||
if (!truncateOptions.words && !truncateOptions.characters) {
|
||||
truncateOptions.words = 50;
|
||||
}
|
||||
|
||||
return downsize(excerpt, truncateOptions);
|
||||
}
|
||||
|
||||
module.exports = getExcerpt;
|
46
core/server/data/meta/index.js
Normal file
46
core/server/data/meta/index.js
Normal file
@ -0,0 +1,46 @@
|
||||
var config = require('../../config'),
|
||||
getUrl = require('./url'),
|
||||
getCanonicalUrl = require('./canonical_url'),
|
||||
getPreviousUrl = require('./previous_url'),
|
||||
getNextUrl = require('./next_url'),
|
||||
getAuthorUrl = require('./author_url'),
|
||||
getRssUrl = require('./rss_url'),
|
||||
getTitle = require('./title'),
|
||||
getDescription = require('./description'),
|
||||
getCoverImage = require('./cover_image'),
|
||||
getAuthorImage = require('./author_image'),
|
||||
getKeywords = require('./keywords'),
|
||||
getPublishedDate = require('./published_date'),
|
||||
getModifiedDate = require('./modified_date'),
|
||||
getOgType = require('./og_type'),
|
||||
getStructuredData = require('./structured_data'),
|
||||
getPostSchema = require('./schema');
|
||||
|
||||
function getMetaData(data, root) {
|
||||
var blog = config.theme, metaData;
|
||||
|
||||
metaData = {
|
||||
url: getUrl(data, true),
|
||||
canonicalUrl: getCanonicalUrl(data),
|
||||
previousUrl: getPreviousUrl(data, true),
|
||||
nextUrl: getNextUrl(data, true),
|
||||
authorUrl: getAuthorUrl(data, true),
|
||||
rssUrl: getRssUrl(data, true),
|
||||
metaTitle: getTitle(data, root),
|
||||
metaDescription: getDescription(data, root),
|
||||
coverImage: getCoverImage(data, true),
|
||||
authorImage: getAuthorImage(data, true),
|
||||
keywords: getKeywords(data),
|
||||
publishedDate: getPublishedDate(data),
|
||||
modifiedDate: getModifiedDate(data),
|
||||
ogType: getOgType(data),
|
||||
blog: blog
|
||||
};
|
||||
|
||||
metaData.structuredData = getStructuredData(metaData);
|
||||
metaData.schema = getPostSchema(metaData, data);
|
||||
|
||||
return metaData;
|
||||
}
|
||||
|
||||
module.exports = getMetaData;
|
10
core/server/data/meta/keywords.js
Normal file
10
core/server/data/meta/keywords.js
Normal file
@ -0,0 +1,10 @@
|
||||
function getKeywords(data) {
|
||||
if (data.post && data.post.tags && data.post.tags.length > 0) {
|
||||
return data.post.tags.map(function (tag) {
|
||||
return tag.name;
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = getKeywords;
|
13
core/server/data/meta/modified_date.js
Normal file
13
core/server/data/meta/modified_date.js
Normal file
@ -0,0 +1,13 @@
|
||||
function getModifiedDate(data) {
|
||||
var context = data.context ? data.context[0] : null,
|
||||
modDate;
|
||||
if (data[context]) {
|
||||
modDate = data[context].updated_at || null;
|
||||
if (modDate) {
|
||||
return new Date(modDate).toISOString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = getModifiedDate;
|
23
core/server/data/meta/next_url.js
Normal file
23
core/server/data/meta/next_url.js
Normal file
@ -0,0 +1,23 @@
|
||||
var config = require('../../config'),
|
||||
trimmedUrlpattern = /.+(?=\/page\/\d*\/)/,
|
||||
tagOrAuthorPattern = /\/(tag)|(author)\//;
|
||||
|
||||
function getNextUrl(data, absolute) {
|
||||
var trimmedUrl, next;
|
||||
|
||||
if (data.relativeUrl) {
|
||||
trimmedUrl = data.relativeUrl.match(trimmedUrlpattern);
|
||||
if (data.pagination && data.pagination.next) {
|
||||
next = '/page/' + data.pagination.next + '/';
|
||||
if (trimmedUrl) {
|
||||
next = trimmedUrl + next;
|
||||
} else if (tagOrAuthorPattern.test(data.relativeUrl)) {
|
||||
next = data.relativeUrl.slice(0, -1) + next;
|
||||
}
|
||||
return config.urlFor({relativeUrl: next, secure: data.secure}, absolute);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = getNextUrl;
|
12
core/server/data/meta/og_type.js
Normal file
12
core/server/data/meta/og_type.js
Normal file
@ -0,0 +1,12 @@
|
||||
function getOgType(data) {
|
||||
var context = data.context ? data.context[0] : null;
|
||||
if (context === 'author') {
|
||||
return 'profile';
|
||||
}
|
||||
if (context === 'post') {
|
||||
return 'article';
|
||||
}
|
||||
return 'website';
|
||||
}
|
||||
|
||||
module.exports = getOgType;
|
18
core/server/data/meta/previous_url.js
Normal file
18
core/server/data/meta/previous_url.js
Normal file
@ -0,0 +1,18 @@
|
||||
var config = require('../../config'),
|
||||
trimmedUrlpattern = /.+(?=\/page\/\d*\/)/;
|
||||
|
||||
function getPreviousUrl(data, absolute) {
|
||||
var trimmedUrl, prev;
|
||||
|
||||
if (data.relativeUrl) {
|
||||
trimmedUrl = data.relativeUrl.match(trimmedUrlpattern);
|
||||
if (data.pagination && data.pagination.prev) {
|
||||
prev = (data.pagination.prev > 1 ? '/page/' + data.pagination.prev + '/' : '/');
|
||||
prev = (trimmedUrl) ? trimmedUrl + prev : prev;
|
||||
return config.urlFor({relativeUrl: prev, secure: data.secure}, absolute);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = getPreviousUrl;
|
13
core/server/data/meta/published_date.js
Normal file
13
core/server/data/meta/published_date.js
Normal file
@ -0,0 +1,13 @@
|
||||
function getPublishedDate(data) {
|
||||
var context = data.context ? data.context[0] : null,
|
||||
pubDate;
|
||||
if (data[context]) {
|
||||
pubDate = data[context].published_at || data[context].created_at || null;
|
||||
if (pubDate) {
|
||||
return new Date(pubDate).toISOString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = getPublishedDate;
|
7
core/server/data/meta/rss_url.js
Normal file
7
core/server/data/meta/rss_url.js
Normal file
@ -0,0 +1,7 @@
|
||||
var config = require('../../config');
|
||||
|
||||
function getRssUrl(data, absolute) {
|
||||
return config.urlFor('rss', {secure: data.secure}, absolute);
|
||||
}
|
||||
|
||||
module.exports = getRssUrl;
|
111
core/server/data/meta/schema.js
Normal file
111
core/server/data/meta/schema.js
Normal file
@ -0,0 +1,111 @@
|
||||
var config = require('../../config'),
|
||||
hbs = require('express-hbs'),
|
||||
escapeExpression = hbs.handlebars.Utils.escapeExpression,
|
||||
_ = require('lodash');
|
||||
|
||||
// Creates the final schema object with values that are not null
|
||||
function trimSchema(schema) {
|
||||
var schemaObject = {};
|
||||
|
||||
_.each(schema, function (value, key) {
|
||||
if (value !== null && typeof value !== 'undefined') {
|
||||
schemaObject[key] = value;
|
||||
}
|
||||
});
|
||||
return schemaObject;
|
||||
}
|
||||
|
||||
function getPostSchema(metaData, data) {
|
||||
var schema = {
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'Article',
|
||||
publisher: metaData.blog.title,
|
||||
author: {
|
||||
'@type': 'Person',
|
||||
name: escapeExpression(data.post.author.name),
|
||||
image: metaData.authorImage,
|
||||
url: metaData.authorUrl,
|
||||
sameAs: data.post.author.website || null,
|
||||
description: data.post.author.bio ?
|
||||
escapeExpression(data.post.author.bio) :
|
||||
null
|
||||
},
|
||||
headline: escapeExpression(metaData.metaTitle),
|
||||
url: metaData.url,
|
||||
datePublished: metaData.publishedDate,
|
||||
dateModified: metaData.modifiedDate,
|
||||
image: metaData.coverImage,
|
||||
keywords: metaData.keywords && metaData.keywords.length > 0 ?
|
||||
metaData.keywords.join(', ') : null,
|
||||
description: metaData.metaDescription ?
|
||||
escapeExpression(metaData.metaDescription) :
|
||||
null
|
||||
};
|
||||
schema.author = trimSchema(schema.author);
|
||||
return trimSchema(schema);
|
||||
}
|
||||
|
||||
function getHomeSchema(metaData) {
|
||||
var schema = {
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'Website',
|
||||
publisher: escapeExpression(metaData.blog.title),
|
||||
url: metaData.url,
|
||||
image: metaData.coverImage,
|
||||
description: metaData.metaDescription ?
|
||||
escapeExpression(metaData.metaDescription) :
|
||||
null
|
||||
};
|
||||
return trimSchema(schema);
|
||||
}
|
||||
|
||||
function getTagSchema(metaData, data) {
|
||||
var schema = {
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'Series',
|
||||
publisher: escapeExpression(metaData.blog.title),
|
||||
url: metaData.url,
|
||||
image: metaData.coverImage,
|
||||
name: data.tag.name,
|
||||
description: metaData.metaDescription ?
|
||||
escapeExpression(metaData.metaDescription) :
|
||||
null
|
||||
};
|
||||
|
||||
return trimSchema(schema);
|
||||
}
|
||||
|
||||
function getAuthorSchema(metaData, data) {
|
||||
var schema = {
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'Person',
|
||||
sameAs: data.author.website || null,
|
||||
publisher: escapeExpression(metaData.blog.title),
|
||||
name: escapeExpression(data.author.name),
|
||||
url: metaData.authorUrl,
|
||||
image: metaData.coverImage,
|
||||
description: metaData.metaDescription ?
|
||||
escapeExpression(metaData.metaDescription) :
|
||||
null
|
||||
};
|
||||
|
||||
return trimSchema(schema);
|
||||
}
|
||||
|
||||
function getSchema(metaData, data) {
|
||||
if (!config.isPrivacyDisabled('useStructuredData')) {
|
||||
var context = data.context ? data.context[0] : null;
|
||||
if (context === 'post') {
|
||||
return getPostSchema(metaData, data);
|
||||
} else if (context === 'home') {
|
||||
return getHomeSchema(metaData);
|
||||
} else if (context === 'tag') {
|
||||
return getTagSchema(metaData, data);
|
||||
} else if (context === 'author') {
|
||||
return getAuthorSchema(metaData, data);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = getSchema;
|
36
core/server/data/meta/structured_data.js
Normal file
36
core/server/data/meta/structured_data.js
Normal file
@ -0,0 +1,36 @@
|
||||
function getStructuredData(metaData) {
|
||||
var structuredData,
|
||||
card = 'summary';
|
||||
|
||||
if (metaData.coverImage) {
|
||||
card = 'summary_large_image';
|
||||
}
|
||||
|
||||
structuredData = {
|
||||
'og:site_name': metaData.blog.title,
|
||||
'og:type': metaData.ogType,
|
||||
'og:title': metaData.metaTitle,
|
||||
'og:description': metaData.metaDescription,
|
||||
'og:url': metaData.canonicalUrl,
|
||||
'og:image': metaData.coverImage,
|
||||
'article:published_time': metaData.publishedDate,
|
||||
'article:modified_time': metaData.modifiedDate,
|
||||
'article:tag': metaData.keywords,
|
||||
'twitter:card': card,
|
||||
'twitter:title': metaData.metaTitle,
|
||||
'twitter:description': metaData.metaDescription,
|
||||
'twitter:url': metaData.canonicalUrl,
|
||||
'twitter:image:src': metaData.coverImage
|
||||
};
|
||||
|
||||
// return structored data removing null or undefined keys
|
||||
return Object.keys(structuredData).reduce(function (data, key) {
|
||||
var content = structuredData[key];
|
||||
if (content !== null && typeof content !== 'undefined') {
|
||||
data[key] = content;
|
||||
}
|
||||
return data;
|
||||
}, {});
|
||||
}
|
||||
|
||||
module.exports = getStructuredData;
|
31
core/server/data/meta/title.js
Normal file
31
core/server/data/meta/title.js
Normal file
@ -0,0 +1,31 @@
|
||||
var _ = require('lodash'),
|
||||
config = require('../../config');
|
||||
|
||||
function getTitle(data, root) {
|
||||
var title = '',
|
||||
context = root ? root.context : null,
|
||||
blog = config.theme,
|
||||
pagination = root ? root.pagination : null,
|
||||
pageString = '';
|
||||
|
||||
if (pagination && pagination.total > 1) {
|
||||
pageString = ' - Page ' + pagination.page;
|
||||
}
|
||||
if (data.meta_title) {
|
||||
title = data.meta_title;
|
||||
} else if (_.contains(context, 'home')) {
|
||||
title = blog.title;
|
||||
} else if (_.contains(context, 'author') && data.author) {
|
||||
title = data.author.name + pageString + ' - ' + blog.title;
|
||||
} else if (_.contains(context, 'tag') && data.tag) {
|
||||
title = data.tag.meta_title || data.tag.name + pageString + ' - ' + blog.title;
|
||||
} else if ((_.contains(context, 'post') || _.contains(context, 'page')) && data.post) {
|
||||
title = data.post.meta_title || data.post.title;
|
||||
} else {
|
||||
title = blog.title + pageString;
|
||||
}
|
||||
|
||||
return (title || '').trim();
|
||||
}
|
||||
|
||||
module.exports = getTitle;
|
24
core/server/data/meta/url.js
Normal file
24
core/server/data/meta/url.js
Normal file
@ -0,0 +1,24 @@
|
||||
var schema = require('../schema').checks,
|
||||
config = require('../../config');
|
||||
|
||||
function getUrl(data, absolute) {
|
||||
if (schema.isPost(data)) {
|
||||
return config.urlFor('post', {post: data, secure: data.secure}, absolute);
|
||||
}
|
||||
|
||||
if (schema.isTag(data)) {
|
||||
return config.urlFor('tag', {tag: data, secure: data.secure}, absolute);
|
||||
}
|
||||
|
||||
if (schema.isUser(data)) {
|
||||
return config.urlFor('author', {author: data, secure: data.secure}, absolute);
|
||||
}
|
||||
|
||||
if (schema.isNav(data)) {
|
||||
return config.urlFor('nav', {nav: data, secure: data.secure}, absolute);
|
||||
}
|
||||
|
||||
return config.urlFor(data, {}, absolute);
|
||||
}
|
||||
|
||||
module.exports = getUrl;
|
@ -3,49 +3,23 @@
|
||||
//
|
||||
// Returns the path to the specified asset. The ghost flag outputs the asset path for the Ghost admin
|
||||
|
||||
var hbs = require('express-hbs'),
|
||||
config = require('../config'),
|
||||
utils = require('./utils'),
|
||||
asset;
|
||||
var getAssetUrl = require('../data/meta/asset_url'),
|
||||
hbs = require('express-hbs');
|
||||
|
||||
asset = function (context, options) {
|
||||
var output = '',
|
||||
isAdmin,
|
||||
function asset(context, options) {
|
||||
var isAdmin,
|
||||
minify;
|
||||
|
||||
if (options && options.hash) {
|
||||
isAdmin = options.hash.ghost;
|
||||
minify = options.hash.minifyInProduction;
|
||||
}
|
||||
|
||||
output += config.paths.subdir + '/';
|
||||
|
||||
if (!context.match(/^favicon\.ico$/) && !context.match(/^shared/) && !context.match(/^asset/)) {
|
||||
if (isAdmin) {
|
||||
output += 'ghost/';
|
||||
} else {
|
||||
output += 'assets/';
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
minify = false;
|
||||
}
|
||||
|
||||
// Get rid of any leading slash on the context
|
||||
context = context.replace(/^\//, '');
|
||||
|
||||
// replace ".foo" with ".min.foo" in production
|
||||
if (utils.isProduction && minify) {
|
||||
context = context.replace('.', '.min.');
|
||||
}
|
||||
|
||||
output += context;
|
||||
|
||||
if (!context.match(/^favicon\.ico$/)) {
|
||||
output = utils.assetTemplate({
|
||||
source: output,
|
||||
version: config.assetHash
|
||||
});
|
||||
}
|
||||
|
||||
return new hbs.handlebars.SafeString(output);
|
||||
};
|
||||
return new hbs.handlebars.SafeString(
|
||||
getAssetUrl(context, isAdmin, minify)
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = asset;
|
||||
|
@ -5,37 +5,21 @@
|
||||
//
|
||||
// Defaults to words="50"
|
||||
|
||||
var hbs = require('express-hbs'),
|
||||
_ = require('lodash'),
|
||||
downsize = require('downsize'),
|
||||
excerpt;
|
||||
var hbs = require('express-hbs'),
|
||||
_ = require('lodash'),
|
||||
getMetaDataExcerpt = require('../data/meta/excerpt');
|
||||
|
||||
excerpt = function (options) {
|
||||
var truncateOptions = (options || {}).hash || {},
|
||||
excerpt;
|
||||
function excerpt(options) {
|
||||
var truncateOptions = (options || {}).hash || {};
|
||||
|
||||
truncateOptions = _.pick(truncateOptions, ['words', 'characters']);
|
||||
_.keys(truncateOptions).map(function (key) {
|
||||
truncateOptions[key] = parseInt(truncateOptions[key], 10);
|
||||
});
|
||||
|
||||
/*jslint regexp:true */
|
||||
excerpt = String(this.html);
|
||||
// Strip inline and bottom footnotes
|
||||
excerpt = excerpt.replace(/<a href="#fn.*?rel="footnote">.*?<\/a>/gi, '');
|
||||
excerpt = excerpt.replace(/<div class="footnotes"><ol>.*?<\/ol><\/div>/, '');
|
||||
// Strip other html
|
||||
excerpt = excerpt.replace(/<\/?[^>]+>/gi, '');
|
||||
excerpt = excerpt.replace(/(\r\n|\n|\r)+/gm, ' ');
|
||||
/*jslint regexp:false */
|
||||
|
||||
if (!truncateOptions.words && !truncateOptions.characters) {
|
||||
truncateOptions.words = 50;
|
||||
}
|
||||
|
||||
return new hbs.handlebars.SafeString(
|
||||
downsize(excerpt, truncateOptions)
|
||||
getMetaDataExcerpt(String(this.html), truncateOptions)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = excerpt;
|
||||
|
@ -6,31 +6,12 @@
|
||||
// We use the name meta_description to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
|
||||
var _ = require('lodash'),
|
||||
config = require('../config'),
|
||||
meta_description;
|
||||
var getMetaDataDescription = require('../data/meta/description');
|
||||
|
||||
meta_description = function (options) {
|
||||
function meta_description(options) {
|
||||
options = options || {};
|
||||
|
||||
var context = options.data.root.context,
|
||||
description;
|
||||
|
||||
if (this.meta_description) {
|
||||
description = this.meta_description; // E.g. in {{#foreach}}
|
||||
} else if (_.contains(context, 'paged')) {
|
||||
description = '';
|
||||
} else if (_.contains(context, 'home')) {
|
||||
description = config.theme.description;
|
||||
} else if (_.contains(context, 'author') && this.author) {
|
||||
description = this.author.bio;
|
||||
} else if (_.contains(context, 'tag') && this.tag) {
|
||||
description = this.tag.meta_description;
|
||||
} else if ((_.contains(context, 'post') || _.contains(context, 'page')) && this.post) {
|
||||
description = this.post.meta_description;
|
||||
}
|
||||
|
||||
return (description || '').trim();
|
||||
};
|
||||
return getMetaDataDescription(this, options.data.root) || '';
|
||||
}
|
||||
|
||||
module.exports = meta_description;
|
||||
|
@ -6,37 +6,10 @@
|
||||
// We use the name meta_title to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
|
||||
var _ = require('lodash'),
|
||||
config = require('../config'),
|
||||
meta_title;
|
||||
var getMetaDataTitle = require('../data/meta/title');
|
||||
|
||||
meta_title = function (options) {
|
||||
/*jshint unused:false*/
|
||||
var title = '',
|
||||
context = options.data.root.context,
|
||||
blog = config.theme,
|
||||
pagination = options.data.root.pagination,
|
||||
pageString = '';
|
||||
|
||||
if (pagination && pagination.total > 1) {
|
||||
pageString = ' - Page ' + pagination.page;
|
||||
}
|
||||
|
||||
if (this.meta_title) {
|
||||
title = this.meta_title; // E.g. in {{#foreach}}
|
||||
} else if (_.contains(context, 'home')) {
|
||||
title = blog.title;
|
||||
} else if (_.contains(context, 'author') && this.author) {
|
||||
title = this.author.name + pageString + ' - ' + blog.title;
|
||||
} else if (_.contains(context, 'tag') && this.tag) {
|
||||
title = this.tag.meta_title || this.tag.name + pageString + ' - ' + blog.title;
|
||||
} else if ((_.contains(context, 'post') || _.contains(context, 'page')) && this.post) {
|
||||
title = this.post.meta_title || this.post.title;
|
||||
} else {
|
||||
title = blog.title + pageString;
|
||||
}
|
||||
|
||||
return (title || '').trim();
|
||||
};
|
||||
function meta_title(options) {
|
||||
return getMetaDataTitle(this, options.data.root);
|
||||
}
|
||||
|
||||
module.exports = meta_title;
|
||||
|
@ -4,30 +4,12 @@
|
||||
// Returns the URL for the current object scope i.e. If inside a post scope will return post permalink
|
||||
// `absolute` flag outputs absolute URL, else URL is relative
|
||||
|
||||
var config = require('../config'),
|
||||
schema = require('../data/schema').checks,
|
||||
url;
|
||||
var getMetaDataUrl = require('../data/meta/url');
|
||||
|
||||
url = function (options) {
|
||||
function url(options) {
|
||||
var absolute = options && options.hash.absolute;
|
||||
|
||||
if (schema.isPost(this)) {
|
||||
return config.urlFor('post', {post: this, secure: this.secure}, absolute);
|
||||
}
|
||||
|
||||
if (schema.isTag(this)) {
|
||||
return config.urlFor('tag', {tag: this, secure: this.secure}, absolute);
|
||||
}
|
||||
|
||||
if (schema.isUser(this)) {
|
||||
return config.urlFor('author', {author: this, secure: this.secure}, absolute);
|
||||
}
|
||||
|
||||
if (schema.isNav(this)) {
|
||||
return config.urlFor('nav', {nav: this, secure: this.secure}, absolute);
|
||||
}
|
||||
|
||||
return config.urlFor(this, {}, absolute);
|
||||
};
|
||||
return getMetaDataUrl(this, absolute);
|
||||
}
|
||||
|
||||
module.exports = url;
|
||||
|
45
core/test/unit/metadata/asset_url_spec.js
Normal file
45
core/test/unit/metadata/asset_url_spec.js
Normal file
@ -0,0 +1,45 @@
|
||||
/*globals describe, it*/
|
||||
var getAssetUrl = require('../../../server/data/meta/asset_url'),
|
||||
config = require('../../../server/config');
|
||||
|
||||
describe('getAssetUrl', function () {
|
||||
it('should return asset url with just context', function () {
|
||||
var testUrl = getAssetUrl('myfile.js');
|
||||
testUrl.should.equal('/assets/myfile.js?v=' + config.assetHash);
|
||||
});
|
||||
|
||||
it('should return asset url with just context even with leading /', function () {
|
||||
var testUrl = getAssetUrl('/myfile.js');
|
||||
testUrl.should.equal('/assets/myfile.js?v=' + config.assetHash);
|
||||
});
|
||||
|
||||
it('should return ghost url if is admin', function () {
|
||||
var testUrl = getAssetUrl('myfile.js', true);
|
||||
testUrl.should.equal('/ghost/myfile.js?v=' + config.assetHash);
|
||||
});
|
||||
|
||||
it('should not add ghost to url if is admin and has asset in context', function () {
|
||||
var testUrl = getAssetUrl('asset/myfile.js', true);
|
||||
testUrl.should.equal('/asset/myfile.js?v=' + config.assetHash);
|
||||
});
|
||||
|
||||
it('should not add ghost or asset to url if favicon.ico', function () {
|
||||
var testUrl = getAssetUrl('favicon.ico');
|
||||
testUrl.should.equal('/favicon.ico');
|
||||
});
|
||||
|
||||
it('should not add ghost or asset to url has shared in it', function () {
|
||||
var testUrl = getAssetUrl('shared/myfile.js');
|
||||
testUrl.should.equal('/shared/myfile.js?v=' + config.assetHash);
|
||||
});
|
||||
|
||||
it('should return asset minified url when minify true', function () {
|
||||
var testUrl = getAssetUrl('myfile.js', false, true);
|
||||
testUrl.should.equal('/assets/myfile.min.js?v=' + config.assetHash);
|
||||
});
|
||||
|
||||
it('should not add min to anything besides the last .', function () {
|
||||
var testUrl = getAssetUrl('test.page/myfile.js', false, true);
|
||||
testUrl.should.equal('/assets/test.page/myfile.min.js?v=' + config.assetHash);
|
||||
});
|
||||
});
|
76
core/test/unit/metadata/author_image_spec.js
Normal file
76
core/test/unit/metadata/author_image_spec.js
Normal file
@ -0,0 +1,76 @@
|
||||
/*globals describe, it*/
|
||||
var getAuthorImage = require('../../../server/data/meta/author_image'),
|
||||
should = require('should'),
|
||||
config = require('../../../server/config');
|
||||
|
||||
describe('getAuthorImage', function () {
|
||||
it('should return author image url if post and has url',
|
||||
function () {
|
||||
var imageUrl = getAuthorImage({
|
||||
context: ['post'],
|
||||
post: {
|
||||
author: {
|
||||
image: '/content/images/2016/01/myimage.jpg'
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
imageUrl.should.equal('/content/images/2016/01/myimage.jpg');
|
||||
});
|
||||
|
||||
it('should return absolute author image url if post and has url',
|
||||
function () {
|
||||
var imageUrl = getAuthorImage({
|
||||
context: ['post'],
|
||||
post: {
|
||||
author: {
|
||||
image: '/content/images/2016/01/myimage.jpg'
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
imageUrl.should.not.equal('/content/images/2016/01/myimage.jpg');
|
||||
imageUrl.should.match(/\/content\/images\/2016\/01\/myimage\.jpg$/);
|
||||
});
|
||||
|
||||
it('should return null if context does not contain author image url and is a post',
|
||||
function () {
|
||||
var imageUrl = getAuthorImage({
|
||||
context: ['post'],
|
||||
post: {
|
||||
author: {
|
||||
name: 'Test Author'
|
||||
}
|
||||
}
|
||||
});
|
||||
should(imageUrl).equal(null);
|
||||
});
|
||||
|
||||
it('should return null if context does not contain author and is a post', function () {
|
||||
var imageUrl = getAuthorImage({
|
||||
context: ['post'],
|
||||
post: {}
|
||||
});
|
||||
should(imageUrl).equal(null);
|
||||
});
|
||||
|
||||
it('should return null if context is not a post', function () {
|
||||
var imageUrl = getAuthorImage({
|
||||
context: ['tag']
|
||||
});
|
||||
should(imageUrl).equal(null);
|
||||
});
|
||||
|
||||
it('should return config theme auther image if context is a post and no post',
|
||||
function () {
|
||||
config.set({
|
||||
theme: {
|
||||
author: {
|
||||
image: '/content/images/2016/01/myimage.jpg'
|
||||
}
|
||||
}
|
||||
});
|
||||
var imageUrl = getAuthorImage({
|
||||
context: ['post']
|
||||
});
|
||||
imageUrl.should.match(/\/content\/images\/2016\/01\/myimage\.jpg$/);
|
||||
});
|
||||
});
|
59
core/test/unit/metadata/author_url_spec.js
Normal file
59
core/test/unit/metadata/author_url_spec.js
Normal file
@ -0,0 +1,59 @@
|
||||
/*globals describe, it*/
|
||||
var getAuthorUrl = require('../../../server/data/meta/author_url'),
|
||||
should = require('should');
|
||||
|
||||
describe('getAuthorUrl', function () {
|
||||
it('should return author url if context contains author',
|
||||
function () {
|
||||
var authorUrl = getAuthorUrl({
|
||||
context: ['post'],
|
||||
post: {
|
||||
author: {
|
||||
slug: 'test-author'
|
||||
}
|
||||
}
|
||||
});
|
||||
authorUrl.should.equal('/author/test-author/');
|
||||
});
|
||||
|
||||
it('should return absolute author url if context contains author',
|
||||
function () {
|
||||
var authorUrl = getAuthorUrl({
|
||||
context: ['post'],
|
||||
post: {
|
||||
author: {
|
||||
slug: 'test-author'
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
authorUrl.should.not.equal('/author/test-author/');
|
||||
authorUrl.should.match(/\/author\/test-author\/$/);
|
||||
});
|
||||
|
||||
it('should return author url if data contains author',
|
||||
function () {
|
||||
var authorUrl = getAuthorUrl({
|
||||
author: {
|
||||
slug: 'test-author'
|
||||
}
|
||||
});
|
||||
authorUrl.should.equal('/author/test-author/');
|
||||
});
|
||||
|
||||
it('should return absolute author url if data contains author',
|
||||
function () {
|
||||
var authorUrl = getAuthorUrl({
|
||||
author: {
|
||||
slug: 'test-author'
|
||||
}
|
||||
}, true);
|
||||
authorUrl.should.not.equal('/author/test-author/');
|
||||
authorUrl.should.match(/\/author\/test-author\/$/);
|
||||
});
|
||||
|
||||
it('should return null if no author on data or context',
|
||||
function () {
|
||||
var authorUrl = getAuthorUrl({}, true);
|
||||
should(authorUrl).equal(null);
|
||||
});
|
||||
});
|
55
core/test/unit/metadata/canonical_url_spec.js
Normal file
55
core/test/unit/metadata/canonical_url_spec.js
Normal file
@ -0,0 +1,55 @@
|
||||
/*globals describe, it*/
|
||||
var getCanonicalUrl = require('../../../server/data/meta/canonical_url');
|
||||
|
||||
describe('getCanonicalUrl', function () {
|
||||
it('should return absolute canonical url for post', function () {
|
||||
var canonicalUrl = getCanonicalUrl({
|
||||
url: '/this-is-a-test-post/',
|
||||
html: '<h1>Test 123</h1>',
|
||||
markdown: '# Test 123',
|
||||
title: 'This is a test post',
|
||||
slug: 'this-is-a-test-post',
|
||||
secure: true
|
||||
});
|
||||
canonicalUrl.should.not.equal('/this-is-a-test-post/');
|
||||
canonicalUrl.should.match(/\/this-is-a-test-post\/$/);
|
||||
canonicalUrl.should.not.match(/^https:/);
|
||||
});
|
||||
|
||||
it('should return absolute canonical url for tag', function () {
|
||||
var canonicalUrl = getCanonicalUrl({
|
||||
parent: null,
|
||||
name: 'testing',
|
||||
slug: 'testing',
|
||||
description: 'We need testing',
|
||||
secure: true
|
||||
});
|
||||
canonicalUrl.should.not.equal('/tag/testing/');
|
||||
canonicalUrl.should.match(/\/tag\/testing\/$/);
|
||||
canonicalUrl.should.not.match(/^https:/);
|
||||
});
|
||||
|
||||
it('should return absolute canonical url for author', function () {
|
||||
var canonicalUrl = getCanonicalUrl({
|
||||
name: 'Test User',
|
||||
bio: 'This is all about testing',
|
||||
website: 'http://my-testing-site.com',
|
||||
status: 'testing',
|
||||
location: 'Wounderland',
|
||||
slug: 'test-user',
|
||||
secure: true
|
||||
});
|
||||
canonicalUrl.should.not.equal('/author/test-user/');
|
||||
canonicalUrl.should.match(/\/author\/test-user\/$/);
|
||||
canonicalUrl.should.not.match(/^https:/);
|
||||
});
|
||||
|
||||
it('should return home if empty secure data', function () {
|
||||
var canonicalUrl = getCanonicalUrl({
|
||||
secure: true
|
||||
});
|
||||
canonicalUrl.should.not.equal('/');
|
||||
canonicalUrl.should.match(/\/$/);
|
||||
canonicalUrl.should.not.match(/^https:/);
|
||||
});
|
||||
});
|
62
core/test/unit/metadata/cover_image_spec.js
Normal file
62
core/test/unit/metadata/cover_image_spec.js
Normal file
@ -0,0 +1,62 @@
|
||||
/*globals describe, it*/
|
||||
var getCoverImage = require('../../../server/data/meta/cover_image'),
|
||||
should = require('should');
|
||||
|
||||
describe('getCoverImage', function () {
|
||||
it('should return absolute cover image url for home', function () {
|
||||
var coverImageUrl = getCoverImage({
|
||||
context: ['home'],
|
||||
home: {
|
||||
cover: '/content/images/my-test-image.jpg'
|
||||
}
|
||||
});
|
||||
coverImageUrl.should.not.equal('/content/images/my-test-image.jpg');
|
||||
coverImageUrl.should.match(/\/content\/images\/my-test-image\.jpg$/);
|
||||
});
|
||||
|
||||
it('should return absolute cover image url for author', function () {
|
||||
var coverImageUrl = getCoverImage({
|
||||
context: ['author'],
|
||||
author: {
|
||||
cover: '/content/images/my-test-image.jpg'
|
||||
}
|
||||
});
|
||||
coverImageUrl.should.not.equal('/content/images/my-test-image.jpg');
|
||||
coverImageUrl.should.match(/\/content\/images\/my-test-image\.jpg$/);
|
||||
});
|
||||
|
||||
it('should return absolute image url for post', function () {
|
||||
var coverImageUrl = getCoverImage({
|
||||
context: ['post'],
|
||||
post: {
|
||||
image: '/content/images/my-test-image.jpg'
|
||||
}
|
||||
});
|
||||
coverImageUrl.should.not.equal('/content/images/my-test-image.jpg');
|
||||
coverImageUrl.should.match(/\/content\/images\/my-test-image\.jpg$/);
|
||||
});
|
||||
|
||||
it('should return null if missing image', function () {
|
||||
var coverImageUrl = getCoverImage({
|
||||
context: ['post'],
|
||||
post: {}
|
||||
});
|
||||
should(coverImageUrl).equal(null);
|
||||
});
|
||||
|
||||
it('should return null if author missing cover', function () {
|
||||
var coverImageUrl = getCoverImage({
|
||||
context: ['author'],
|
||||
author: {}
|
||||
});
|
||||
should(coverImageUrl).equal(null);
|
||||
});
|
||||
|
||||
it('should return null if home missing cover', function () {
|
||||
var coverImageUrl = getCoverImage({
|
||||
context: ['home'],
|
||||
home: {}
|
||||
});
|
||||
should(coverImageUrl).equal(null);
|
||||
});
|
||||
});
|
62
core/test/unit/metadata/description_spec.js
Normal file
62
core/test/unit/metadata/description_spec.js
Normal file
@ -0,0 +1,62 @@
|
||||
/*globals describe, it*/
|
||||
var getMetaDescription = require('../../../server/data/meta/description');
|
||||
|
||||
describe('getMetaDescription', function () {
|
||||
it('should return meta_description if on data root', function () {
|
||||
var description = getMetaDescription({
|
||||
meta_description: 'My test description.'
|
||||
});
|
||||
description.should.equal('My test description.');
|
||||
});
|
||||
|
||||
it('should return empty string if on root context contains paged', function () {
|
||||
var description = getMetaDescription({}, {
|
||||
context: ['paged']
|
||||
});
|
||||
description.should.equal('');
|
||||
});
|
||||
|
||||
it('should return data author bio if on root context contains author', function () {
|
||||
var description = getMetaDescription({
|
||||
author: {
|
||||
bio: 'Just some hack building code to make the world better.'
|
||||
}
|
||||
}, {
|
||||
context: ['author']
|
||||
});
|
||||
description.should.equal('Just some hack building code to make the world better.');
|
||||
});
|
||||
|
||||
it('should return data tag meta description if on root context contains tag', function () {
|
||||
var description = getMetaDescription({
|
||||
tag: {
|
||||
meta_description: 'Best tag ever!'
|
||||
}
|
||||
}, {
|
||||
context: ['tag']
|
||||
});
|
||||
description.should.equal('Best tag ever!');
|
||||
});
|
||||
|
||||
it('should return data post meta description if on root context contains post', function () {
|
||||
var description = getMetaDescription({
|
||||
post: {
|
||||
meta_description: 'Best post ever!'
|
||||
}
|
||||
}, {
|
||||
context: ['post']
|
||||
});
|
||||
description.should.equal('Best post ever!');
|
||||
});
|
||||
|
||||
it('should return data post meta description if on root context contains page', function () {
|
||||
var description = getMetaDescription({
|
||||
post: {
|
||||
meta_description: 'Best page ever!'
|
||||
}
|
||||
}, {
|
||||
context: ['page']
|
||||
});
|
||||
description.should.equal('Best page ever!');
|
||||
});
|
||||
});
|
59
core/test/unit/metadata/excerpt_spec.js
Normal file
59
core/test/unit/metadata/excerpt_spec.js
Normal file
@ -0,0 +1,59 @@
|
||||
/*globals describe, it*/
|
||||
var getExcerpt = require('../../../server/data/meta/excerpt');
|
||||
|
||||
describe('getExcerpt', function () {
|
||||
it('should return html excerpt with no html', function () {
|
||||
var html = '<p>There are <br />10<br> types<br/> of people in <img src="a">the world:' +
|
||||
'<img src=b alt="c"> those who <img src="@" onclick="javascript:alert(\'hello\');">' +
|
||||
'understand trinary</p>, those who don\'t <div style="" class=~/\'-,._?!|#>and' +
|
||||
'< test > those<<< test >>> who mistake it <for> binary.',
|
||||
expected = 'There are 10 types of people in the world: those who understand trinary, those who ' +
|
||||
'don\'t and those>> who mistake it <for> binary.';
|
||||
|
||||
getExcerpt(html, {}).should.equal(expected);
|
||||
});
|
||||
|
||||
it('should return html excerpt strips multiple inline footnotes', function () {
|
||||
var html = '<p>Testing<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>, ' +
|
||||
'my footnotes. And stuff. Footnote<sup id="fnref:2"><a href="#fn:2" ' +
|
||||
'rel="footnote">2</a></sup><a href="http://google.com">with a link</a> ' +
|
||||
'right after.',
|
||||
expected = 'Testing, my footnotes. And stuff. Footnotewith a link right after.';
|
||||
|
||||
getExcerpt(html, {}).should.equal(expected);
|
||||
});
|
||||
|
||||
it('should return html excerpt striping inline and bottom footnotes', function () {
|
||||
var html = '<p>Testing<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a>' +
|
||||
'</sup> a very short post with a single footnote.</p>\n' +
|
||||
'<div class="footnotes"><ol><li class="footnote" id="fn:1"><p>' +
|
||||
'<a href="https://ghost.org">https://ghost.org</a> <a href="#fnref:1" ' +
|
||||
'title="return to article">↩</a></p></li></ol></div>',
|
||||
expected = 'Testing a very short post with a single footnote.';
|
||||
|
||||
getExcerpt(html, {}).should.equal(expected);
|
||||
});
|
||||
|
||||
it('should return html excerpt truncated by word', function () {
|
||||
var html = '<p>Hello <strong>World! It\'s me!</strong></p>',
|
||||
expected = 'Hello World!';
|
||||
|
||||
getExcerpt(html, {words: '2'}).should.equal(expected);
|
||||
});
|
||||
|
||||
it('should return html excerpt truncated by words with non-ascii characters',
|
||||
function () {
|
||||
var html = '<p>Едквюэ опортэат <strong>праэчынт ючю но, квуй эю</strong></p>',
|
||||
expected = 'Едквюэ опортэат';
|
||||
|
||||
getExcerpt(html, {words: '2'}).should.equal(expected);
|
||||
});
|
||||
|
||||
it('should return html excerpt truncated by character',
|
||||
function () {
|
||||
var html = '<p>Hello <strong>World! It\'s me!</strong></p>',
|
||||
expected = 'Hello Wo';
|
||||
|
||||
getExcerpt(html, {characters: '8'}).should.equal(expected);
|
||||
});
|
||||
});
|
41
core/test/unit/metadata/keywords_spec.js
Normal file
41
core/test/unit/metadata/keywords_spec.js
Normal file
@ -0,0 +1,41 @@
|
||||
/*globals describe, it*/
|
||||
var getKeywords = require('../../../server/data/meta/keywords'),
|
||||
should = require('should');
|
||||
|
||||
describe('getKeywords', function () {
|
||||
it('should return tags as keywords if post has tags', function () {
|
||||
var keywords = getKeywords({
|
||||
post: {
|
||||
tags: [
|
||||
{name: 'one'},
|
||||
{name: 'two'},
|
||||
{name: 'three'}
|
||||
]
|
||||
}
|
||||
});
|
||||
should.deepEqual(keywords, ['one', 'two', 'three']);
|
||||
});
|
||||
|
||||
it('should return null if post has tags is empty array', function () {
|
||||
var keywords = getKeywords({
|
||||
post: {
|
||||
tags: []
|
||||
}
|
||||
});
|
||||
should.equal(keywords, null);
|
||||
});
|
||||
|
||||
it('should return null if post has no tags', function () {
|
||||
var keywords = getKeywords({
|
||||
post: {}
|
||||
});
|
||||
should.equal(keywords, null);
|
||||
});
|
||||
|
||||
it('should return null if not a post', function () {
|
||||
var keywords = getKeywords({
|
||||
author: {}
|
||||
});
|
||||
should.equal(keywords, null);
|
||||
});
|
||||
});
|
33
core/test/unit/metadata/modified_date_spec.js
Normal file
33
core/test/unit/metadata/modified_date_spec.js
Normal file
@ -0,0 +1,33 @@
|
||||
/*globals describe, it*/
|
||||
var getModifiedDate = require('../../../server/data/meta/modified_date'),
|
||||
should = require('should');
|
||||
|
||||
describe('getModifiedDate', function () {
|
||||
it('should return updated at date as ISO 8601 from context if exists', function () {
|
||||
var modDate = getModifiedDate({
|
||||
context: ['post'],
|
||||
post: {
|
||||
updated_at: new Date('2016-01-01 12:56:45.232Z')
|
||||
}
|
||||
});
|
||||
should.equal(modDate, '2016-01-01T12:56:45.232Z');
|
||||
});
|
||||
|
||||
it('should return null if no update_at date on context', function () {
|
||||
var modDate = getModifiedDate({
|
||||
context: ['author'],
|
||||
author: {}
|
||||
});
|
||||
should.equal(modDate, null);
|
||||
});
|
||||
|
||||
it('should return null if context and property do not match in name', function () {
|
||||
var modDate = getModifiedDate({
|
||||
context: ['author'],
|
||||
post: {
|
||||
updated_at: new Date('2016-01-01 12:56:45.232Z')
|
||||
}
|
||||
});
|
||||
should.equal(modDate, null);
|
||||
});
|
||||
});
|
55
core/test/unit/metadata/next_url_spec.js
Normal file
55
core/test/unit/metadata/next_url_spec.js
Normal file
@ -0,0 +1,55 @@
|
||||
/*globals describe, it*/
|
||||
var getNextUrl = require('../../../server/data/meta/next_url'),
|
||||
should = require('should');
|
||||
|
||||
describe('getNextUrl', function () {
|
||||
it('should return next url if relative url and pagination next set', function () {
|
||||
var nextUrl = getNextUrl({
|
||||
relativeUrl: '/test/page/2/',
|
||||
pagination: {
|
||||
next: '3'
|
||||
}
|
||||
});
|
||||
should.equal(nextUrl, '/test/page/3/');
|
||||
});
|
||||
|
||||
it('should return next url if with / relative url', function () {
|
||||
var nextUrl = getNextUrl({
|
||||
relativeUrl: '/',
|
||||
pagination: {
|
||||
next: '2'
|
||||
}
|
||||
});
|
||||
should.equal(nextUrl, '/page/2/');
|
||||
});
|
||||
|
||||
it('should return absolute next url if relative url and pagination next set', function () {
|
||||
var nextUrl = getNextUrl({
|
||||
relativeUrl: '/test/page/2/',
|
||||
pagination: {
|
||||
next: '3'
|
||||
}
|
||||
}, true);
|
||||
should.equal(nextUrl, 'http://127.0.0.1:2369/test/page/3/');
|
||||
});
|
||||
|
||||
it('should return null if no pagination next', function () {
|
||||
var nextUrl = getNextUrl({
|
||||
relativeUrl: '/',
|
||||
pagination: {
|
||||
prev: '2'
|
||||
}
|
||||
});
|
||||
should.equal(nextUrl, null);
|
||||
});
|
||||
|
||||
it('should return null if no relative url', function () {
|
||||
var nextUrl = getNextUrl({
|
||||
relativeUrl: '',
|
||||
pagination: {
|
||||
next: '2'
|
||||
}
|
||||
});
|
||||
should.equal(nextUrl, null);
|
||||
});
|
||||
});
|
26
core/test/unit/metadata/og_type_spec.js
Normal file
26
core/test/unit/metadata/og_type_spec.js
Normal file
@ -0,0 +1,26 @@
|
||||
/*globals describe, it*/
|
||||
var getOgType = require('../../../server/data/meta/og_type'),
|
||||
should = require('should');
|
||||
|
||||
describe('getOgType', function () {
|
||||
it('should return og type profile if context is type author', function () {
|
||||
var ogType = getOgType({
|
||||
context: ['author']
|
||||
});
|
||||
should.equal(ogType, 'profile');
|
||||
});
|
||||
|
||||
it('should return og type article if context is type post', function () {
|
||||
var ogType = getOgType({
|
||||
context: ['post']
|
||||
});
|
||||
should.equal(ogType, 'article');
|
||||
});
|
||||
|
||||
it('should return og type website if context is not author or post', function () {
|
||||
var ogType = getOgType({
|
||||
context: ['tag']
|
||||
});
|
||||
should.equal(ogType, 'website');
|
||||
});
|
||||
});
|
65
core/test/unit/metadata/previous_url_spec.js
Normal file
65
core/test/unit/metadata/previous_url_spec.js
Normal file
@ -0,0 +1,65 @@
|
||||
/*globals describe, it*/
|
||||
var getPreviousUrl = require('../../../server/data/meta/previous_url'),
|
||||
should = require('should');
|
||||
|
||||
describe('getPreviousUrl', function () {
|
||||
it('should return prev url if relative url and pagination prev set', function () {
|
||||
var prevUrl = getPreviousUrl({
|
||||
relativeUrl: '/test/page/3/',
|
||||
pagination: {
|
||||
prev: '2'
|
||||
}
|
||||
});
|
||||
should.equal(prevUrl, '/test/page/2/');
|
||||
});
|
||||
|
||||
it('should return prev url if with / relative url', function () {
|
||||
var prevUrl = getPreviousUrl({
|
||||
relativeUrl: '/',
|
||||
pagination: {
|
||||
prev: '2'
|
||||
}
|
||||
});
|
||||
should.equal(prevUrl, '/page/2/');
|
||||
});
|
||||
|
||||
it('should return prev url with no page is prev is 1', function () {
|
||||
var prevUrl = getPreviousUrl({
|
||||
relativeUrl: '/page/2/',
|
||||
pagination: {
|
||||
prev: '1'
|
||||
}
|
||||
});
|
||||
should.equal(prevUrl, '/');
|
||||
});
|
||||
|
||||
it('should return absolute prev url if relative url and pagination prev set', function () {
|
||||
var prevUrl = getPreviousUrl({
|
||||
relativeUrl: '/test/page/2/',
|
||||
pagination: {
|
||||
prev: '3'
|
||||
}
|
||||
}, true);
|
||||
should.equal(prevUrl, 'http://127.0.0.1:2369/test/page/3/');
|
||||
});
|
||||
|
||||
it('should return null if no pagination prev', function () {
|
||||
var prevUrl = getPreviousUrl({
|
||||
relativeUrl: '/',
|
||||
pagination: {
|
||||
next: '2'
|
||||
}
|
||||
});
|
||||
should.equal(prevUrl, null);
|
||||
});
|
||||
|
||||
it('should return null if no relative url', function () {
|
||||
var prevUrl = getPreviousUrl({
|
||||
relativeUrl: '',
|
||||
pagination: {
|
||||
prev: '2'
|
||||
}
|
||||
});
|
||||
should.equal(prevUrl, null);
|
||||
});
|
||||
});
|
54
core/test/unit/metadata/published_date_spec.js
Normal file
54
core/test/unit/metadata/published_date_spec.js
Normal file
@ -0,0 +1,54 @@
|
||||
/*globals describe, it*/
|
||||
var getPublishedDate = require('../../../server/data/meta/published_date'),
|
||||
should = require('should');
|
||||
|
||||
describe('getPublishedDate', function () {
|
||||
it('should return published at date as ISO 8601 from context if exists', function () {
|
||||
var pubDate = getPublishedDate({
|
||||
context: ['post'],
|
||||
post: {
|
||||
published_at: new Date('2016-01-01 12:56:45.232Z')
|
||||
}
|
||||
});
|
||||
should.equal(pubDate, '2016-01-01T12:56:45.232Z');
|
||||
});
|
||||
|
||||
it('should return created at date as ISO 8601 if no published at date', function () {
|
||||
var pubDate = getPublishedDate({
|
||||
context: ['author'],
|
||||
author: {
|
||||
created_at: new Date('2016-01-01 12:56:45.232Z')
|
||||
}
|
||||
});
|
||||
should.equal(pubDate, '2016-01-01T12:56:45.232Z');
|
||||
});
|
||||
|
||||
it('should return published at over created at date as ISO 8601 if has both', function () {
|
||||
var pubDate = getPublishedDate({
|
||||
context: ['post'],
|
||||
post: {
|
||||
published_at: new Date('2016-01-01 12:56:45.232Z'),
|
||||
created_at: new Date('2015-01-01 12:56:45.232Z')
|
||||
}
|
||||
});
|
||||
should.equal(pubDate, '2016-01-01T12:56:45.232Z');
|
||||
});
|
||||
|
||||
it('should return null if no update_at date on context', function () {
|
||||
var pubDate = getPublishedDate({
|
||||
context: ['author'],
|
||||
author: {}
|
||||
});
|
||||
should.equal(pubDate, null);
|
||||
});
|
||||
|
||||
it('should return null if context and property do not match in name', function () {
|
||||
var pubDate = getPublishedDate({
|
||||
context: ['author'],
|
||||
post: {
|
||||
published_at: new Date('2016-01-01 12:56:45.232Z')
|
||||
}
|
||||
});
|
||||
should.equal(pubDate, null);
|
||||
});
|
||||
});
|
26
core/test/unit/metadata/rss_url_spec.js
Normal file
26
core/test/unit/metadata/rss_url_spec.js
Normal file
@ -0,0 +1,26 @@
|
||||
/*globals describe, it*/
|
||||
var getRssUrl = require('../../../server/data/meta/rss_url'),
|
||||
should = require('should');
|
||||
|
||||
describe('getRssUrl', function () {
|
||||
it('should return rss url', function () {
|
||||
var rssUrl = getRssUrl({
|
||||
secure: false
|
||||
});
|
||||
should.equal(rssUrl, '/rss/');
|
||||
});
|
||||
|
||||
it('should return absolute rss url', function () {
|
||||
var rssUrl = getRssUrl({
|
||||
secure: false
|
||||
}, true);
|
||||
should.equal(rssUrl, 'http://127.0.0.1:2369/rss/');
|
||||
});
|
||||
|
||||
it('should return absolute rss url with https if secure', function () {
|
||||
var rssUrl = getRssUrl({
|
||||
secure: true
|
||||
}, true);
|
||||
should.equal(rssUrl, 'https://127.0.0.1:2369/rss/');
|
||||
});
|
||||
});
|
177
core/test/unit/metadata/schema_spec.js
Normal file
177
core/test/unit/metadata/schema_spec.js
Normal file
@ -0,0 +1,177 @@
|
||||
/*globals describe, it*/
|
||||
var getSchema = require('../../../server/data/meta/schema'),
|
||||
should = require('should');
|
||||
|
||||
describe('getSchema', function () {
|
||||
it('should return post schema if context starts with post', function () {
|
||||
var metadata = {
|
||||
blog: {
|
||||
title: 'Blog Title'
|
||||
},
|
||||
authorImage: 'http://mysite.com/author/image/url/me.jpg',
|
||||
authorUrl: 'http://mysite.com/author/me/',
|
||||
metaTitle: 'Post Title',
|
||||
url: 'http://mysite.com/post/my-post-slug/',
|
||||
publishedDate: '2015-12-25T05:35:01.234Z',
|
||||
modifiedDate: '2016-01-21T22:13:05.412Z',
|
||||
coverImage: 'http://mysite.com/content/image/mypostcoverimage.jpg',
|
||||
keywords: ['one', 'two', 'tag'],
|
||||
metaDescription: 'Post meta description'
|
||||
}, data = {
|
||||
context: ['post'],
|
||||
post: {
|
||||
author: {
|
||||
name: 'Post Author',
|
||||
website: 'http://myblogsite.com/',
|
||||
bio: 'My author bio.'
|
||||
}
|
||||
}
|
||||
}, schema = getSchema(metadata, data);
|
||||
|
||||
should.deepEqual(schema, {
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'Article',
|
||||
author: {
|
||||
'@type': 'Person',
|
||||
description: 'My author bio.',
|
||||
image: 'http://mysite.com/author/image/url/me.jpg',
|
||||
name: 'Post Author',
|
||||
sameAs: 'http://myblogsite.com/',
|
||||
url: 'http://mysite.com/author/me/'
|
||||
},
|
||||
dateModified: '2016-01-21T22:13:05.412Z',
|
||||
datePublished: '2015-12-25T05:35:01.234Z',
|
||||
description: 'Post meta description',
|
||||
headline: 'Post Title',
|
||||
image: 'http://mysite.com/content/image/mypostcoverimage.jpg',
|
||||
keywords: 'one, two, tag',
|
||||
publisher: 'Blog Title',
|
||||
url: 'http://mysite.com/post/my-post-slug/'
|
||||
});
|
||||
});
|
||||
|
||||
it('should return post schema removing null or undefined values', function () {
|
||||
var metadata = {
|
||||
blog: {
|
||||
title: 'Blog Title'
|
||||
},
|
||||
authorImage: null,
|
||||
authorUrl: 'http://mysite.com/author/me/',
|
||||
metaTitle: 'Post Title',
|
||||
url: 'http://mysite.com/post/my-post-slug/',
|
||||
publishedDate: '2015-12-25T05:35:01.234Z',
|
||||
modifiedDate: '2016-01-21T22:13:05.412Z',
|
||||
coverImage: undefined,
|
||||
keywords: [],
|
||||
metaDescription: 'Post meta description'
|
||||
}, data = {
|
||||
context: ['post'],
|
||||
post: {
|
||||
author: {
|
||||
name: 'Post Author',
|
||||
website: undefined,
|
||||
bio: null
|
||||
}
|
||||
}
|
||||
}, schema = getSchema(metadata, data);
|
||||
|
||||
should.deepEqual(schema, {
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'Article',
|
||||
author: {
|
||||
'@type': 'Person',
|
||||
name: 'Post Author',
|
||||
url: 'http://mysite.com/author/me/'
|
||||
},
|
||||
dateModified: '2016-01-21T22:13:05.412Z',
|
||||
datePublished: '2015-12-25T05:35:01.234Z',
|
||||
description: 'Post meta description',
|
||||
headline: 'Post Title',
|
||||
publisher: 'Blog Title',
|
||||
url: 'http://mysite.com/post/my-post-slug/'
|
||||
});
|
||||
});
|
||||
|
||||
it('should return home schema if context starts with home', function () {
|
||||
var metadata = {
|
||||
blog: {
|
||||
title: 'Blog Title'
|
||||
},
|
||||
url: 'http://mysite.com/post/my-post-slug/',
|
||||
coverImage: 'http://mysite.com/content/image/mypostcoverimage.jpg',
|
||||
metaDescription: 'This is the theme description'
|
||||
}, data = {
|
||||
context: ['home']
|
||||
}, schema = getSchema(metadata, data);
|
||||
|
||||
should.deepEqual(schema, {
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'Website',
|
||||
description: 'This is the theme description',
|
||||
image: 'http://mysite.com/content/image/mypostcoverimage.jpg',
|
||||
publisher: 'Blog Title',
|
||||
url: 'http://mysite.com/post/my-post-slug/'
|
||||
});
|
||||
});
|
||||
|
||||
it('should return tag schema if context starts with tag', function () {
|
||||
var metadata = {
|
||||
blog: {
|
||||
title: 'Blog Title'
|
||||
},
|
||||
url: 'http://mysite.com/post/my-post-slug/',
|
||||
coverImage: 'http://mysite.com/content/image/mypostcoverimage.jpg',
|
||||
metaDescription: 'This is the tag description!'
|
||||
}, data = {
|
||||
context: ['tag'],
|
||||
tag: {
|
||||
name: 'Great Tag'
|
||||
}
|
||||
}, schema = getSchema(metadata, data);
|
||||
|
||||
should.deepEqual(schema, {
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'Series',
|
||||
description: 'This is the tag description!',
|
||||
image: 'http://mysite.com/content/image/mypostcoverimage.jpg',
|
||||
name: 'Great Tag',
|
||||
publisher: 'Blog Title',
|
||||
url: 'http://mysite.com/post/my-post-slug/'
|
||||
});
|
||||
});
|
||||
|
||||
it('should return author schema if context starts with author', function () {
|
||||
var metadata = {
|
||||
blog: {
|
||||
title: 'Blog Title'
|
||||
},
|
||||
authorImage: 'http://mysite.com/author/image/url/me.jpg',
|
||||
authorUrl: 'http://mysite.com/author/me/',
|
||||
metaDescription: 'This is the author description!'
|
||||
}, data = {
|
||||
context: ['author'],
|
||||
author: {
|
||||
name: 'Author Name',
|
||||
website: 'http://myblogsite.com/'
|
||||
}
|
||||
}, schema = getSchema(metadata, data);
|
||||
|
||||
should.deepEqual(schema, {
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'Person',
|
||||
description: 'This is the author description!',
|
||||
name: 'Author Name',
|
||||
publisher: 'Blog Title',
|
||||
sameAs: 'http://myblogsite.com/',
|
||||
url: 'http://mysite.com/author/me/'
|
||||
});
|
||||
});
|
||||
|
||||
it('should return null if not a supported type', function () {
|
||||
var metadata = {},
|
||||
data = {},
|
||||
schema = getSchema(metadata, data);
|
||||
|
||||
should.deepEqual(schema, null);
|
||||
});
|
||||
});
|
66
core/test/unit/metadata/structured_data_spec.js
Normal file
66
core/test/unit/metadata/structured_data_spec.js
Normal file
@ -0,0 +1,66 @@
|
||||
/*globals describe, it*/
|
||||
var getStructuredData = require('../../../server/data/meta/structured_data'),
|
||||
should = require('should');
|
||||
|
||||
describe('getStructuredData', function () {
|
||||
it('should return structored data from metadata', function () {
|
||||
var metadata = {
|
||||
blog: {
|
||||
title: 'Blog Title'
|
||||
},
|
||||
ogType: 'article',
|
||||
metaTitle: 'Post Title',
|
||||
canonicalUrl: 'http://mysite.com/post/my-post-slug/',
|
||||
publishedDate: '2015-12-25T05:35:01.234Z',
|
||||
modifiedDate: '2016-01-21T22:13:05.412Z',
|
||||
coverImage: 'http://mysite.com/content/image/mypostcoverimage.jpg',
|
||||
keywords: ['one', 'two', 'tag'],
|
||||
metaDescription: 'Post meta description'
|
||||
}, structuredData = getStructuredData(metadata);
|
||||
|
||||
should.deepEqual(structuredData, {
|
||||
'article:modified_time': '2016-01-21T22:13:05.412Z',
|
||||
'article:published_time': '2015-12-25T05:35:01.234Z',
|
||||
'article:tag': ['one', 'two', 'tag'],
|
||||
'og:description': 'Post meta description',
|
||||
'og:image': 'http://mysite.com/content/image/mypostcoverimage.jpg',
|
||||
'og:site_name': 'Blog Title',
|
||||
'og:title': 'Post Title',
|
||||
'og:type': 'article',
|
||||
'og:url': 'http://mysite.com/post/my-post-slug/',
|
||||
'twitter:card': 'summary_large_image',
|
||||
'twitter:description': 'Post meta description',
|
||||
'twitter:image:src': 'http://mysite.com/content/image/mypostcoverimage.jpg',
|
||||
'twitter:title': 'Post Title',
|
||||
'twitter:url': 'http://mysite.com/post/my-post-slug/'
|
||||
});
|
||||
});
|
||||
|
||||
it('should return structored data from metadata with no nulls', function () {
|
||||
var metadata = {
|
||||
blog: {
|
||||
title: 'Blog Title'
|
||||
},
|
||||
ogType: 'article',
|
||||
metaTitle: 'Post Title',
|
||||
canonicalUrl: 'http://mysite.com/post/my-post-slug/',
|
||||
publishedDate: '2015-12-25T05:35:01.234Z',
|
||||
modifiedDate: '2016-01-21T22:13:05.412Z',
|
||||
coverImage: undefined,
|
||||
keywords: null,
|
||||
metaDescription: null
|
||||
}, structuredData = getStructuredData(metadata);
|
||||
|
||||
should.deepEqual(structuredData, {
|
||||
'article:modified_time': '2016-01-21T22:13:05.412Z',
|
||||
'article:published_time': '2015-12-25T05:35:01.234Z',
|
||||
'og:site_name': 'Blog Title',
|
||||
'og:title': 'Post Title',
|
||||
'og:type': 'article',
|
||||
'og:url': 'http://mysite.com/post/my-post-slug/',
|
||||
'twitter:card': 'summary',
|
||||
'twitter:title': 'Post Title',
|
||||
'twitter:url': 'http://mysite.com/post/my-post-slug/'
|
||||
});
|
||||
});
|
||||
});
|
144
core/test/unit/metadata/title_spec.js
Normal file
144
core/test/unit/metadata/title_spec.js
Normal file
@ -0,0 +1,144 @@
|
||||
/*globals describe, it*/
|
||||
var getTitle = require('../../../server/data/meta/title'),
|
||||
config = require('../../../server/config');
|
||||
|
||||
describe('getTitle', function () {
|
||||
it('should return meta_title if on data root', function () {
|
||||
var title = getTitle({
|
||||
meta_title: 'My test title'
|
||||
});
|
||||
title.should.equal('My test title');
|
||||
});
|
||||
|
||||
it('should return blog title if on home', function () {
|
||||
config.set({
|
||||
theme: {
|
||||
title: 'My blog title'
|
||||
}
|
||||
});
|
||||
var title = getTitle({}, {context: 'home'});
|
||||
title.should.equal('My blog title');
|
||||
});
|
||||
|
||||
it('should return author name - blog title if on data author page', function () {
|
||||
config.set({
|
||||
theme: {
|
||||
title: 'My blog title 2'
|
||||
}
|
||||
});
|
||||
var title = getTitle({
|
||||
author: {
|
||||
name: 'Author Name'
|
||||
}
|
||||
}, {context: 'author'});
|
||||
title.should.equal('Author Name - My blog title 2');
|
||||
});
|
||||
|
||||
it('should return author page title if on data author page with more then one page', function () {
|
||||
config.set({
|
||||
theme: {
|
||||
title: 'My blog title 2'
|
||||
}
|
||||
});
|
||||
var title = getTitle({
|
||||
author: {
|
||||
name: 'Author Name'
|
||||
}
|
||||
}, {
|
||||
context: 'author',
|
||||
pagination: {
|
||||
total: 40,
|
||||
page: 3
|
||||
}
|
||||
});
|
||||
title.should.equal('Author Name - Page 3 - My blog title 2');
|
||||
});
|
||||
|
||||
it('should return tag name - blog title if on data tag page no meta_title', function () {
|
||||
config.set({
|
||||
theme: {
|
||||
title: 'My blog title 3'
|
||||
}
|
||||
});
|
||||
var title = getTitle({
|
||||
tag: {
|
||||
name: 'Tag Name'
|
||||
}
|
||||
}, {context: 'tag'});
|
||||
title.should.equal('Tag Name - My blog title 3');
|
||||
});
|
||||
|
||||
it('should return tag name - page - blog title if on data tag page no meta_title', function () {
|
||||
config.set({
|
||||
theme: {
|
||||
title: 'My blog title 3'
|
||||
}
|
||||
});
|
||||
var title = getTitle({
|
||||
tag: {
|
||||
name: 'Tag Name'
|
||||
}
|
||||
}, {
|
||||
context: 'tag',
|
||||
pagination: {
|
||||
total: 40,
|
||||
page: 39
|
||||
}
|
||||
});
|
||||
title.should.equal('Tag Name - Page 39 - My blog title 3');
|
||||
});
|
||||
|
||||
it('should return tag meta_title if in tag data', function () {
|
||||
var title = getTitle({
|
||||
tag: {
|
||||
name: 'Tag Name',
|
||||
meta_title: 'My Tag Meta Title!'
|
||||
}
|
||||
}, {context: 'tag'});
|
||||
title.should.equal('My Tag Meta Title!');
|
||||
});
|
||||
|
||||
it('should return post title if in post context', function () {
|
||||
var title = getTitle({
|
||||
post: {
|
||||
title: 'My awesome post!'
|
||||
}
|
||||
}, {context: 'post'});
|
||||
title.should.equal('My awesome post!');
|
||||
});
|
||||
|
||||
it('should return post title if in page context', function () {
|
||||
var title = getTitle({
|
||||
post: {
|
||||
title: 'My awesome page!'
|
||||
}
|
||||
}, {context: 'page'});
|
||||
title.should.equal('My awesome page!');
|
||||
});
|
||||
|
||||
it('should return post meta_title if in post data', function () {
|
||||
var title = getTitle({
|
||||
post: {
|
||||
name: 'My awesome post!',
|
||||
meta_title: 'My Tag Meta Title Post! '
|
||||
}
|
||||
}, {context: 'post'});
|
||||
title.should.equal('My Tag Meta Title Post!');
|
||||
});
|
||||
|
||||
it('should return blog title with page if unknown type', function () {
|
||||
config.set({
|
||||
theme: {
|
||||
title: 'My blog title 4'
|
||||
}
|
||||
});
|
||||
var title = getTitle({}, {
|
||||
context: 'paged',
|
||||
pagination: {
|
||||
total: 40,
|
||||
page: 35
|
||||
}
|
||||
});
|
||||
title.should.equal('My blog title 4 - Page 35');
|
||||
});
|
||||
});
|
99
core/test/unit/metadata/url_spec.js
Normal file
99
core/test/unit/metadata/url_spec.js
Normal file
@ -0,0 +1,99 @@
|
||||
/*globals describe, it*/
|
||||
var getUrl = require('../../../server/data/meta/url');
|
||||
|
||||
describe('getUrl', function () {
|
||||
it('should return url for a post', function () {
|
||||
var url = getUrl({
|
||||
html: '<p>Welcome to my post.</p>',
|
||||
markdown: 'Welcome to my post.',
|
||||
title: 'Welcome Post',
|
||||
slug: 'welcome-post',
|
||||
url: '/post/welcome-post/'
|
||||
});
|
||||
url.should.equal('/post/welcome-post/');
|
||||
});
|
||||
|
||||
it('should return absolute url for a post', function () {
|
||||
var url = getUrl({
|
||||
html: '<p>Welcome to my post.</p>',
|
||||
markdown: 'Welcome to my post.',
|
||||
title: 'Welcome Post',
|
||||
slug: 'welcome-post',
|
||||
url: '/post/welcome-post/'
|
||||
}, true);
|
||||
url.should.equal('http://127.0.0.1:2369/post/welcome-post/');
|
||||
});
|
||||
|
||||
it('should return url for a tag', function () {
|
||||
var url = getUrl({
|
||||
name: 'Great',
|
||||
slug: 'great',
|
||||
description: 'My great tag',
|
||||
parent: null
|
||||
});
|
||||
url.should.equal('/tag/great/');
|
||||
});
|
||||
|
||||
it('should return secure absolute url for a tag', function () {
|
||||
var url = getUrl({
|
||||
name: 'Great',
|
||||
slug: 'great',
|
||||
description: 'My great tag',
|
||||
parent: null,
|
||||
secure: true
|
||||
}, true);
|
||||
url.should.equal('https://127.0.0.1:2369/tag/great/');
|
||||
});
|
||||
|
||||
it('should return url for a author', function () {
|
||||
var url = getUrl({
|
||||
name: 'Author Name',
|
||||
bio: 'I am fun bio!',
|
||||
website: 'http://myoksite.com',
|
||||
status: 'active',
|
||||
location: 'London',
|
||||
slug: 'author-name'
|
||||
});
|
||||
url.should.equal('/author/author-name/');
|
||||
});
|
||||
|
||||
it('should return secure absolute url for a author', function () {
|
||||
var url = getUrl({
|
||||
name: 'Author Name',
|
||||
bio: 'I am fun bio!',
|
||||
website: 'http://myoksite.com',
|
||||
status: 'active',
|
||||
location: 'London',
|
||||
slug: 'author-name',
|
||||
secure: true
|
||||
}, true);
|
||||
url.should.equal('https://127.0.0.1:2369/author/author-name/');
|
||||
});
|
||||
|
||||
it('should return url for a nav', function () {
|
||||
var url = getUrl({
|
||||
label: 'About Me',
|
||||
url: '/about-me/',
|
||||
slug: 'about-me',
|
||||
current: true
|
||||
});
|
||||
url.should.equal('/about-me/');
|
||||
});
|
||||
|
||||
it('should return absolute url for a nav', function () {
|
||||
var url = getUrl({
|
||||
label: 'About Me',
|
||||
url: '/about-me/',
|
||||
slug: 'about-me',
|
||||
current: true
|
||||
}, true);
|
||||
url.should.equal('http://127.0.0.1:2369/about-me/');
|
||||
});
|
||||
|
||||
it('should return url for a context object with relative url', function () {
|
||||
var url = getUrl({
|
||||
relativeUrl: '/my/relitive/url/'
|
||||
});
|
||||
url.should.equal('/my/relitive/url/');
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user