Moved utils/url.js to UrlService

refs #9178

- we have to take care that we don't end up in circular dependencies
  - e.g. API requires UrlService and UrlService needs to require the API (for requesting data)
- update the references
- we would like to get rid of the utils folder, this is/was the most complicated change
This commit is contained in:
kirrg001 2017-12-11 19:14:05 +01:00 committed by Katharina Irrgang
parent 7d99ee8466
commit 4265afe580
85 changed files with 598 additions and 557 deletions

View File

@ -8,22 +8,22 @@
require('./core/server/overrides'); require('./core/server/overrides');
var config = require('./core/server/config'), var config = require('./core/server/config'),
utils = require('./core/server/utils'), urlService = require('./core/server/services/url'),
_ = require('lodash'), _ = require('lodash'),
chalk = require('chalk'), chalk = require('chalk'),
fs = require('fs-extra'), fs = require('fs-extra'),
KnexMigrator = require('knex-migrator'), KnexMigrator = require('knex-migrator'),
knexMigrator = new KnexMigrator({ knexMigrator = new KnexMigrator({
knexMigratorFilePath: config.get('paths:appRoot') knexMigratorFilePath: config.get('paths:appRoot')
}), }),
path = require('path'), path = require('path'),
escapeChar = process.platform.match(/^win/) ? '^' : '\\', escapeChar = process.platform.match(/^win/) ? '^' : '\\',
cwd = process.cwd().replace(/( |\(|\))/g, escapeChar + '$1'), cwd = process.cwd().replace(/( |\(|\))/g, escapeChar + '$1'),
buildDirectory = path.resolve(cwd, '.build'), buildDirectory = path.resolve(cwd, '.build'),
distDirectory = path.resolve(cwd, '.dist'), distDirectory = path.resolve(cwd, '.dist'),
// ## Grunt configuration // ## Grunt configuration
@ -230,8 +230,8 @@ var config = require('./core/server/config'),
var upstream = grunt.option('upstream') || process.env.GHOST_UPSTREAM || 'upstream'; var upstream = grunt.option('upstream') || process.env.GHOST_UPSTREAM || 'upstream';
grunt.log.writeln('Pulling down the latest master from ' + upstream); grunt.log.writeln('Pulling down the latest master from ' + upstream);
return 'git checkout master; git pull ' + upstream + ' master; ' + return 'git checkout master; git pull ' + upstream + ' master; ' +
'yarn; git submodule foreach "git checkout master && git pull ' + 'yarn; git submodule foreach "git checkout master && git pull ' +
upstream + ' master"'; upstream + ' master"';
} }
}, },
@ -349,7 +349,7 @@ var config = require('./core/server/config'),
watch: { watch: {
projects: { projects: {
'core/client': ['shell:ember:watch', '--live-reload-base-url="' + utils.url.getSubdir() + '/ghost/"'] 'core/client': ['shell:ember:watch', '--live-reload-base-url="' + urlService.utils.getSubdir() + '/ghost/"']
} }
} }
}, },

View File

@ -1,11 +1,11 @@
var Promise = require('bluebird'), var Promise = require('bluebird'),
moment = require('moment'), moment = require('moment'),
localUtils = require(__dirname + '/../utils'), localUtils = require('../utils'),
events = require(__dirname + '/../../../events'), events = require('../../../events'),
errors = require(__dirname + '/../../../errors'), errors = require('../../../errors'),
models = require(__dirname + '/../../../models'), models = require('../../../models'),
schedules = require(__dirname + '/../../../api/schedules'), schedules = require('../../../api/schedules'),
utils = require(__dirname + '/../../../utils'), urlService = require('../../../services/url'),
_private = {}; _private = {};
_private.normalize = function normalize(options) { _private.normalize = function normalize(options) {
@ -15,7 +15,7 @@ _private.normalize = function normalize(options) {
return { return {
time: moment(object.get('published_at')).valueOf(), time: moment(object.get('published_at')).valueOf(),
url: utils.url.urlJoin(apiUrl, 'schedules', 'posts', object.get('id')) + '?client_id=' + client.get('slug') + '&client_secret=' + client.get('secret'), url: urlService.utils.urlJoin(apiUrl, 'schedules', 'posts', object.get('id')) + '?client_id=' + client.get('slug') + '&client_secret=' + client.get('secret'),
extra: { extra: {
httpMethod: 'PUT', httpMethod: 'PUT',
oldTime: object.updated('published_at') ? moment(object.updated('published_at')).valueOf() : null oldTime: object.updated('published_at') ? moment(object.updated('published_at')).valueOf() : null

View File

@ -11,7 +11,8 @@ var serveStatic = require('express').static,
config = require('../../config'), config = require('../../config'),
errors = require('../../errors'), errors = require('../../errors'),
i18n = require('../../i18n'), i18n = require('../../i18n'),
utils = require('../../utils'), globalUtils = require('../../utils'),
urlService = require('../../services/url'),
logging = require('../../logging'), logging = require('../../logging'),
StorageBase = require('ghost-storage-base'); StorageBase = require('ghost-storage-base');
@ -47,8 +48,8 @@ class LocalFileStore extends StorageBase {
// The src for the image must be in URI format, not a file system path, which in Windows uses \ // The src for the image must be in URI format, not a file system path, which in Windows uses \
// For local file system storage can use relative path so add a slash // For local file system storage can use relative path so add a slash
var fullUrl = ( var fullUrl = (
utils.url.urlJoin('/', utils.url.getSubdir(), urlService.utils.urlJoin('/', urlService.utils.getSubdir(),
utils.url.STATIC_IMAGE_URL_PREFIX, urlService.utils.STATIC_IMAGE_URL_PREFIX,
path.relative(self.storagePath, targetFilename)) path.relative(self.storagePath, targetFilename))
).replace(new RegExp('\\' + path.sep, 'g'), '/'); ).replace(new RegExp('\\' + path.sep, 'g'), '/');
@ -85,7 +86,7 @@ class LocalFileStore extends StorageBase {
return serveStatic( return serveStatic(
self.storagePath, self.storagePath,
{ {
maxAge: utils.ONE_YEAR_MS, maxAge: globalUtils.ONE_YEAR_MS,
fallthrough: false, fallthrough: false,
onEnd: function onEnd() { onEnd: function onEnd() {
logging.info('LocalFileStorage.serve', req.path, moment().diff(startedAtMoment, 'ms') + 'ms'); logging.info('LocalFileStorage.serve', req.path, moment().diff(startedAtMoment, 'ms') + 'ms');

View File

@ -1,4 +1,4 @@
var globalUtils = require('../../utils'); var urlService = require('../../services/url');
/** /**
* @TODO: move `index.js` to here - e.g. storageUtils.getStorage * @TODO: move `index.js` to here - e.g. storageUtils.getStorage
@ -15,8 +15,8 @@ var globalUtils = require('../../utils');
*/ */
exports.getLocalFileStoragePath = function getLocalFileStoragePath(imagePath) { exports.getLocalFileStoragePath = function getLocalFileStoragePath(imagePath) {
// The '/' in urlJoin is necessary to add the '/' to `content/images`, if no subdirectory is setup // The '/' in urlJoin is necessary to add the '/' to `content/images`, if no subdirectory is setup
var urlRegExp = new RegExp('^' + globalUtils.url.urlJoin(globalUtils.url.urlFor('home', true), globalUtils.url.getSubdir(), '/', globalUtils.url.STATIC_IMAGE_URL_PREFIX)), var urlRegExp = new RegExp('^' + urlService.utils.urlJoin(urlService.utils.urlFor('home', true), urlService.utils.getSubdir(), '/', urlService.utils.STATIC_IMAGE_URL_PREFIX)),
filePathRegExp = new RegExp('^' + globalUtils.url.urlJoin(globalUtils.url.getSubdir(), '/', globalUtils.url.STATIC_IMAGE_URL_PREFIX)); filePathRegExp = new RegExp('^' + urlService.utils.urlJoin(urlService.utils.getSubdir(), '/', urlService.utils.STATIC_IMAGE_URL_PREFIX));
if (imagePath.match(urlRegExp)) { if (imagePath.match(urlRegExp)) {
return imagePath.replace(urlRegExp, ''); return imagePath.replace(urlRegExp, '');

View File

@ -4,6 +4,7 @@ var Promise = require('bluebird'),
pipeline = require('../utils/pipeline'), pipeline = require('../utils/pipeline'),
mail = require('./../mail'), mail = require('./../mail'),
globalUtils = require('../utils'), globalUtils = require('../utils'),
urlService = require('../services/url'),
apiUtils = require('./utils'), apiUtils = require('./utils'),
models = require('../models'), models = require('../models'),
config = require('../config'), config = require('../config'),
@ -184,8 +185,8 @@ authentication = {
} }
function sendResetNotification(data) { function sendResetNotification(data) {
var adminUrl = globalUtils.url.urlFor('admin', true), var adminUrl = urlService.utils.urlFor('admin', true),
resetUrl = globalUtils.url.urlJoin(adminUrl, 'reset', globalUtils.encodeBase64URLsafe(data.resetToken), '/'); resetUrl = urlService.utils.urlJoin(adminUrl, 'reset', globalUtils.encodeBase64URLsafe(data.resetToken), '/');
return mail.utils.generateContent({ return mail.utils.generateContent({
data: { data: {

View File

@ -2,7 +2,7 @@
// RESTful API for browsing the configuration // RESTful API for browsing the configuration
var Promise = require('bluebird'), var Promise = require('bluebird'),
_ = require('lodash'), _ = require('lodash'),
apiUtils = require('../utils'), urlService = require('../services/url'),
models = require('../models'), models = require('../models'),
config = require('../config'), config = require('../config'),
settingsCache = require('../settings/cache'), settingsCache = require('../settings/cache'),
@ -27,7 +27,7 @@ function getBaseConfig() {
return { return {
useGravatar: !config.isPrivacyDisabled('useGravatar'), useGravatar: !config.isPrivacyDisabled('useGravatar'),
publicAPI: config.get('publicAPI') === true, publicAPI: config.get('publicAPI') === true,
blogUrl: apiUtils.url.urlFor('home', true), blogUrl: urlService.utils.urlFor('home', true),
blogTitle: settingsCache.get('title'), blogTitle: settingsCache.get('title'),
routeKeywords: config.get('routeKeywords'), routeKeywords: config.get('routeKeywords'),
clientExtensions: config.get('clientExtensions') clientExtensions: config.get('clientExtensions')

View File

@ -11,7 +11,7 @@ var Promise = require('bluebird'),
models = require('../models'), models = require('../models'),
config = require('../config'), config = require('../config'),
errors = require('../errors'), errors = require('../errors'),
utilsUrl = require('../utils/url'), urlService = require('../services/url'),
docName = 'db', docName = 'db',
db; db;
@ -36,7 +36,7 @@ db = {
return Promise.props(props) return Promise.props(props)
.then(function successMessage(exportResult) { .then(function successMessage(exportResult) {
var filename = path.resolve(utilsUrl.urlJoin(config.get('paths').contentPath, 'data', exportResult.filename)); var filename = path.resolve(urlService.utils.urlJoin(config.get('paths').contentPath, 'data', exportResult.filename));
return Promise.promisify(fs.writeFile)(filename, JSON.stringify(exportResult.data)) return Promise.promisify(fs.writeFile)(filename, JSON.stringify(exportResult.data))
.then(function () { .then(function () {

View File

@ -8,7 +8,7 @@ var _ = require('lodash'),
Promise = require('bluebird'), Promise = require('bluebird'),
config = require('../config'), config = require('../config'),
models = require('../models'), models = require('../models'),
utils = require('../utils'), urlService = require('../services/url'),
configuration = require('./configuration'), configuration = require('./configuration'),
db = require('./db'), db = require('./db'),
mail = require('./mail'), mail = require('./mail'),
@ -103,7 +103,7 @@ cacheInvalidationHeader = function cacheInvalidationHeader(req, result) {
if (hasStatusChanged || wasPublishedUpdated) { if (hasStatusChanged || wasPublishedUpdated) {
return INVALIDATE_ALL; return INVALIDATE_ALL;
} else { } else {
return utils.url.urlFor({relativeUrl: utils.url.urlJoin('/', config.get('routeKeywords').preview, post.uuid, '/')}); return urlService.utils.urlFor({relativeUrl: urlService.utils.urlJoin('/', config.get('routeKeywords').preview, post.uuid, '/')});
} }
} }
} }
@ -121,7 +121,7 @@ cacheInvalidationHeader = function cacheInvalidationHeader(req, result) {
* @return {String} Resolves to header string * @return {String} Resolves to header string
*/ */
locationHeader = function locationHeader(req, result) { locationHeader = function locationHeader(req, result) {
var apiRoot = utils.url.urlFor('api'), var apiRoot = urlService.utils.urlFor('api'),
location, location,
newObject, newObject,
statusQuery; statusQuery;
@ -130,19 +130,19 @@ locationHeader = function locationHeader(req, result) {
if (result.hasOwnProperty('posts')) { if (result.hasOwnProperty('posts')) {
newObject = result.posts[0]; newObject = result.posts[0];
statusQuery = '/?status=' + newObject.status; statusQuery = '/?status=' + newObject.status;
location = utils.url.urlJoin(apiRoot, 'posts', newObject.id, statusQuery); location = urlService.utils.urlJoin(apiRoot, 'posts', newObject.id, statusQuery);
} else if (result.hasOwnProperty('notifications')) { } else if (result.hasOwnProperty('notifications')) {
newObject = result.notifications[0]; newObject = result.notifications[0];
location = utils.url.urlJoin(apiRoot, 'notifications', newObject.id, '/'); location = urlService.utils.urlJoin(apiRoot, 'notifications', newObject.id, '/');
} else if (result.hasOwnProperty('users')) { } else if (result.hasOwnProperty('users')) {
newObject = result.users[0]; newObject = result.users[0];
location = utils.url.urlJoin(apiRoot, 'users', newObject.id, '/'); location = urlService.utils.urlJoin(apiRoot, 'users', newObject.id, '/');
} else if (result.hasOwnProperty('tags')) { } else if (result.hasOwnProperty('tags')) {
newObject = result.tags[0]; newObject = result.tags[0];
location = utils.url.urlJoin(apiRoot, 'tags', newObject.id, '/'); location = urlService.utils.urlJoin(apiRoot, 'tags', newObject.id, '/');
} else if (result.hasOwnProperty('webhooks')) { } else if (result.hasOwnProperty('webhooks')) {
newObject = result.webhooks[0]; newObject = result.webhooks[0];
location = utils.url.urlJoin(apiRoot, 'webhooks', newObject.id, '/'); location = urlService.utils.urlJoin(apiRoot, 'webhooks', newObject.id, '/');
} }
} }

View File

@ -3,6 +3,7 @@ var Promise = require('bluebird'),
pipeline = require('../utils/pipeline'), pipeline = require('../utils/pipeline'),
mail = require('./../mail'), mail = require('./../mail'),
globalUtils = require('../utils'), globalUtils = require('../utils'),
urlService = require('../services/url'),
apiUtils = require('./utils'), apiUtils = require('./utils'),
models = require('../models'), models = require('../models'),
errors = require('../errors'), errors = require('../errors'),
@ -101,14 +102,14 @@ invites = {
return settingsAPI.read({key: 'title'}); return settingsAPI.read({key: 'title'});
}) })
.then(function (response) { .then(function (response) {
var adminUrl = globalUtils.url.urlFor('admin', true); var adminUrl = urlService.utils.urlFor('admin', true);
emailData = { emailData = {
blogName: response.settings[0].value, blogName: response.settings[0].value,
invitedByName: loggedInUser.get('name'), invitedByName: loggedInUser.get('name'),
invitedByEmail: loggedInUser.get('email'), invitedByEmail: loggedInUser.get('email'),
// @TODO: resetLink sounds weird // @TODO: resetLink sounds weird
resetLink: globalUtils.url.urlJoin(adminUrl, 'signup', globalUtils.encodeBase64URLsafe(invite.get('token')), '/') resetLink: urlService.utils.urlJoin(adminUrl, 'signup', globalUtils.encodeBase64URLsafe(invite.get('token')), '/')
}; };
return mail.utils.generateContent({data: emailData, template: 'invite-user'}); return mail.utils.generateContent({data: emailData, template: 'invite-user'});

View File

@ -16,7 +16,7 @@ var Promise = require('bluebird'),
i18n = proxy.i18n, i18n = proxy.i18n,
errors = proxy.errors, errors = proxy.errors,
makeAbsoluteUrl = require('../../../../utils/make-absolute-urls'), makeAbsoluteUrl = require('../../../../utils/make-absolute-urls'),
utils = require('../../../../utils'), urlService = require('../../../../services/url'),
amperizeCache = {}, amperizeCache = {},
allowedAMPTags = [], allowedAMPTags = [],
allowedAMPAttributes = {}, allowedAMPAttributes = {},
@ -126,7 +126,7 @@ function getAmperizeHTML(html, post) {
amperize = amperize || new Amperize(); amperize = amperize || new Amperize();
// make relative URLs abolute // make relative URLs abolute
html = makeAbsoluteUrl(html, utils.url.urlFor('home', true), post.url).html(); html = makeAbsoluteUrl(html, urlService.utils.urlFor('home', true), post.url).html();
if (!amperizeCache[post.id] || moment(new Date(amperizeCache[post.id].updated_at)).diff(new Date(post.updated_at)) < 0) { if (!amperizeCache[post.id] || moment(new Date(amperizeCache[post.id].updated_at)).diff(new Date(post.updated_at)) < 0) {
return new Promise(function (resolve) { return new Promise(function (resolve) {

View File

@ -1,18 +1,18 @@
var config = require('../../config'), var config = require('../../config'),
utils = require('../../utils'), urlService = require('../../services/url'),
errors = require('../../errors'), errors = require('../../errors'),
logging = require('../../logging'), logging = require('../../logging'),
i18n = require('../../i18n'), i18n = require('../../i18n'),
middleware = require('./lib/middleware'), middleware = require('./lib/middleware'),
router = require('./lib/router'), router = require('./lib/router'),
registerHelpers = require('./lib/helpers'), registerHelpers = require('./lib/helpers'),
checkSubdir; checkSubdir;
checkSubdir = function checkSubdir() { checkSubdir = function checkSubdir() {
var paths; var paths;
if (utils.url.getSubdir()) { if (urlService.utils.getSubdir()) {
paths = utils.url.getSubdir().split('/'); paths = urlService.utils.getSubdir().split('/');
if (paths.pop() === config.get('routeKeywords').private) { if (paths.pop() === config.get('routeKeywords').private) {
logging.error(new errors.GhostError({ logging.error(new errors.GhostError({

View File

@ -3,7 +3,8 @@ var fs = require('fs'),
crypto = require('crypto'), crypto = require('crypto'),
path = require('path'), path = require('path'),
config = require('../../../config'), config = require('../../../config'),
utils = require('../../../utils'), urlService = require('../../../services/url'),
globalUtils = require('../../../utils'),
errors = require('../../../errors'), errors = require('../../../errors'),
i18n = require('../../../i18n'), i18n = require('../../../i18n'),
settingsCache = require('../../../settings/cache'), settingsCache = require('../../../settings/cache'),
@ -32,7 +33,7 @@ privateBlogging = {
res.isPrivateBlog = true; res.isPrivateBlog = true;
return session({ return session({
maxAge: utils.ONE_MONTH_MS, maxAge: globalUtils.ONE_MONTH_MS,
signed: false signed: false
})(req, res, next); })(req, res, next);
}, },
@ -88,7 +89,7 @@ privateBlogging = {
if (isVerified) { if (isVerified) {
return next(); return next();
} else { } else {
url = utils.url.urlFor({relativeUrl: privateRoute}); url = urlService.utils.urlFor({relativeUrl: privateRoute});
url += req.url === '/' ? '' : '?r=' + encodeURIComponent(req.url); url += req.url === '/' ? '' : '?r=' + encodeURIComponent(req.url);
return res.redirect(url); return res.redirect(url);
} }
@ -97,7 +98,7 @@ privateBlogging = {
// This is here so a call to /private/ after a session is verified will redirect to home; // This is here so a call to /private/ after a session is verified will redirect to home;
isPrivateSessionAuth: function isPrivateSessionAuth(req, res, next) { isPrivateSessionAuth: function isPrivateSessionAuth(req, res, next) {
if (!res.isPrivateBlog) { if (!res.isPrivateBlog) {
return res.redirect(utils.url.urlFor('home', true)); return res.redirect(urlService.utils.urlFor('home', true));
} }
var hash = req.session.token || '', var hash = req.session.token || '',
@ -106,7 +107,7 @@ privateBlogging = {
if (isVerified) { if (isVerified) {
// redirect to home if user is already authenticated // redirect to home if user is already authenticated
return res.redirect(utils.url.urlFor('home', true)); return res.redirect(urlService.utils.urlFor('home', true));
} else { } else {
return next(); return next();
} }
@ -129,7 +130,7 @@ privateBlogging = {
req.session.token = hasher.digest('hex'); req.session.token = hasher.digest('hex');
req.session.salt = salt; req.session.salt = salt;
return res.redirect(utils.url.urlFor({relativeUrl: decodeURIComponent(forward)})); return res.redirect(urlService.utils.urlFor({relativeUrl: decodeURIComponent(forward)}));
} else { } else {
res.error = { res.error = {
message: i18n.t('errors.middleware.privateblogging.wrongPassword') message: i18n.t('errors.middleware.privateblogging.wrongPassword')

View File

@ -1,6 +1,6 @@
var _ = require('lodash'), var _ = require('lodash'),
models = require('../models'), models = require('../models'),
utils = require('../utils'), globalUtils = require('../utils'),
i18n = require('../i18n'), i18n = require('../i18n'),
errors = require('../errors'), errors = require('../errors'),
strategies; strategies;
@ -95,7 +95,7 @@ strategies = {
handleInviteToken = function handleInviteToken() { handleInviteToken = function handleInviteToken() {
var user, invite; var user, invite;
inviteToken = utils.decodeBase64URLsafe(inviteToken); inviteToken = globalUtils.decodeBase64URLsafe(inviteToken);
return models.Invite.findOne({token: inviteToken}, options) return models.Invite.findOne({token: inviteToken}, options)
.then(function addInviteUser(_invite) { .then(function addInviteUser(_invite) {
@ -116,7 +116,7 @@ strategies = {
return models.User.add({ return models.User.add({
email: profile.email, email: profile.email,
name: profile.name, name: profile.name,
password: utils.uid(50), password: globalUtils.uid(50),
roles: [invite.toJSON().role_id], roles: [invite.toJSON().role_id],
ghost_auth_id: profile.id, ghost_auth_id: profile.id,
ghost_auth_access_token: ghostAuthAccessToken ghost_auth_access_token: ghostAuthAccessToken

View File

@ -1,4 +1,4 @@
var utils = require('../utils'), var urlService = require('../services/url'),
filters = require('../filters'), filters = require('../filters'),
handleError = require('./frontend/error'), handleError = require('./frontend/error'),
postLookup = require('./frontend/post-lookup'), postLookup = require('./frontend/post-lookup'),
@ -31,12 +31,12 @@ module.exports = function entryController(req, res, next) {
// CASE: last param is of url is /edit, redirect to admin // CASE: last param is of url is /edit, redirect to admin
if (lookup.isEditURL) { if (lookup.isEditURL) {
return utils.url.redirectToAdmin(302, res, '#/editor/' + post.id); return urlService.utils.redirectToAdmin(302, res, '#/editor/' + post.id);
} }
// CASE: permalink is not valid anymore, we redirect him permanently to the correct one // CASE: permalink is not valid anymore, we redirect him permanently to the correct one
if (post.url !== req.path) { if (post.url !== req.path) {
return utils.url.redirect301(res, post.url); return urlService.utils.redirect301(res, post.url);
} }
setRequestIsSecure(req, post); setRequestIsSecure(req, post);

View File

@ -1,5 +1,5 @@
var api = require('../api'), var api = require('../api'),
utils = require('../utils'), urlService = require('../services/url'),
filters = require('../filters'), filters = require('../filters'),
handleError = require('./frontend/error'), handleError = require('./frontend/error'),
renderEntry = require('./frontend/render-entry'), renderEntry = require('./frontend/render-entry'),
@ -30,14 +30,14 @@ module.exports = function previewController(req, res, next) {
if (req.params.options && req.params.options.toLowerCase() === 'edit') { if (req.params.options && req.params.options.toLowerCase() === 'edit') {
// CASE: last param is of url is /edit, redirect to admin // CASE: last param is of url is /edit, redirect to admin
return utils.url.redirectToAdmin(302, res, '#/editor/' + post.id); return urlService.utils.redirectToAdmin(302, res, '#/editor/' + post.id);
} else if (req.params.options) { } else if (req.params.options) {
// CASE: unknown options param detected. Ignore and end in 404. // CASE: unknown options param detected. Ignore and end in 404.
return next(); return next();
} }
if (post.status === 'published') { if (post.status === 'published') {
return utils.url.redirect301(res, utils.url.urlFor('post', {post: post})); return urlService.utils.redirect301(res, urlService.utils.urlFor('post', {post: post}));
} }
setRequestIsSecure(req, post); setRequestIsSecure(req, post);

View File

@ -1,18 +1,18 @@
// # Backup Database // # Backup Database
// Provides for backing up the database before making potentially destructive changes // Provides for backing up the database before making potentially destructive changes
var fs = require('fs'), var fs = require('fs'),
path = require('path'), path = require('path'),
Promise = require('bluebird'), Promise = require('bluebird'),
config = require('../../config'), config = require('../../config'),
logging = require('../../logging'), logging = require('../../logging'),
utils = require('../../utils'), urlService = require('../../services/url'),
exporter = require('../export'), exporter = require('../export'),
writeExportFile, writeExportFile,
backup; backup;
writeExportFile = function writeExportFile(exportResult) { writeExportFile = function writeExportFile(exportResult) {
var filename = path.resolve(utils.url.urlJoin(config.get('paths').contentPath, 'data', exportResult.filename)); var filename = path.resolve(urlService.utils.urlJoin(config.get('paths').contentPath, 'data', exportResult.filename));
return Promise.promisify(fs.writeFile)(filename, JSON.stringify(exportResult.data)).return(filename); return Promise.promisify(fs.writeFile)(filename, JSON.stringify(exportResult.data)).return(filename);
}; };

View File

@ -2,12 +2,12 @@ var _ = require('lodash'),
Promise = require('bluebird'), Promise = require('bluebird'),
db = require('../../data/db'), db = require('../../data/db'),
commands = require('../schema').commands, commands = require('../schema').commands,
serverUtils = require('../../utils'), globalUtils = require('../../utils'),
ghostVersion = require('../../utils/ghost-version'), ghostVersion = require('../../utils/ghost-version'),
errors = require('../../errors'), errors = require('../../errors'),
logging = require('../../logging'), logging = require('../../logging'),
models = require('../../models'), models = require('../../models'),
i18n = require('../../i18n'), i18n = require('../../i18n'),
excludedTables = ['accesstokens', 'refreshtokens', 'clients', 'client_trusted_domains'], excludedTables = ['accesstokens', 'refreshtokens', 'clients', 'client_trusted_domains'],
modelOptions = {context: {internal: true}}, modelOptions = {context: {internal: true}},
@ -25,7 +25,7 @@ exportFileName = function exportFileName(options) {
return models.Settings.findOne({key: 'title'}, _.merge({}, modelOptions, options)).then(function (result) { return models.Settings.findOne({key: 'title'}, _.merge({}, modelOptions, options)).then(function (result) {
if (result) { if (result) {
title = serverUtils.safeString(result.get('value')) + '.'; title = globalUtils.safeString(result.get('value')) + '.';
} }
return title + 'ghost.' + datetime + '.json'; return title + 'ghost.' + datetime + '.json';

View File

@ -1,8 +1,8 @@
var _ = require('lodash'), var _ = require('lodash'),
Promise = require('bluebird'), Promise = require('bluebird'),
path = require('path'), path = require('path'),
config = require('../../../config'), config = require('../../../config'),
utils = require('../../../utils'), urlService = require('../../../services/url'),
storage = require('../../../adapters/storage'), storage = require('../../../adapters/storage'),
ImageHandler; ImageHandler;
@ -16,7 +16,7 @@ ImageHandler = {
loadFile: function (files, baseDir) { loadFile: function (files, baseDir) {
var store = storage.getStorage(), var store = storage.getStorage(),
baseDirRegex = baseDir ? new RegExp('^' + baseDir + '/') : new RegExp(''), baseDirRegex = baseDir ? new RegExp('^' + baseDir + '/') : new RegExp(''),
imageFolderRegexes = _.map(utils.url.STATIC_IMAGE_URL_PREFIX.split('/'), function (dir) { imageFolderRegexes = _.map(urlService.utils.STATIC_IMAGE_URL_PREFIX.split('/'), function (dir) {
return new RegExp('^' + dir + '/'); return new RegExp('^' + dir + '/');
}); });
@ -37,7 +37,7 @@ ImageHandler = {
return Promise.map(files, function (image) { return Promise.map(files, function (image) {
return store.getUniqueFileName(image, image.targetDir).then(function (targetFilename) { return store.getUniqueFileName(image, image.targetDir).then(function (targetFilename) {
image.newPath = utils.url.urlJoin('/', utils.url.getSubdir(), utils.url.STATIC_IMAGE_URL_PREFIX, image.newPath = urlService.utils.urlJoin('/', urlService.utils.getSubdir(), urlService.utils.STATIC_IMAGE_URL_PREFIX,
path.relative(config.getContentPath('images'), targetFilename)); path.relative(config.getContentPath('images'), targetFilename));
return image; return image;

View File

@ -1,7 +1,7 @@
var _ = require('lodash'), var _ = require('lodash'),
Promise = require('bluebird'), Promise = require('bluebird'),
models = require('../../../../models'), models = require('../../../../models'),
utils = require('../../../../utils'), globalUtils = require('../../../../utils'),
SubscribersImporter = require('./subscribers'), SubscribersImporter = require('./subscribers'),
PostsImporter = require('./posts'), PostsImporter = require('./posts'),
TagsImporter = require('./tags'), TagsImporter = require('./tags'),
@ -65,7 +65,7 @@ DataImporter = {
}); });
}); });
utils.sequence(ops) globalUtils.sequence(ops)
.then(function () { .then(function () {
results.forEach(function (promise) { results.forEach(function (promise) {
if (!promise.isFulfilled()) { if (!promise.isFulfilled()) {

View File

@ -1,4 +1,4 @@
var utils = require('../../utils'), var urlService = require('../../services/url'),
getUrl = require('./url'), getUrl = require('./url'),
_ = require('lodash'); _ = require('lodash');
@ -6,7 +6,7 @@ function getAmplUrl(data) {
var context = data.context ? data.context : null; var context = data.context ? data.context : null;
if (_.includes(context, 'post') && !_.includes(context, 'amp')) { if (_.includes(context, 'post') && !_.includes(context, 'amp')) {
return utils.url.urlJoin(utils.url.urlFor('home', true), getUrl(data, false), 'amp/'); return urlService.utils.urlJoin(urlService.utils.urlFor('home', true), getUrl(data, false), 'amp/');
} }
return null; return null;
} }

View File

@ -1,6 +1,7 @@
var config = require('../../config'), var config = require('../../config'),
blogIconUtils = require('../../utils/blog-icon'), blogIconUtils = require('../../utils/blog-icon'),
utils = require('../../utils'); urlService = require('../../services/url'),
globalUtils = require('../../utils');
/** /**
* Serve either uploaded favicon or default * Serve either uploaded favicon or default
@ -19,11 +20,11 @@ function getAssetUrl(path, hasMinFile) {
// CASE: Build the output URL // CASE: Build the output URL
// Add subdirectory... // Add subdirectory...
var output = utils.url.urlJoin(utils.url.getSubdir(), '/'); var output = urlService.utils.urlJoin(urlService.utils.getSubdir(), '/');
// Optionally add /assets/ // Optionally add /assets/
if (!path.match(/^public/) && !path.match(/^asset/)) { if (!path.match(/^public/) && !path.match(/^asset/)) {
output = utils.url.urlJoin(output, 'assets/'); output = urlService.utils.urlJoin(output, 'assets/');
} }
// replace ".foo" with ".min.foo" if configured // replace ".foo" with ".min.foo" if configured
@ -32,12 +33,12 @@ function getAssetUrl(path, hasMinFile) {
} }
// Add the path for the requested asset // Add the path for the requested asset
output = utils.url.urlJoin(output, path); output = urlService.utils.urlJoin(output, path);
// Ensure we have an assetHash // Ensure we have an assetHash
// @TODO rework this! // @TODO rework this!
if (!config.get('assetHash')) { if (!config.get('assetHash')) {
config.set('assetHash', utils.generateAssetHash()); config.set('assetHash', globalUtils.generateAssetHash());
} }
// Finally add the asset hash to the output URL // Finally add the asset hash to the output URL

View File

@ -1,13 +1,13 @@
var utils = require('../../utils'), var urlService = require('../../services/url'),
getContextObject = require('./context_object.js'), getContextObject = require('./context_object.js'),
_ = require('lodash'); _ = require('lodash');
function getAuthorImage(data, absolute) { function getAuthorImage(data, absolute) {
var context = data.context ? data.context : null, var context = data.context ? data.context : null,
contextObject = getContextObject(data, context); contextObject = getContextObject(data, context);
if ((_.includes(context, 'post') || _.includes(context, 'page')) && contextObject.author && contextObject.author.profile_image) { if ((_.includes(context, 'post') || _.includes(context, 'page')) && contextObject.author && contextObject.author.profile_image) {
return utils.url.urlFor('image', {image: contextObject.author.profile_image}, absolute); return urlService.utils.urlFor('image', {image: contextObject.author.profile_image}, absolute);
} }
return null; return null;
} }

View File

@ -1,4 +1,4 @@
var utils = require('../../utils'); var urlService = require('../../services/url');
function getAuthorUrl(data, absolute) { function getAuthorUrl(data, absolute) {
var context = data.context ? data.context[0] : null; var context = data.context ? data.context[0] : null;
@ -6,10 +6,10 @@ function getAuthorUrl(data, absolute) {
context = context === 'amp' ? 'post' : context; context = context === 'amp' ? 'post' : context;
if (data.author) { if (data.author) {
return utils.url.urlFor('author', {author: data.author}, absolute); return urlService.utils.urlFor('author', {author: data.author}, absolute);
} }
if (data[context] && data[context].author) { if (data[context] && data[context].author) {
return utils.url.urlFor('author', {author: data[context].author}, absolute); return urlService.utils.urlFor('author', {author: data[context].author}, absolute);
} }
return null; return null;
} }

View File

@ -1,12 +1,12 @@
var utils = require('../../utils'), var urlService = require('../../services/url'),
settingsCache = require('../../settings/cache'), settingsCache = require('../../settings/cache'),
blogIconUtils = require('../../utils/blog-icon'); blogIconUtils = require('../../utils/blog-icon');
function getBlogLogo() { function getBlogLogo() {
var logo = {}; var logo = {};
if (settingsCache.get('logo')) { if (settingsCache.get('logo')) {
logo.url = utils.url.urlFor('image', {image: settingsCache.get('logo')}, true); logo.url = urlService.utils.urlFor('image', {image: settingsCache.get('logo')}, true);
} else { } else {
// CASE: no publication logo is updated. We can try to use either an uploaded publication icon // CASE: no publication logo is updated. We can try to use either an uploaded publication icon
// or use the default one to make // or use the default one to make

View File

@ -1,8 +1,8 @@
var utils = require('../../utils'), var urlService = require('../../services/url'),
getUrl = require('./url'); getUrl = require('./url');
function getCanonicalUrl(data) { function getCanonicalUrl(data) {
var url = utils.url.urlJoin(utils.url.urlFor('home', true), getUrl(data, false)); var url = urlService.utils.urlJoin(urlService.utils.urlFor('home', true), getUrl(data, false));
if (url.indexOf('/amp/')) { if (url.indexOf('/amp/')) {
url = url.replace(/\/amp\/$/i, '/'); url = url.replace(/\/amp\/$/i, '/');

View File

@ -1,6 +1,6 @@
var utils = require('../../utils'), var urlService = require('../../services/url'),
getContextObject = require('./context_object.js'), getContextObject = require('./context_object.js'),
_ = require('lodash'); _ = require('lodash');
function getCoverImage(data) { function getCoverImage(data) {
var context = data.context ? data.context : null, var context = data.context ? data.context : null,
@ -8,11 +8,11 @@ function getCoverImage(data) {
if (_.includes(context, 'home') || _.includes(context, 'author')) { if (_.includes(context, 'home') || _.includes(context, 'author')) {
if (contextObject.cover_image) { if (contextObject.cover_image) {
return utils.url.urlFor('image', {image: contextObject.cover_image}, true); return urlService.utils.urlFor('image', {image: contextObject.cover_image}, true);
} }
} else { } else {
if (contextObject.feature_image) { if (contextObject.feature_image) {
return utils.url.urlFor('image', {image: contextObject.feature_image}, true); return urlService.utils.urlFor('image', {image: contextObject.feature_image}, true);
} }
} }
return null; return null;

View File

@ -1,6 +1,6 @@
var Promise = require('bluebird'), var Promise = require('bluebird'),
settingsCache = require('../../settings/cache'), settingsCache = require('../../settings/cache'),
utils = require('../../utils'), urlService = require('../../services/url'),
logging = require('../../logging'), logging = require('../../logging'),
getUrl = require('./url'), getUrl = require('./url'),
getImageDimensions = require('./image-dimensions'), getImageDimensions = require('./image-dimensions'),
@ -61,7 +61,7 @@ function getMetaData(data, root) {
blog: { blog: {
title: settingsCache.get('title'), title: settingsCache.get('title'),
description: settingsCache.get('description'), description: settingsCache.get('description'),
url: utils.url.urlFor('home', true), url: urlService.utils.urlFor('home', true),
facebook: settingsCache.get('facebook'), facebook: settingsCache.get('facebook'),
twitter: settingsCache.get('twitter'), twitter: settingsCache.get('twitter'),
timezone: settingsCache.get('active_timezone'), timezone: settingsCache.get('active_timezone'),

View File

@ -1,6 +1,6 @@
var utils = require('../../utils'), var urlService = require('../../services/url'),
getContextObject = require('./context_object.js'), getContextObject = require('./context_object.js'),
_ = require('lodash'); _ = require('lodash');
function getOgImage(data) { function getOgImage(data) {
var context = data.context ? data.context : null, var context = data.context ? data.context : null,
@ -8,9 +8,9 @@ function getOgImage(data) {
if (_.includes(context, 'post') || _.includes(context, 'page') || _.includes(context, 'amp')) { if (_.includes(context, 'post') || _.includes(context, 'page') || _.includes(context, 'amp')) {
if (contextObject.og_image) { if (contextObject.og_image) {
return utils.url.urlFor('image', {image: contextObject.og_image}, true); return urlService.utils.urlFor('image', {image: contextObject.og_image}, true);
} else if (contextObject.feature_image) { } else if (contextObject.feature_image) {
return utils.url.urlFor('image', {image: contextObject.feature_image}, true); return urlService.utils.urlFor('image', {image: contextObject.feature_image}, true);
} }
} }

View File

@ -1,6 +1,6 @@
var _ = require('lodash'), var _ = require('lodash'),
config = require('../../config'), config = require('../../config'),
utils = require('../../utils'); urlService = require('../../services/url');
function getPaginatedUrl(page, data, absolute) { function getPaginatedUrl(page, data, absolute) {
// If we don't have enough information, return null right away // If we don't have enough information, return null right away
@ -8,7 +8,7 @@ function getPaginatedUrl(page, data, absolute) {
return null; return null;
} }
var pagePath = utils.url.urlJoin('/', config.get('routeKeywords').page, '/'), var pagePath = urlService.utils.urlJoin('/', config.get('routeKeywords').page, '/'),
// Try to match the base url, as whatever precedes the pagePath // Try to match the base url, as whatever precedes the pagePath
baseUrlPattern = new RegExp('(.+)?(/' + config.get('routeKeywords').page + '/\\d+/)'), baseUrlPattern = new RegExp('(.+)?(/' + config.get('routeKeywords').page + '/\\d+/)'),
baseUrlMatch = data.relativeUrl.match(baseUrlPattern), baseUrlMatch = data.relativeUrl.match(baseUrlPattern),
@ -17,20 +17,20 @@ function getPaginatedUrl(page, data, absolute) {
newRelativeUrl; newRelativeUrl;
if (page === 'next' && data.pagination.next) { if (page === 'next' && data.pagination.next) {
newRelativeUrl = utils.url.urlJoin(pagePath, data.pagination.next, '/'); newRelativeUrl = urlService.utils.urlJoin(pagePath, data.pagination.next, '/');
} else if (page === 'prev' && data.pagination.prev) { } else if (page === 'prev' && data.pagination.prev) {
newRelativeUrl = data.pagination.prev > 1 ? utils.url.urlJoin(pagePath, data.pagination.prev, '/') : '/'; newRelativeUrl = data.pagination.prev > 1 ? urlService.utils.urlJoin(pagePath, data.pagination.prev, '/') : '/';
} else if (_.isNumber(page)) { } else if (_.isNumber(page)) {
newRelativeUrl = page > 1 ? utils.url.urlJoin(pagePath, page, '/') : '/'; newRelativeUrl = page > 1 ? urlService.utils.urlJoin(pagePath, page, '/') : '/';
} else { } else {
// If none of the cases match, return null right away // If none of the cases match, return null right away
return null; return null;
} }
// baseUrl can be undefined, if there was nothing preceding the pagePath (e.g. first page of the index channel) // baseUrl can be undefined, if there was nothing preceding the pagePath (e.g. first page of the index channel)
newRelativeUrl = baseUrl ? utils.url.urlJoin(baseUrl, newRelativeUrl) : newRelativeUrl; newRelativeUrl = baseUrl ? urlService.utils.urlJoin(baseUrl, newRelativeUrl) : newRelativeUrl;
return utils.url.urlFor({relativeUrl: newRelativeUrl, secure: data.secure}, absolute); return urlService.utils.urlFor({relativeUrl: newRelativeUrl, secure: data.secure}, absolute);
} }
module.exports = getPaginatedUrl; module.exports = getPaginatedUrl;

View File

@ -1,7 +1,7 @@
var utils = require('../../utils'); var urlService = require('../../services/url');
function getRssUrl(data, absolute) { function getRssUrl(data, absolute) {
return utils.url.urlFor('rss', {secure: data.secure}, absolute); return urlService.utils.urlFor('rss', {secure: data.secure}, absolute);
} }
module.exports = getRssUrl; module.exports = getRssUrl;

View File

@ -1,6 +1,6 @@
var utils = require('../../utils'), var urlService = require('../../services/url'),
getContextObject = require('./context_object.js'), getContextObject = require('./context_object.js'),
_ = require('lodash'); _ = require('lodash');
function getTwitterImage(data) { function getTwitterImage(data) {
var context = data.context ? data.context : null, var context = data.context ? data.context : null,
@ -8,9 +8,9 @@ function getTwitterImage(data) {
if (_.includes(context, 'post') || _.includes(context, 'page') || _.includes(context, 'amp')) { if (_.includes(context, 'post') || _.includes(context, 'page') || _.includes(context, 'amp')) {
if (contextObject.twitter_image) { if (contextObject.twitter_image) {
return utils.url.urlFor('image', {image: contextObject.twitter_image}, true); return urlService.utils.urlFor('image', {image: contextObject.twitter_image}, true);
} else if (contextObject.feature_image) { } else if (contextObject.feature_image) {
return utils.url.urlFor('image', {image: contextObject.feature_image}, true); return urlService.utils.urlFor('image', {image: contextObject.feature_image}, true);
} }
} }

View File

@ -1,5 +1,5 @@
var schema = require('../schema').checks, var schema = require('../schema').checks,
utils = require('../../utils'); urlService = require('../../services/url');
// This cleans the url from any `/amp` postfixes, so we'll never // This cleans the url from any `/amp` postfixes, so we'll never
// output a url with `/amp` in the end, except for the needed `amphtml` // output a url with `/amp` in the end, except for the needed `amphtml`
@ -13,23 +13,23 @@ function sanitizeAmpUrl(url) {
function getUrl(data, absolute) { function getUrl(data, absolute) {
if (schema.isPost(data)) { if (schema.isPost(data)) {
return utils.url.urlFor('post', {post: data, secure: data.secure}, absolute); return urlService.utils.urlFor('post', {post: data, secure: data.secure}, absolute);
} }
if (schema.isTag(data)) { if (schema.isTag(data)) {
return utils.url.urlFor('tag', {tag: data, secure: data.secure}, absolute); return urlService.utils.urlFor('tag', {tag: data, secure: data.secure}, absolute);
} }
if (schema.isUser(data)) { if (schema.isUser(data)) {
return utils.url.urlFor('author', {author: data, secure: data.secure}, absolute); return urlService.utils.urlFor('author', {author: data, secure: data.secure}, absolute);
} }
if (schema.isNav(data)) { if (schema.isNav(data)) {
return utils.url.urlFor('nav', {nav: data, secure: data.secure}, absolute); return urlService.utils.urlFor('nav', {nav: data, secure: data.secure}, absolute);
} }
// sanitize any trailing `/amp` in the url // sanitize any trailing `/amp` in the url
return sanitizeAmpUrl(utils.url.urlFor(data, {}, absolute)); return sanitizeAmpUrl(urlService.utils.urlFor(data, {}, absolute));
} }
module.exports = getUrl; module.exports = getUrl;

View File

@ -7,7 +7,7 @@ var schema = require('../schema').tables,
errors = require('../../errors'), errors = require('../../errors'),
i18n = require('../../i18n'), i18n = require('../../i18n'),
settingsCache = require('../../settings/cache'), settingsCache = require('../../settings/cache'),
utils = require('../../utils/url'), urlService = require('../../services/url'),
validatePassword, validatePassword,
validateSchema, validateSchema,
@ -95,7 +95,7 @@ validator.extend('isSlug', function isSlug(str) {
validatePassword = function validatePassword(password, email, blogTitle) { validatePassword = function validatePassword(password, email, blogTitle) {
var validationResult = {isValid: true}, var validationResult = {isValid: true},
disallowedPasswords = ['password', 'ghost', 'passw0rd'], disallowedPasswords = ['password', 'ghost', 'passw0rd'],
blogUrl = utils.urlFor('home', true), blogUrl = urlService.utils.urlFor('home', true),
badPasswords = [ badPasswords = [
'1234567890', '1234567890',
'qwertyuiop', 'qwertyuiop',

View File

@ -1,11 +1,11 @@
var _ = require('lodash'), var _ = require('lodash'),
xml = require('xml'), xml = require('xml'),
moment = require('moment'), moment = require('moment'),
utils = require('../../../utils'), Promise = require('bluebird'),
events = require('../../../events'), path = require('path'),
localUtils = require('./utils'), urlService = require('../../../services/url'),
Promise = require('bluebird'), events = require('../../../events'),
path = require('path'), localUtils = require('./utils'),
CHANGE_FREQ = 'weekly', CHANGE_FREQ = 'weekly',
XMLNS_DECLS; XMLNS_DECLS;
@ -133,11 +133,11 @@ _.extend(BaseSiteMapGenerator.prototype, {
}, },
getUrlForDatum: function () { getUrlForDatum: function () {
return utils.url.urlFor('home', true); return urlService.utils.urlFor('home', true);
}, },
getUrlForImage: function (image) { getUrlForImage: function (image) {
return utils.url.urlFor('image', {image: image}, true); return urlService.utils.urlFor('image', {image: image}, true);
}, },
getPriorityForDatum: function () { getPriorityForDatum: function () {

View File

@ -1,7 +1,7 @@
var _ = require('lodash'), var _ = require('lodash'),
xml = require('xml'), xml = require('xml'),
moment = require('moment'), moment = require('moment'),
utils = require('../../../utils'), urlService = require('../../../services/url'),
localUtils = require('./utils'), localUtils = require('./utils'),
RESOURCES, RESOURCES,
XMLNS_DECLS; XMLNS_DECLS;
@ -35,7 +35,7 @@ _.extend(SiteMapIndexGenerator.prototype, {
var self = this; var self = this;
return _.map(RESOURCES, function (resourceType) { return _.map(RESOURCES, function (resourceType) {
var url = utils.url.urlFor({ var url = urlService.utils.urlFor({
relativeUrl: '/sitemap-' + resourceType + '.xml' relativeUrl: '/sitemap-' + resourceType + '.xml'
}, true), }, true),
lastModified = self[resourceType].lastModified; lastModified = self[resourceType].lastModified;

View File

@ -1,6 +1,6 @@
var _ = require('lodash'), var _ = require('lodash'),
api = require('../../../api'), api = require('../../../api'),
utils = require('../../../utils'), urlService = require('../../../services/url'),
BaseMapGenerator = require('./base-generator'); BaseMapGenerator = require('./base-generator');
// A class responsible for generating a sitemap from posts and keeping it updated // A class responsible for generating a sitemap from posts and keeping it updated
@ -46,10 +46,10 @@ _.extend(PageMapGenerator.prototype, {
getUrlForDatum: function (post) { getUrlForDatum: function (post) {
if (post.id === 0 && !_.isEmpty(post.name)) { if (post.id === 0 && !_.isEmpty(post.name)) {
return utils.url.urlFor(post.name, true); return urlService.utils.urlFor(post.name, true);
} }
return utils.url.urlFor('post', {post: post}, true); return urlService.utils.urlFor('post', {post: post}, true);
}, },
getPriorityForDatum: function (post) { getPriorityForDatum: function (post) {

View File

@ -1,6 +1,6 @@
var _ = require('lodash'), var _ = require('lodash'),
api = require('../../../api'), api = require('../../../api'),
utils = require('../../../utils'), urlService = require('../../../services/url'),
BaseMapGenerator = require('./base-generator'); BaseMapGenerator = require('./base-generator');
// A class responsible for generating a sitemap from posts and keeping it updated // A class responsible for generating a sitemap from posts and keeping it updated
@ -42,7 +42,7 @@ _.extend(PostMapGenerator.prototype, {
}, },
getUrlForDatum: function (post) { getUrlForDatum: function (post) {
return utils.url.urlFor('post', {post: post}, true); return urlService.utils.urlFor('post', {post: post}, true);
}, },
getPriorityForDatum: function (post) { getPriorityForDatum: function (post) {

View File

@ -1,6 +1,6 @@
var _ = require('lodash'), var _ = require('lodash'),
api = require('../../../api'), api = require('../../../api'),
utils = require('../../../utils'), urlService = require('../../../services/url'),
BaseMapGenerator = require('./base-generator'); BaseMapGenerator = require('./base-generator');
// A class responsible for generating a sitemap from posts and keeping it updated // A class responsible for generating a sitemap from posts and keeping it updated
@ -38,7 +38,7 @@ _.extend(TagsMapGenerator.prototype, {
}, },
getUrlForDatum: function (tag) { getUrlForDatum: function (tag) {
return utils.url.urlFor('tag', {tag: tag}, true); return urlService.utils.urlFor('tag', {tag: tag}, true);
}, },
getPriorityForDatum: function () { getPriorityForDatum: function () {

View File

@ -1,6 +1,6 @@
var _ = require('lodash'), var _ = require('lodash'),
api = require('../../../api'), api = require('../../../api'),
utils = require('../../../utils'), urlService = require('../../../services/url'),
validator = require('validator'), validator = require('validator'),
BaseMapGenerator = require('./base-generator'), BaseMapGenerator = require('./base-generator'),
// @TODO: figure out a way to get rid of this // @TODO: figure out a way to get rid of this
@ -42,7 +42,7 @@ _.extend(UserMapGenerator.prototype, {
}, },
getUrlForDatum: function (user) { getUrlForDatum: function (user) {
return utils.url.urlFor('author', {author: user}, true); return urlService.utils.urlFor('author', {author: user}, true);
}, },
getPriorityForDatum: function () { getPriorityForDatum: function () {

View File

@ -1,9 +1,9 @@
var utils = require('../../../utils'), var urlService = require('../../../services/url'),
sitemapsUtils; sitemapsUtils;
sitemapsUtils = { sitemapsUtils = {
getDeclarations: function () { getDeclarations: function () {
var baseUrl = utils.url.urlFor('sitemap_xsl', true); var baseUrl = urlService.utils.urlFor('sitemap_xsl', true);
baseUrl = baseUrl.replace(/^(http:|https:)/, ''); baseUrl = baseUrl.replace(/^(http:|https:)/, '');
return '<?xml version="1.0" encoding="UTF-8"?>' + return '<?xml version="1.0" encoding="UTF-8"?>' +
'<?xml-stylesheet type="text/xsl" href="' + baseUrl + '"?>'; '<?xml-stylesheet type="text/xsl" href="' + baseUrl + '"?>';

View File

@ -9,7 +9,7 @@ var debug = require('ghost-ignition').debug('server'),
events = require('./events'), events = require('./events'),
logging = require('./logging'), logging = require('./logging'),
config = require('./config'), config = require('./config'),
utils = require('./utils'), urlService = require('./services/url'),
i18n = require('./i18n'), i18n = require('./i18n'),
moment = require('moment'); moment = require('moment');
@ -193,7 +193,7 @@ GhostServer.prototype.logStartMessages = function () {
// Startup & Shutdown messages // Startup & Shutdown messages
if (config.get('env') === 'production') { if (config.get('env') === 'production') {
logging.info(i18n.t('notices.httpServer.ghostIsRunningIn', {env: config.get('env')})); logging.info(i18n.t('notices.httpServer.ghostIsRunningIn', {env: config.get('env')}));
logging.info(i18n.t('notices.httpServer.yourBlogIsAvailableOn', {url: utils.url.urlFor('home', true)})); logging.info(i18n.t('notices.httpServer.yourBlogIsAvailableOn', {url: urlService.utils.urlFor('home', true)}));
logging.info(i18n.t('notices.httpServer.ctrlCToShutDown')); logging.info(i18n.t('notices.httpServer.ctrlCToShutDown'));
} else { } else {
logging.info(i18n.t('notices.httpServer.ghostIsRunningIn', {env: config.get('env')})); logging.info(i18n.t('notices.httpServer.ghostIsRunningIn', {env: config.get('env')}));
@ -201,7 +201,7 @@ GhostServer.prototype.logStartMessages = function () {
host: config.get('server').socket || config.get('server').host, host: config.get('server').socket || config.get('server').host,
port: config.get('server').port port: config.get('server').port
})); }));
logging.info(i18n.t('notices.httpServer.urlConfiguredAs', {url: utils.url.urlFor('home', true)})); logging.info(i18n.t('notices.httpServer.urlConfiguredAs', {url: urlService.utils.urlFor('home', true)}));
logging.info(i18n.t('notices.httpServer.ctrlCToShutDown')); logging.info(i18n.t('notices.httpServer.ctrlCToShutDown'));
} }

View File

@ -63,7 +63,7 @@ module.exports = {
// Various utils, needs cleaning up / simplifying // Various utils, needs cleaning up / simplifying
socialUrls: require('../utils/social-urls'), socialUrls: require('../utils/social-urls'),
blogIcon: require('../utils/blog-icon'), blogIcon: require('../utils/blog-icon'),
url: require('../utils').url, url: require('../services/url').utils,
utils: { utils: {
findKey: function findKey(key /* ...objects... */) { findKey: function findKey(key /* ...objects... */) {
var objects = Array.prototype.slice.call(arguments, 1); var objects = Array.prototype.slice.call(arguments, 1);

View File

@ -11,7 +11,6 @@
* - overrides is the first package to load * - overrides is the first package to load
*/ */
require('./overrides'); require('./overrides');
require('./services/url');
// Module dependencies // Module dependencies
var debug = require('ghost-ignition').debug('boot:init'), var debug = require('ghost-ignition').debug('boot:init'),
@ -26,7 +25,7 @@ var debug = require('ghost-ignition').debug('boot:init'),
scheduling = require('./adapters/scheduling'), scheduling = require('./adapters/scheduling'),
settings = require('./settings'), settings = require('./settings'),
themes = require('./themes'), themes = require('./themes'),
utils = require('./utils'), urlService = require('./services/url'),
// Services that need initialisation // Services that need initialisation
apps = require('./services/apps'), apps = require('./services/apps'),
@ -94,7 +93,7 @@ function init() {
return scheduling.init({ return scheduling.init({
schedulerUrl: config.get('scheduling').schedulerUrl, schedulerUrl: config.get('scheduling').schedulerUrl,
active: config.get('scheduling').active, active: config.get('scheduling').active,
apiUrl: utils.url.urlFor('api', true), apiUrl: urlService.utils.urlFor('api', true),
internalPath: config.get('paths').internalSchedulingPath, internalPath: config.get('paths').internalSchedulingPath,
contentPath: config.getContentPath('scheduling') contentPath: config.getContentPath('scheduling')
}); });

View File

@ -7,7 +7,7 @@ var _ = require('lodash'),
errors = require('../errors'), errors = require('../errors'),
settingsCache = require('../settings/cache'), settingsCache = require('../settings/cache'),
i18n = require('../i18n'), i18n = require('../i18n'),
utils = require('../utils'); urlService = require('../services/url');
function GhostMailer() { function GhostMailer() {
var nodemailer = require('nodemailer'), var nodemailer = require('nodemailer'),
@ -40,7 +40,7 @@ GhostMailer.prototype.from = function () {
// Moved it to its own module // Moved it to its own module
GhostMailer.prototype.getDomain = function () { GhostMailer.prototype.getDomain = function () {
var domain = utils.url.urlFor('home', true).match(new RegExp('^https?://([^/:?#]+)(?:[/:?#]|$)', 'i')); var domain = urlService.utils.urlFor('home', true).match(new RegExp('^https?://([^/:?#]+)(?:[/:?#]|$)', 'i'));
return domain && domain[1]; return domain && domain[1];
}; };

View File

@ -3,7 +3,7 @@ var _ = require('lodash').runInContext(),
Promise = require('bluebird'), Promise = require('bluebird'),
path = require('path'), path = require('path'),
htmlToText = require('html-to-text'), htmlToText = require('html-to-text'),
utils = require('../utils'), urlService = require('../services/url'),
templatesDir = path.resolve(__dirname, '..', 'mail', 'templates'); templatesDir = path.resolve(__dirname, '..', 'mail', 'templates');
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g; _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
@ -13,7 +13,7 @@ exports.generateContent = function generateContent(options) {
data; data;
defaults = { defaults = {
siteUrl: utils.url.urlFor('home', true) siteUrl: urlService.utils.urlFor('home', true)
}; };
data = _.defaults(defaults, options.data); data = _.defaults(defaults, options.data);

View File

@ -15,7 +15,8 @@ var _ = require('lodash'),
errors = require('../../errors'), errors = require('../../errors'),
filters = require('../../filters'), filters = require('../../filters'),
schema = require('../../data/schema'), schema = require('../../data/schema'),
utils = require('../../utils'), urlService = require('../../services/url'),
globalUtils = require('../../utils'),
validation = require('../../data/validation'), validation = require('../../data/validation'),
plugins = require('../plugins'), plugins = require('../plugins'),
i18n = require('../../i18n'), i18n = require('../../i18n'),
@ -739,7 +740,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
// the slug may never be longer than the allowed limit of 191 chars, but should also // the slug may never be longer than the allowed limit of 191 chars, but should also
// take the counter into count. We reduce a too long slug to 185 so we're always on the // take the counter into count. We reduce a too long slug to 185 so we're always on the
// safe side, also in terms of checking for existing slugs already. // safe side, also in terms of checking for existing slugs already.
slug = utils.safeString(base, options); slug = globalUtils.safeString(base, options);
if (slug.length > 185) { if (slug.length > 185) {
// CASE: don't cut the slug on import // CASE: don't cut the slug on import
@ -765,7 +766,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
// Check the filtered slug doesn't match any of the reserved keywords // Check the filtered slug doesn't match any of the reserved keywords
return filters.doFilter('slug.reservedSlugs', config.get('slugs').reserved).then(function then(slugList) { return filters.doFilter('slug.reservedSlugs', config.get('slugs').reserved).then(function then(slugList) {
// Some keywords cannot be changed // Some keywords cannot be changed
slugList = _.union(slugList, utils.url.getProtectedSlugs()); slugList = _.union(slugList, urlService.utils.getProtectedSlugs());
return _.includes(slugList, slug) ? slug + '-' + baseName : slug; return _.includes(slugList, slug) ? slug + '-' + baseName : slug;
}).then(function then(slug) { }).then(function then(slug) {

View File

@ -12,7 +12,8 @@ var _ = require('lodash'),
ghostBookshelf = require('./base'), ghostBookshelf = require('./base'),
events = require('../events'), events = require('../events'),
config = require('../config'), config = require('../config'),
utils = require('../utils'), globalUtils = require('../utils'),
urlService = require('../services/url'),
i18n = require('../i18n'), i18n = require('../i18n'),
Post, Post,
Posts; Posts;
@ -217,7 +218,7 @@ Post = ghostBookshelf.Model.extend({
ghostBookshelf.Model.prototype.onSaving.call(this, model, attr, options); ghostBookshelf.Model.prototype.onSaving.call(this, model, attr, options);
if (mobiledoc) { if (mobiledoc) {
this.set('html', utils.mobiledocConverter.render(JSON.parse(mobiledoc))); this.set('html', globalUtils.mobiledocConverter.render(JSON.parse(mobiledoc)));
} }
if (this.hasChanged('html') || !this.get('plaintext')) { if (this.hasChanged('html') || !this.get('plaintext')) {
@ -375,7 +376,7 @@ Post = ghostBookshelf.Model.extend({
} }
if (!options.columns || (options.columns && options.columns.indexOf('url') > -1)) { if (!options.columns || (options.columns && options.columns.indexOf('url') > -1)) {
attrs.url = utils.url.urlPathForPost(attrs); attrs.url = urlService.utils.urlPathForPost(attrs);
} }
if (oldPostId) { if (oldPostId) {

View File

@ -3,7 +3,7 @@ var express = require('express'),
config = require('../../config'), config = require('../../config'),
errors = require('../../errors'), errors = require('../../errors'),
i18n = require('../../i18n'), i18n = require('../../i18n'),
utils = require('../../utils'), urlService = require('../../services/url'),
channelController = require('../../controllers/channel'), channelController = require('../../controllers/channel'),
rssController = require('../../controllers/rss'), rssController = require('../../controllers/rss'),
rssRouter, rssRouter,
@ -18,9 +18,9 @@ function handlePageParam(req, res, next, page) {
if (page === 1) { if (page === 1) {
// Page 1 is an alias, do a permanent 301 redirect // Page 1 is an alias, do a permanent 301 redirect
if (rssRegex.test(req.url)) { if (rssRegex.test(req.url)) {
return utils.url.redirect301(res, req.originalUrl.replace(rssRegex, '/rss/')); return urlService.utils.redirect301(res, req.originalUrl.replace(rssRegex, '/rss/'));
} else { } else {
return utils.url.redirect301(res, req.originalUrl.replace(pageRegex, '/')); return urlService.utils.redirect301(res, req.originalUrl.replace(pageRegex, '/'));
} }
} else if (page < 1 || isNaN(page)) { } else if (page < 1 || isNaN(page)) {
// Nothing less than 1 is a valid page number, go straight to a 404 // Nothing less than 1 is a valid page number, go straight to a 404
@ -50,14 +50,14 @@ rssRouter = function rssRouter(channelMiddleware) {
// @TODO move this to an RSS module // @TODO move this to an RSS module
var router = express.Router({mergeParams: true}), var router = express.Router({mergeParams: true}),
baseRoute = '/rss/', baseRoute = '/rss/',
pageRoute = utils.url.urlJoin(baseRoute, ':page(\\d+)/'); pageRoute = urlService.utils.urlJoin(baseRoute, ':page(\\d+)/');
// @TODO figure out how to collapse this into a single rule // @TODO figure out how to collapse this into a single rule
router.get(baseRoute, channelMiddleware, rssConfigMiddleware, rssController); router.get(baseRoute, channelMiddleware, rssConfigMiddleware, rssController);
router.get(pageRoute, channelMiddleware, rssConfigMiddleware, rssController); router.get(pageRoute, channelMiddleware, rssConfigMiddleware, rssController);
// Extra redirect rule // Extra redirect rule
router.get('/feed/', function redirectToRSS(req, res) { router.get('/feed/', function redirectToRSS(req, res) {
return utils.url.redirect301(res, utils.url.urlJoin(utils.url.getSubdir(), req.baseUrl, baseRoute)); return urlService.utils.redirect301(res, urlService.utils.urlJoin(urlService.utils.getSubdir(), req.baseUrl, baseRoute));
}); });
router.param('page', handlePageParam); router.param('page', handlePageParam);
@ -67,7 +67,7 @@ rssRouter = function rssRouter(channelMiddleware) {
channelRouter = function channelRouter(channel) { channelRouter = function channelRouter(channel) {
var channelRouter = express.Router({mergeParams: true}), var channelRouter = express.Router({mergeParams: true}),
baseRoute = '/', baseRoute = '/',
pageRoute = utils.url.urlJoin('/', config.get('routeKeywords').page, ':page(\\d+)/'), pageRoute = urlService.utils.urlJoin('/', config.get('routeKeywords').page, ':page(\\d+)/'),
middleware = [channelConfigMiddleware(channel)]; middleware = [channelConfigMiddleware(channel)];
channelRouter.get(baseRoute, middleware, channelController); channelRouter.get(baseRoute, middleware, channelController);
@ -83,7 +83,7 @@ channelRouter = function channelRouter(channel) {
if (channel.editRedirect) { if (channel.editRedirect) {
channelRouter.get('/edit/', function redirect(req, res) { channelRouter.get('/edit/', function redirect(req, res) {
utils.url.redirectToAdmin(302, res, channel.editRedirect.replace(':slug', req.params.slug)); urlService.utils.redirectToAdmin(302, res, channel.editRedirect.replace(':slug', req.params.slug));
}); });
} }

View File

@ -1,6 +1,6 @@
var downsize = require('downsize'), var downsize = require('downsize'),
RSS = require('rss'), RSS = require('rss'),
utils = require('../../utils'), urlService = require('../../services/url'),
filters = require('../../filters'), filters = require('../../filters'),
processUrls = require('../../utils/make-absolute-urls'), processUrls = require('../../utils/make-absolute-urls'),
@ -22,7 +22,7 @@ generateTags = function generateTags(data) {
}; };
generateItem = function generateItem(post, siteUrl, secure) { generateItem = function generateItem(post, siteUrl, secure) {
var itemUrl = utils.url.urlFor('post', {post: post, secure: secure}, true), var itemUrl = urlService.utils.urlFor('post', {post: post, secure: secure}, true),
htmlContent = processUrls(post.html, siteUrl, itemUrl), htmlContent = processUrls(post.html, siteUrl, itemUrl),
item = { item = {
title: post.title, title: post.title,
@ -38,7 +38,7 @@ generateItem = function generateItem(post, siteUrl, secure) {
imageUrl; imageUrl;
if (post.feature_image) { if (post.feature_image) {
imageUrl = utils.url.urlFor('image', {image: post.feature_image, secure: secure}, true); imageUrl = urlService.utils.urlFor('image', {image: post.feature_image, secure: secure}, true);
// Add a media content tag // Add a media content tag
item.custom_elements.push({ item.custom_elements.push({
@ -73,15 +73,15 @@ generateItem = function generateItem(post, siteUrl, secure) {
* @param {{title, description, safeVersion, secure, posts}} data * @param {{title, description, safeVersion, secure, posts}} data
*/ */
generateFeed = function generateFeed(baseUrl, data) { generateFeed = function generateFeed(baseUrl, data) {
var siteUrl = utils.url.urlFor('home', {secure: data.secure}, true), var siteUrl = urlService.utils.urlFor('home', {secure: data.secure}, true),
feedUrl = utils.url.urlFor({relativeUrl: baseUrl, secure: data.secure}, true), feedUrl = urlService.utils.urlFor({relativeUrl: baseUrl, secure: data.secure}, true),
feed = new RSS({ feed = new RSS({
title: data.title, title: data.title,
description: data.description, description: data.description,
generator: 'Ghost ' + data.safeVersion, generator: 'Ghost ' + data.safeVersion,
feed_url: feedUrl, feed_url: feedUrl,
site_url: siteUrl, site_url: siteUrl,
image_url: utils.url.urlFor({relativeUrl: 'favicon.png'}, true), image_url: urlService.utils.urlFor({relativeUrl: 'favicon.png'}, true),
ttl: '60', ttl: '60',
custom_namespaces: { custom_namespaces: {
content: 'http://purl.org/rss/1.0/modules/content/', content: 'http://purl.org/rss/1.0/modules/content/',

View File

@ -2,7 +2,7 @@ var https = require('https'),
url = require('url'), url = require('url'),
errors = require('../errors'), errors = require('../errors'),
logging = require('../logging'), logging = require('../logging'),
utils = require('../utils'), urlService = require('../services/url'),
blogIconUtils = require('../utils/blog-icon'), blogIconUtils = require('../utils/blog-icon'),
events = require('../events'), events = require('../events'),
settingsCache = require('../settings/cache'), settingsCache = require('../settings/cache'),
@ -50,7 +50,7 @@ function ping(post) {
// If this is a post, we want to send the link of the post // If this is a post, we want to send the link of the post
if (schema.isPost(post)) { if (schema.isPost(post)) {
message = utils.url.urlFor('post', {post: post}, true); message = urlService.utils.urlFor('post', {post: post}, true);
} else { } else {
message = post.message; message = post.message;
} }

View File

@ -1,8 +1,7 @@
'use strict'; 'use strict';
const _ = require('lodash'), const _ = require('lodash'),
api = require('../../api'), localUtils = require('./utils'),
utils = require('../../utils'),
prefetchDefaults = { prefetchDefaults = {
context: { context: {
internal: true internal: true
@ -23,7 +22,7 @@ class Resource {
fetchAll() { fetchAll() {
const options = _.defaults(this.prefetchOptions, prefetchDefaults); const options = _.defaults(this.prefetchOptions, prefetchDefaults);
return api[this.api] return require('../../api')[this.api]
.browse(options) .browse(options)
.then((resp) => { .then((resp) => {
this.items = resp[this.api]; this.items = resp[this.api];
@ -35,7 +34,7 @@ class Resource {
const data = { const data = {
[this.urlLookup]: item [this.urlLookup]: item
}; };
return utils.url.urlFor(this.urlLookup, data); return localUtils.urlFor(this.urlLookup, data);
} }
toData(item) { toData(item) {

View File

@ -16,11 +16,12 @@ const _ = require('lodash'),
resourceConfig = require('./config.json'), resourceConfig = require('./config.json'),
Resource = require('./Resource'), Resource = require('./Resource'),
urlCache = require('./cache'), urlCache = require('./cache'),
utils = require('../../utils'); localUtils = require('./utils');
class UrlService { class UrlService {
constructor(options) { constructor(options) {
this.resources = []; this.resources = [];
this.utils = localUtils;
_.each(resourceConfig, (config) => { _.each(resourceConfig, (config) => {
this.resources.push(new Resource(config)); this.resources.push(new Resource(config));
@ -135,7 +136,7 @@ class UrlService {
} }
static cacheRoute(relativeUrl, data) { static cacheRoute(relativeUrl, data) {
const url = utils.url.urlFor({relativeUrl: relativeUrl}); const url = localUtils.urlFor({relativeUrl: relativeUrl});
data.static = true; data.static = true;
urlCache.set(url, data); urlCache.set(url, data);
} }

View File

@ -1,13 +1,13 @@
// Contains all path information to be used throughout the codebase. // Contains all path information to be used throughout the codebase.
// Assumes that config.url is set, and is valid // Assumes that config.url is set, and is valid
var moment = require('moment-timezone'), var moment = require('moment-timezone'),
_ = require('lodash'), _ = require('lodash'),
url = require('url'), url = require('url'),
config = require('./../config'), config = require('../../config/index'),
settingsCache = require('./../settings/cache'), settingsCache = require('../../settings/cache'),
// @TODO: unify this with the path in server/app.js // @TODO: unify this with the path in server/app.js
API_PATH = '/ghost/api/v0.1/', API_PATH = '/ghost/api/v0.1/',
STATIC_IMAGE_URL_PREFIX = 'content/images'; STATIC_IMAGE_URL_PREFIX = 'content/images';
/** /**
@ -174,13 +174,27 @@ function urlPathForPost(post) {
primaryTagFallback = config.get('routeKeywords').primaryTagFallback, primaryTagFallback = config.get('routeKeywords').primaryTagFallback,
publishedAtMoment = moment.tz(post.published_at || Date.now(), settingsCache.get('active_timezone')), publishedAtMoment = moment.tz(post.published_at || Date.now(), settingsCache.get('active_timezone')),
tags = { tags = {
year: function () { return publishedAtMoment.format('YYYY'); }, year: function () {
month: function () { return publishedAtMoment.format('MM'); }, return publishedAtMoment.format('YYYY');
day: function () { return publishedAtMoment.format('DD'); }, },
author: function () { return post.author.slug; }, month: function () {
primary_tag: function () { return post.primary_tag ? post.primary_tag.slug : primaryTagFallback; }, return publishedAtMoment.format('MM');
slug: function () { return post.slug; }, },
id: function () { return post.id; } day: function () {
return publishedAtMoment.format('DD');
},
author: function () {
return post.author.slug;
},
primary_tag: function () {
return post.primary_tag ? post.primary_tag.slug : primaryTagFallback;
},
slug: function () {
return post.slug;
},
id: function () {
return post.id;
}
}; };
if (post.page) { if (post.page) {

View File

@ -2,7 +2,7 @@ var _ = require('lodash'),
http = require('http'), http = require('http'),
xml = require('xml'), xml = require('xml'),
config = require('../config'), config = require('../config'),
utils = require('../utils'), urlService = require('../services/url'),
errors = require('../errors'), errors = require('../errors'),
logging = require('../logging'), logging = require('../logging'),
events = require('../events'), events = require('../events'),
@ -30,7 +30,7 @@ var _ = require('lodash'),
function ping(post) { function ping(post) {
var pingXML, var pingXML,
title = post.title, title = post.title,
url = utils.url.urlFor('post', {post: post}, true); url = urlService.utils.urlFor('post', {post: post}, true);
if (post.page || config.isPrivacyDisabled('useRpcPing') || settingsCache.get('is_private')) { if (post.page || config.isPrivacyDisabled('useRpcPing') || settingsCache.get('is_private')) {
return; return;

View File

@ -5,7 +5,7 @@ var fs = require('fs-extra'),
path = require('path'), path = require('path'),
Promise = require('bluebird'), Promise = require('bluebird'),
config = require('../config'), config = require('../config'),
utils = require('../utils'), globalUtils = require('../utils'),
LocalFileStorage = require('../adapters/storage/LocalFileStorage'), LocalFileStorage = require('../adapters/storage/LocalFileStorage'),
remove = Promise.promisify(fs.remove); remove = Promise.promisify(fs.remove);
@ -31,13 +31,13 @@ class ThemeStorage extends LocalFileStorage {
themePath = path.join(self.storagePath, themeName), themePath = path.join(self.storagePath, themeName),
zipName = themeName + '.zip', zipName = themeName + '.zip',
// store this in a unique temporary folder // store this in a unique temporary folder
zipBasePath = path.join(os.tmpdir(), utils.uid(10)), zipBasePath = path.join(os.tmpdir(), globalUtils.uid(10)),
zipPath = path.join(zipBasePath, zipName), zipPath = path.join(zipBasePath, zipName),
stream; stream;
Promise.promisify(fs.ensureDir)(zipBasePath) Promise.promisify(fs.ensureDir)(zipBasePath)
.then(function () { .then(function () {
return Promise.promisify(utils.zipFolder)(themePath, zipPath); return Promise.promisify(globalUtils.zipFolder)(themePath, zipPath);
}) })
.then(function (length) { .then(function (length) {
res.set({ res.set({

View File

@ -1,6 +1,6 @@
var _ = require('lodash'), var _ = require('lodash'),
hbs = require('./engine'), hbs = require('./engine'),
utils = require('../utils'), urlService = require('../services/url'),
errors = require('../errors'), errors = require('../errors'),
config = require('../config'), config = require('../config'),
i18n = require('../i18n'), i18n = require('../i18n'),
@ -69,7 +69,7 @@ themeMiddleware.updateTemplateData = function updateTemplateData(req, res, next)
// Request-specific information // Request-specific information
// These things are super dependent on the request, so they need to be in middleware // These things are super dependent on the request, so they need to be in middleware
// Serve the blog url without trailing slash // Serve the blog url without trailing slash
blogData.url = utils.url.urlFor('home', {secure: req.secure, trailingSlash: false}, true); blogData.url = urlService.utils.urlFor('home', {secure: req.secure, trailingSlash: false}, true);
// Pass 'secure' flag to the view engine // Pass 'secure' flag to the view engine
// so that templates can choose to render https or http 'url', see url utility // so that templates can choose to render https or http 'url', see url utility

View File

@ -20,21 +20,21 @@
// - theme - name of the currently active theme // - theme - name of the currently active theme
// - apps - names of any active apps // - apps - names of any active apps
var crypto = require('crypto'), var crypto = require('crypto'),
exec = require('child_process').exec, exec = require('child_process').exec,
https = require('https'), https = require('https'),
http = require('http'), http = require('http'),
moment = require('moment'), moment = require('moment'),
semver = require('semver'), semver = require('semver'),
Promise = require('bluebird'), Promise = require('bluebird'),
_ = require('lodash'), _ = require('lodash'),
url = require('url'), url = require('url'),
api = require('./api'), api = require('./api'),
config = require('./config'), config = require('./config'),
utils = require('./utils'), urlService = require('./services/url'),
logging = require('./logging'), logging = require('./logging'),
errors = require('./errors'), errors = require('./errors'),
i18n = require('./i18n'), i18n = require('./i18n'),
currentVersion = require('./utils/ghost-version').full, currentVersion = require('./utils/ghost-version').full,
internal = {context: {internal: true}}, internal = {context: {internal: true}},
checkEndpoint = config.get('updateCheckUrl') || 'https://updates.ghost.org'; checkEndpoint = config.get('updateCheckUrl') || 'https://updates.ghost.org';
@ -87,14 +87,14 @@ function updateCheckData() {
var data = {}, var data = {},
mailConfig = config.get('mail'); mailConfig = config.get('mail');
data.ghost_version = currentVersion; data.ghost_version = currentVersion;
data.node_version = process.versions.node; data.node_version = process.versions.node;
data.env = config.get('env'); data.env = config.get('env');
data.database_type = config.get('database').client; data.database_type = config.get('database').client;
data.email_transport = mailConfig && data.email_transport = mailConfig &&
(mailConfig.options && mailConfig.options.service ? (mailConfig.options && mailConfig.options.service ?
mailConfig.options.service : mailConfig.options.service :
mailConfig.transport); mailConfig.transport);
return Promise.props({ return Promise.props({
hash: api.settings.read(_.extend({key: 'db_hash'}, internal)).reflect(), hash: api.settings.read(_.extend({key: 'db_hash'}, internal)).reflect(),
@ -105,29 +105,31 @@ function updateCheckData() {
apps = JSON.parse(apps.value); apps = JSON.parse(apps.value);
return _.reduce(apps, function (memo, item) { return memo === '' ? memo + item : memo + ', ' + item; }, ''); return _.reduce(apps, function (memo, item) {
return memo === '' ? memo + item : memo + ', ' + item;
}, '');
}).reflect(), }).reflect(),
posts: api.posts.browse().reflect(), posts: api.posts.browse().reflect(),
users: api.users.browse(internal).reflect(), users: api.users.browse(internal).reflect(),
npm: Promise.promisify(exec)('npm -v').reflect() npm: Promise.promisify(exec)('npm -v').reflect()
}).then(function (descriptors) { }).then(function (descriptors) {
var hash = descriptors.hash.value().settings[0], var hash = descriptors.hash.value().settings[0],
theme = descriptors.theme.value().settings[0], theme = descriptors.theme.value().settings[0],
apps = descriptors.apps.value(), apps = descriptors.apps.value(),
posts = descriptors.posts.value(), posts = descriptors.posts.value(),
users = descriptors.users.value(), users = descriptors.users.value(),
npm = descriptors.npm.value(), npm = descriptors.npm.value(),
blogUrl = url.parse(utils.url.urlFor('home', true)), blogUrl = url.parse(urlService.utils.urlFor('home', true)),
blogId = blogUrl.hostname + blogUrl.pathname.replace(/\//, '') + hash.value; blogId = blogUrl.hostname + blogUrl.pathname.replace(/\//, '') + hash.value;
data.blog_id = crypto.createHash('md5').update(blogId).digest('hex'); data.blog_id = crypto.createHash('md5').update(blogId).digest('hex');
data.theme = theme ? theme.value : ''; data.theme = theme ? theme.value : '';
data.apps = apps || ''; data.apps = apps || '';
data.post_count = posts && posts.meta && posts.meta.pagination ? posts.meta.pagination.total : 0; data.post_count = posts && posts.meta && posts.meta.pagination ? posts.meta.pagination.total : 0;
data.user_count = users && users.users && users.users.length ? users.users.length : 0; data.user_count = users && users.users && users.users.length ? users.users.length : 0;
data.blog_created_at = users && users.users && users.users[0] && users.users[0].created_at ? moment(users.users[0].created_at).unix() : ''; data.blog_created_at = users && users.users && users.users[0] && users.users[0].created_at ? moment(users.users[0].created_at).unix() : '';
data.npm_version = npm.trim(); data.npm_version = npm.trim();
data.lts = false; data.lts = false;
return data; return data;
}).catch(updateCheckError); }).catch(updateCheckError);
@ -158,8 +160,12 @@ function updateCheckRequest() {
method: 'POST', method: 'POST',
headers: headers headers: headers
}, function handler(res) { }, function handler(res) {
res.on('error', function onError(error) { reject(error); }); res.on('error', function onError(error) {
res.on('data', function onData(chunk) { resData += chunk; }); reject(error);
});
res.on('data', function onData(chunk) {
resData += chunk;
});
res.on('end', function onEnd() { res.on('end', function onEnd() {
try { try {
resData = JSON.parse(resData); resData = JSON.parse(resData);

View File

@ -1,12 +1,12 @@
var sizeOf = require('image-size'), var sizeOf = require('image-size'),
errors = require('../errors'),
url = require('./url'),
Promise = require('bluebird'), Promise = require('bluebird'),
i18n = require('../i18n'),
settingsCache = require('../settings/cache'),
_ = require('lodash'), _ = require('lodash'),
path = require('path'), path = require('path'),
i18n = require('../i18n'),
errors = require('../errors'),
settingsCache = require('../settings/cache'),
config = require('../config'), config = require('../config'),
urlService = require('../services/url'),
storageUtils = require('../adapters/storage/utils'), storageUtils = require('../adapters/storage/utils'),
getIconDimensions, getIconDimensions,
isIcoImageType, isIcoImageType,
@ -81,15 +81,15 @@ getIconUrl = function getIconUrl(absolut) {
if (absolut) { if (absolut) {
if (blogIcon) { if (blogIcon) {
return isIcoImageType(blogIcon) ? url.urlFor({relativeUrl: '/favicon.ico'}, true) : url.urlFor({relativeUrl: '/favicon.png'}, true); return isIcoImageType(blogIcon) ? urlService.utils.urlFor({relativeUrl: '/favicon.ico'}, true) : urlService.utils.urlFor({relativeUrl: '/favicon.png'}, true);
} else { } else {
return url.urlFor({relativeUrl: '/favicon.ico'}, true); return urlService.utils.urlFor({relativeUrl: '/favicon.ico'}, true);
} }
} else { } else {
if (blogIcon) { if (blogIcon) {
return isIcoImageType(blogIcon) ? url.urlFor({relativeUrl: '/favicon.ico'}) : url.urlFor({relativeUrl: '/favicon.png'}); return isIcoImageType(blogIcon) ? urlService.utils.urlFor({relativeUrl: '/favicon.ico'}) : urlService.utils.urlFor({relativeUrl: '/favicon.png'});
} else { } else {
return url.urlFor({relativeUrl: '/favicon.ico'}); return urlService.utils.urlFor({relativeUrl: '/favicon.ico'});
} }
} }
}; };

View File

@ -3,7 +3,7 @@ var debug = require('ghost-ignition').debug('utils:image-size'),
url = require('url'), url = require('url'),
Promise = require('bluebird'), Promise = require('bluebird'),
request = require('../utils/request'), request = require('../utils/request'),
utils = require('../utils'), urlService = require('../services/url'),
errors = require('../errors'), errors = require('../errors'),
config = require('../config'), config = require('../config'),
storage = require('../adapters/storage'), storage = require('../adapters/storage'),
@ -85,7 +85,7 @@ getImageSizeFromUrl = function getImageSizeFromUrl(imagePath) {
// CASE: pre 1.0 users were able to use an asset path for their blog logo // CASE: pre 1.0 users were able to use an asset path for their blog logo
if (imagePath.match(/^\/assets/)) { if (imagePath.match(/^\/assets/)) {
imagePath = utils.url.urlJoin(utils.url.urlFor('home', true), utils.url.getSubdir(), '/', imagePath); imagePath = urlService.utils.urlJoin(urlService.utils.urlFor('home', true), urlService.utils.getSubdir(), '/', imagePath);
} }
parsedUrl = url.parse(imagePath); parsedUrl = url.parse(imagePath);
@ -174,7 +174,7 @@ getImageSizeFromUrl = function getImageSizeFromUrl(imagePath) {
getImageSizeFromFilePath = function getImageSizeFromFilePath(imagePath) { getImageSizeFromFilePath = function getImageSizeFromFilePath(imagePath) {
var filePath; var filePath;
imagePath = utils.url.urlFor('image', {image: imagePath}, true); imagePath = urlService.utils.urlFor('image', {image: imagePath}, true);
// get the storage readable filePath // get the storage readable filePath
filePath = storageUtils.getLocalFileStoragePath(imagePath); filePath = storageUtils.getLocalFileStoragePath(imagePath);

View File

@ -136,7 +136,6 @@ utils = {
removeOpenRedirectFromUrl: require('./remove-open-redirect-from-url'), removeOpenRedirectFromUrl: require('./remove-open-redirect-from-url'),
zipFolder: require('./zip-folder'), zipFolder: require('./zip-folder'),
generateAssetHash: require('./asset-hash'), generateAssetHash: require('./asset-hash'),
url: require('./url'),
tokens: require('./tokens'), tokens: require('./tokens'),
sequence: require('./sequence'), sequence: require('./sequence'),
ghostVersion: require('./ghost-version'), ghostVersion: require('./ghost-version'),

View File

@ -1,6 +1,6 @@
var cheerio = require('cheerio'), var cheerio = require('cheerio'),
url = require('url'), url = require('url'),
utils = require('../utils'); urlService = require('../services/url');
/** /**
* Make absolute URLs * Make absolute URLs
@ -50,7 +50,7 @@ function makeAbsoluteUrls(html, siteUrl, itemUrl) {
// if the relative URL begins with a '/' use the blog URL (including sub-directory) // if the relative URL begins with a '/' use the blog URL (including sub-directory)
// as the base URL, otherwise use the post's URL. // as the base URL, otherwise use the post's URL.
baseUrl = attributeValue[0] === '/' ? siteUrl : itemUrl; baseUrl = attributeValue[0] === '/' ? siteUrl : itemUrl;
attributeValue = utils.url.urlJoin(baseUrl, attributeValue); attributeValue = urlService.utils.urlJoin(baseUrl, attributeValue);
el.attr(attributeName, attributeValue); el.attr(attributeName, attributeValue);
}); });
}); });

View File

@ -3,7 +3,8 @@ var debug = require('ghost-ignition').debug('admin'),
// App requires // App requires
config = require('../../config'), config = require('../../config'),
utils = require('../../utils'), globalUtils = require('../../utils'),
urlService = require('../../services/url'),
// Middleware // Middleware
// Admin only middleware // Admin only middleware
@ -34,7 +35,7 @@ module.exports = function setupAdminApp() {
configMaxAge = config.get('caching:admin:maxAge'); configMaxAge = config.get('caching:admin:maxAge');
adminApp.use('/assets', serveStatic( adminApp.use('/assets', serveStatic(
config.get('paths').clientAssets, config.get('paths').clientAssets,
{maxAge: (configMaxAge || configMaxAge === 0) ? configMaxAge : utils.ONE_YEAR_MS, fallthrough: false} {maxAge: (configMaxAge || configMaxAge === 0) ? configMaxAge : globalUtils.ONE_YEAR_MS, fallthrough: false}
)); ));
// Service Worker for offline support // Service Worker for offline support
@ -43,7 +44,7 @@ module.exports = function setupAdminApp() {
// Ember CLI's live-reload script // Ember CLI's live-reload script
if (config.get('env') === 'development') { if (config.get('env') === 'development') {
adminApp.get('/ember-cli-live-reload.js', function (req, res) { adminApp.get('/ember-cli-live-reload.js', function (req, res) {
res.redirect('http://localhost:4200' + utils.url.getSubdir() + '/ghost/ember-cli-live-reload.js'); res.redirect('http://localhost:4200' + urlService.utils.getSubdir() + '/ghost/ember-cli-live-reload.js');
}); });
} }

View File

@ -1,12 +1,12 @@
var utils = require('../../utils'); var urlService = require('../../services/url');
function redirectAdminUrls(req, res, next) { function redirectAdminUrls(req, res, next) {
var subdir = utils.url.getSubdir(), var subdir = urlService.utils.getSubdir(),
ghostPathRegex = new RegExp('^' + subdir + '/ghost/(.+)'), ghostPathRegex = new RegExp('^' + subdir + '/ghost/(.+)'),
ghostPathMatch = req.originalUrl.match(ghostPathRegex); ghostPathMatch = req.originalUrl.match(ghostPathRegex);
if (ghostPathMatch) { if (ghostPathMatch) {
return res.redirect(utils.url.urlJoin(utils.url.urlFor('admin'), '#', ghostPathMatch[1])); return res.redirect(urlService.utils.urlJoin(urlService.utils.urlFor('admin'), '#', ghostPathMatch[1]));
} }
next(); next();

View File

@ -1,10 +1,10 @@
var express = require('express'), var express = require('express'),
utils = require('../../utils'), urlService = require('../../services/url'),
adminRedirect; adminRedirect;
adminRedirect = function adminRedirect(path) { adminRedirect = function adminRedirect(path) {
return function doRedirect(req, res) { return function doRedirect(req, res) {
return utils.url.redirectToAdmin(301, res, path); return urlService.utils.redirectToAdmin(301, res, path);
}; };
}; };

View File

@ -2,7 +2,7 @@ var cors = require('cors'),
_ = require('lodash'), _ = require('lodash'),
url = require('url'), url = require('url'),
os = require('os'), os = require('os'),
utils = require('../../../utils'), urlService = require('../../../services/url'),
whitelist = [], whitelist = [],
ENABLE_CORS = {origin: true, maxAge: 86400}, ENABLE_CORS = {origin: true, maxAge: 86400},
DISABLE_CORS = {origin: false}; DISABLE_CORS = {origin: false};
@ -32,8 +32,8 @@ function getIPs() {
} }
function getUrls() { function getUrls() {
var blogHost = url.parse(utils.url.urlFor('home', true)).hostname, var blogHost = url.parse(urlService.utils.urlFor('home', true)).hostname,
adminHost = url.parse(utils.url.urlFor('admin', true)).hostname, adminHost = url.parse(urlService.utils.urlFor('admin', true)).hostname,
urls = []; urls = [];
urls.push(blogHost); urls.push(blogHost);

View File

@ -2,8 +2,8 @@ var fs = require('fs'),
path = require('path'), path = require('path'),
crypto = require('crypto'), crypto = require('crypto'),
storage = require('../../adapters/storage'), storage = require('../../adapters/storage'),
utils = require('../../utils'), urlService = require('../../services/url'),
config = require('../../config'), config = require('../../config'),
settingsCache = require('../../settings/cache'), settingsCache = require('../../settings/cache'),
blogIconUtils = require('../../utils/blog-icon'), blogIconUtils = require('../../utils/blog-icon'),
buildContentResponse, buildContentResponse,
@ -46,7 +46,7 @@ function serveFavicon() {
if (settingsCache.get('icon')) { if (settingsCache.get('icon')) {
// depends on the uploaded icon extension // depends on the uploaded icon extension
if (originalExtension !== requestedExtension) { if (originalExtension !== requestedExtension) {
return res.redirect(302, utils.url.urlFor({relativeUrl: '/favicon' + originalExtension})); return res.redirect(302, urlService.utils.urlFor({relativeUrl: '/favicon' + originalExtension}));
} }
storage.getStorage() storage.getStorage()
@ -64,7 +64,7 @@ function serveFavicon() {
// CASE: always redirect to .ico for default icon // CASE: always redirect to .ico for default icon
if (originalExtension !== requestedExtension) { if (originalExtension !== requestedExtension) {
return res.redirect(302, utils.url.urlFor({relativeUrl: '/favicon.ico'})); return res.redirect(302, urlService.utils.urlFor({relativeUrl: '/favicon.ico'}));
} }
fs.readFile(filePath, function readFile(err, buf) { fs.readFile(filePath, function readFile(err, buf) {

View File

@ -1,8 +1,8 @@
var crypto = require('crypto'), var crypto = require('crypto'),
fs = require('fs'), fs = require('fs'),
path = require('path'), path = require('path'),
config = require('../../config'), config = require('../../config'),
utils = require('../../utils'); urlService = require('../../services/url');
// ### servePublicFile Middleware // ### servePublicFile Middleware
// Handles requests to robots.txt and favicon.ico (and caches them) // Handles requests to robots.txt and favicon.ico (and caches them)
@ -27,8 +27,8 @@ function servePublicFile(file, type, maxAge) {
} }
if (type === 'text/xsl' || type === 'text/plain' || type === 'application/javascript') { if (type === 'text/xsl' || type === 'text/plain' || type === 'application/javascript') {
buf = buf.toString().replace(blogRegex, utils.url.urlFor('home', true).replace(/\/$/, '')); buf = buf.toString().replace(blogRegex, urlService.utils.urlFor('home', true).replace(/\/$/, ''));
buf = buf.toString().replace(apiRegex, utils.url.urlFor('api', {cors: true}, true)); buf = buf.toString().replace(apiRegex, urlService.utils.urlFor('api', {cors: true}, true));
} }
content = { content = {
headers: { headers: {

View File

@ -12,9 +12,10 @@
// req.baseUrl = /blog // req.baseUrl = /blog
// req.path = /ghost/signin/ // req.path = /ghost/signin/
var utils = require('../../utils'), var urlService = require('../../services/url'),
errors = require('../../errors'), errors = require('../../errors'),
i18n = require('../../i18n'), i18n = require('../../i18n'),
globalUtils = require('../../utils'),
uncapitalise; uncapitalise;
uncapitalise = function uncapitalise(req, res, next) { uncapitalise = function uncapitalise(req, res, next) {
@ -47,10 +48,10 @@ uncapitalise = function uncapitalise(req, res, next) {
*/ */
if (/[A-Z]/.test(decodedURI)) { if (/[A-Z]/.test(decodedURI)) {
redirectPath = ( redirectPath = (
utils.removeOpenRedirectFromUrl((req.originalUrl || req.url).replace(pathToTest, pathToTest.toLowerCase())) globalUtils.removeOpenRedirectFromUrl((req.originalUrl || req.url).replace(pathToTest, pathToTest.toLowerCase()))
); );
return utils.url.redirect301(res, redirectPath); return urlService.utils.redirect301(res, redirectPath);
} }
next(); next();

View File

@ -1,6 +1,6 @@
var url = require('url'), var url = require('url'),
debug = require('ghost-ignition').debug('url-redirects'), debug = require('ghost-ignition').debug('url-redirects'),
utils = require('../../utils'), urlService = require('../../services/url'),
urlRedirects, urlRedirects,
_private = {}; _private = {};
@ -26,8 +26,8 @@ _private.redirectUrl = function redirectUrl(options) {
}; };
_private.getAdminRedirectUrl = function getAdminRedirectUrl(options) { _private.getAdminRedirectUrl = function getAdminRedirectUrl(options) {
var blogHostWithProtocol = utils.url.urlFor('home', true), var blogHostWithProtocol = urlService.utils.urlFor('home', true),
adminHostWithProtocol = utils.url.urlFor('admin', true), adminHostWithProtocol = urlService.utils.urlFor('admin', true),
adminHostWithoutProtocol = adminHostWithProtocol.replace(/(^\w+:|^)\/\//, ''), adminHostWithoutProtocol = adminHostWithProtocol.replace(/(^\w+:|^)\/\//, ''),
blogHostWithoutProtocol = blogHostWithProtocol.replace(/(^\w+:|^)\/\//, ''), blogHostWithoutProtocol = blogHostWithProtocol.replace(/(^\w+:|^)\/\//, ''),
requestedHost = options.requestedHost, requestedHost = options.requestedHost,
@ -41,8 +41,8 @@ _private.getAdminRedirectUrl = function getAdminRedirectUrl(options) {
// If url and admin.url are not equal AND the requested host does not match, redirect. // If url and admin.url are not equal AND the requested host does not match, redirect.
// The first condition is the most important, because it ensures that you have a custom admin url configured, // The first condition is the most important, because it ensures that you have a custom admin url configured,
// because we don't force an admin redirect if you have a custom url configured, but no admin url. // because we don't force an admin redirect if you have a custom url configured, but no admin url.
if (adminHostWithoutProtocol !== utils.url.urlJoin(blogHostWithoutProtocol, 'ghost/') && if (adminHostWithoutProtocol !== urlService.utils.urlJoin(blogHostWithoutProtocol, 'ghost/') &&
adminHostWithoutProtocol !== utils.url.urlJoin(requestedHost, utils.url.getSubdir(), 'ghost/')) { adminHostWithoutProtocol !== urlService.utils.urlJoin(requestedHost, urlService.utils.getSubdir(), 'ghost/')) {
debug('redirect because admin host does not match'); debug('redirect because admin host does not match');
return _private.redirectUrl({ return _private.redirectUrl({
@ -53,7 +53,7 @@ _private.getAdminRedirectUrl = function getAdminRedirectUrl(options) {
} }
// CASE: configured admin url is HTTPS, but request is HTTP // CASE: configured admin url is HTTPS, but request is HTTP
if (utils.url.isSSL(adminHostWithProtocol) && !secure) { if (urlService.utils.isSSL(adminHostWithProtocol) && !secure) {
debug('redirect because protocol does not match'); debug('redirect because protocol does not match');
return _private.redirectUrl({ return _private.redirectUrl({
@ -65,7 +65,7 @@ _private.getAdminRedirectUrl = function getAdminRedirectUrl(options) {
}; };
_private.getBlogRedirectUrl = function getBlogRedirectUrl(options) { _private.getBlogRedirectUrl = function getBlogRedirectUrl(options) {
var blogHostWithProtocol = utils.url.urlFor('home', true), var blogHostWithProtocol = urlService.utils.urlFor('home', true),
requestedHost = options.requestedHost, requestedHost = options.requestedHost,
requestedUrl = options.requestedUrl, requestedUrl = options.requestedUrl,
queryParameters = options.queryParameters, queryParameters = options.queryParameters,
@ -74,7 +74,7 @@ _private.getBlogRedirectUrl = function getBlogRedirectUrl(options) {
debug('getBlogRedirectUrl', requestedHost, requestedUrl, blogHostWithProtocol); debug('getBlogRedirectUrl', requestedHost, requestedUrl, blogHostWithProtocol);
// CASE: configured canonical url is HTTPS, but request is HTTP, redirect to requested host + SSL // CASE: configured canonical url is HTTPS, but request is HTTP, redirect to requested host + SSL
if (utils.url.isSSL(blogHostWithProtocol) && !secure) { if (urlService.utils.isSSL(blogHostWithProtocol) && !secure) {
debug('redirect because protocol does not match'); debug('redirect because protocol does not match');
return _private.redirectUrl({ return _private.redirectUrl({
@ -102,7 +102,7 @@ urlRedirects = function urlRedirects(req, res, next) {
if (redirectUrl) { if (redirectUrl) {
debug('url redirect to: ' + redirectUrl); debug('url redirect to: ' + redirectUrl);
return utils.url.redirect301(res, redirectUrl); return urlService.utils.redirect301(res, redirectUrl);
} }
debug('no url redirect'); debug('no url redirect');

View File

@ -4,8 +4,9 @@ var debug = require('ghost-ignition').debug('blog'),
// App requires // App requires
config = require('../../config'), config = require('../../config'),
globalUtils = require('../../utils'),
storage = require('../../adapters/storage'), storage = require('../../adapters/storage'),
utils = require('../../utils'), urlService = require('../../services/url'),
// This should probably be an internal app // This should probably be an internal app
sitemapHandler = require('../../data/xml/sitemap/handler'), sitemapHandler = require('../../data/xml/sitemap/handler'),
@ -51,21 +52,21 @@ module.exports = function setupSiteApp() {
// Favicon // Favicon
siteApp.use(serveFavicon()); siteApp.use(serveFavicon());
// /public/ghost-sdk.js // /public/ghost-sdk.js
siteApp.use(servePublicFile('public/ghost-sdk.js', 'application/javascript', utils.ONE_HOUR_S)); siteApp.use(servePublicFile('public/ghost-sdk.js', 'application/javascript', globalUtils.ONE_HOUR_S));
siteApp.use(servePublicFile('public/ghost-sdk.min.js', 'application/javascript', utils.ONE_HOUR_S)); siteApp.use(servePublicFile('public/ghost-sdk.min.js', 'application/javascript', globalUtils.ONE_HOUR_S));
// Serve sitemap.xsl file // Serve sitemap.xsl file
siteApp.use(servePublicFile('sitemap.xsl', 'text/xsl', utils.ONE_DAY_S)); siteApp.use(servePublicFile('sitemap.xsl', 'text/xsl', globalUtils.ONE_DAY_S));
// Serve stylesheets for default templates // Serve stylesheets for default templates
siteApp.use(servePublicFile('public/ghost.css', 'text/css', utils.ONE_HOUR_S)); siteApp.use(servePublicFile('public/ghost.css', 'text/css', globalUtils.ONE_HOUR_S));
siteApp.use(servePublicFile('public/ghost.min.css', 'text/css', utils.ONE_HOUR_S)); siteApp.use(servePublicFile('public/ghost.min.css', 'text/css', globalUtils.ONE_HOUR_S));
// Serve images for default templates // Serve images for default templates
siteApp.use(servePublicFile('public/404-ghost@2x.png', 'png', utils.ONE_HOUR_S)); siteApp.use(servePublicFile('public/404-ghost@2x.png', 'png', globalUtils.ONE_HOUR_S));
siteApp.use(servePublicFile('public/404-ghost.png', 'png', utils.ONE_HOUR_S)); siteApp.use(servePublicFile('public/404-ghost.png', 'png', globalUtils.ONE_HOUR_S));
// Serve blog images using the storage adapter // Serve blog images using the storage adapter
siteApp.use('/' + utils.url.STATIC_IMAGE_URL_PREFIX, storage.getStorage().serve()); siteApp.use('/' + urlService.utils.STATIC_IMAGE_URL_PREFIX, storage.getStorage().serve());
// @TODO find this a better home // @TODO find this a better home
// We do this here, at the top level, because helpers require so much stuff. // We do this here, at the top level, because helpers require so much stuff.
@ -86,7 +87,7 @@ module.exports = function setupSiteApp() {
debug('Static content done'); debug('Static content done');
// Serve robots.txt if not found in theme // Serve robots.txt if not found in theme
siteApp.use(servePublicFile('robots.txt', 'text/plain', utils.ONE_HOUR_S)); siteApp.use(servePublicFile('robots.txt', 'text/plain', globalUtils.ONE_HOUR_S));
// setup middleware for internal apps // setup middleware for internal apps
// @TODO: refactor this to be a proper app middleware hook for internal & external apps // @TODO: refactor this to be a proper app middleware hook for internal & external apps

View File

@ -13,12 +13,12 @@ var debug = require('ghost-ignition').debug('site:routes'),
// Utils for creating paths // Utils for creating paths
// @TODO: refactor these away // @TODO: refactor these away
config = require('../../config'), config = require('../../config'),
utils = require('../../utils'); urlService = require('../../services/url');
module.exports = function siteRoutes() { module.exports = function siteRoutes() {
// @TODO move this path out of this file! // @TODO move this path out of this file!
// Note this also exists in api/index.js // Note this also exists in api/index.js
var previewRoute = utils.url.urlJoin('/', config.get('routeKeywords').preview, ':uuid', ':options?'); var previewRoute = urlService.utils.urlJoin('/', config.get('routeKeywords').preview, ':uuid', ':options?');
// Preview - register controller as route // Preview - register controller as route
// Ideal version, as we don't want these paths all over the place // Ideal version, as we don't want these paths all over the place

View File

@ -7,7 +7,7 @@ var should = require('should'),
_ = require('lodash'), _ = require('lodash'),
context = testUtils.context, context = testUtils.context,
errors = require('../../../server/errors'), errors = require('../../../server/errors'),
serverUtils = require('../../../server/utils'), globalUtils = require('../../../server/utils'),
apiUtils = require('../../../server/api/utils'), apiUtils = require('../../../server/api/utils'),
SubscribersAPI = require('../../../server/api/subscribers'), SubscribersAPI = require('../../../server/api/subscribers'),
@ -284,7 +284,7 @@ describe('Subscribers API', function () {
}); });
sandbox.stub(apiUtils, 'checkFileExists').returns(true); sandbox.stub(apiUtils, 'checkFileExists').returns(true);
stub = sandbox.stub(apiUtils, 'checkFileIsValid').returns(true); stub = sandbox.stub(apiUtils, 'checkFileIsValid').returns(true);
sandbox.stub(serverUtils, 'readCSV').callsFake(function () { sandbox.stub(globalUtils, 'readCSV').callsFake(function () {
if (scope.csvError) { if (scope.csvError) {
return Promise.reject(new Error('csv')); return Promise.reject(new Error('csv'));
} }

View File

@ -5,7 +5,7 @@ var should = require('should'),
// Stuff we are testing // Stuff we are testing
exporter = require('../../server/data/export'), exporter = require('../../server/data/export'),
utils = require('../../server/utils'), globalUtils = require('../../server/utils'),
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
@ -29,7 +29,7 @@ describe('Exporter', function () {
should.exist(exportData.meta); should.exist(exportData.meta);
should.exist(exportData.data); should.exist(exportData.data);
exportData.meta.version.should.equal(utils.ghostVersion.full); exportData.meta.version.should.equal(globalUtils.ghostVersion.full);
_.each(tables, function (name) { _.each(tables, function (name) {
should.exist(exportData.data[name]); should.exist(exportData.data[name]);

View File

@ -1,9 +1,8 @@
var should = require('should'), var should = require('should'),
sinon = require('sinon'), sinon = require('sinon'),
testUtils = require('../../utils'), testUtils = require('../../utils'),
events = require('../../../server/events'), events = require('../../../server/events'),
utils = require('../../../server/utils'), globalUtils = require('../../../server/utils'),
// Stuff we are testing // Stuff we are testing
AccesstokenModel = require('../../../server/models/accesstoken').Accesstoken, AccesstokenModel = require('../../../server/models/accesstoken').Accesstoken,
@ -31,7 +30,7 @@ describe('Accesstoken Model', function () {
token: 'foobartoken', token: 'foobartoken',
user_id: testUtils.DataGenerator.Content.users[0].id, user_id: testUtils.DataGenerator.Content.users[0].id,
client_id: testUtils.DataGenerator.forKnex.clients[0].id, client_id: testUtils.DataGenerator.forKnex.clients[0].id,
expires: Date.now() + utils.ONE_MONTH_MS expires: Date.now() + globalUtils.ONE_MONTH_MS
}) })
.then(function (token) { .then(function (token) {
should.exist(token); should.exist(token);

View File

@ -11,7 +11,7 @@ var should = require('should'),
schedulingUtils = require(config.get('paths').corePath + '/server/adapters/scheduling/utils'), schedulingUtils = require(config.get('paths').corePath + '/server/adapters/scheduling/utils'),
SchedulingDefault = require(config.get('paths').corePath + '/server/adapters/scheduling/SchedulingDefault'), SchedulingDefault = require(config.get('paths').corePath + '/server/adapters/scheduling/SchedulingDefault'),
postScheduling = require(config.get('paths').corePath + '/server/adapters/scheduling/post-scheduling'), postScheduling = require(config.get('paths').corePath + '/server/adapters/scheduling/post-scheduling'),
generalUtils = require(__dirname + '/../../../../../server/utils'), urlService = require('../../../../../server/services/url'),
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
@ -70,7 +70,7 @@ describe('Scheduling: Post Scheduling', function () {
scope.adapter.schedule.calledWith({ scope.adapter.schedule.calledWith({
time: moment(scope.post.get('published_at')).valueOf(), time: moment(scope.post.get('published_at')).valueOf(),
url: generalUtils.url.urlJoin(scope.apiUrl, 'schedules', 'posts', scope.post.get('id')) + '?client_id=' + scope.client.get('slug') + '&client_secret=' + scope.client.get('secret'), url: urlService.utils.urlJoin(scope.apiUrl, 'schedules', 'posts', scope.post.get('id')) + '?client_id=' + scope.client.get('slug') + '&client_secret=' + scope.client.get('secret'),
extra: { extra: {
httpMethod: 'PUT', httpMethod: 'PUT',
oldTime: null oldTime: null

View File

@ -1,6 +1,6 @@
var should = require('should'), var should = require('should'),
sinon = require('sinon'), sinon = require('sinon'),
utils = require('../../../../server/utils'), urlService = require('../../../../server/services/url'),
// Stuff we are testing // Stuff we are testing
storageUtils = require('../../../../server/adapters/storage/utils'), storageUtils = require('../../../../server/adapters/storage/utils'),
@ -24,9 +24,9 @@ describe('storage utils', function () {
var url = 'http://myblog.com/content/images/2017/07/ghost-logo.png', var url = 'http://myblog.com/content/images/2017/07/ghost-logo.png',
result; result;
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
result = storageUtils.getLocalFileStoragePath(url); result = storageUtils.getLocalFileStoragePath(url);
@ -41,9 +41,9 @@ describe('storage utils', function () {
var url = 'https://myblog.com/content/images/2017/07/ghost-logo.png', var url = 'https://myblog.com/content/images/2017/07/ghost-logo.png',
result; result;
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
result = storageUtils.getLocalFileStoragePath(url); result = storageUtils.getLocalFileStoragePath(url);
@ -55,9 +55,9 @@ describe('storage utils', function () {
var url = 'http://myblog.com/blog/content/images/2017/07/ghost-logo.png', var url = 'http://myblog.com/blog/content/images/2017/07/ghost-logo.png',
result; result;
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns('/blog'); urlGetSubdirStub.returns('/blog');
result = storageUtils.getLocalFileStoragePath(url); result = storageUtils.getLocalFileStoragePath(url);
@ -69,9 +69,9 @@ describe('storage utils', function () {
var filePath = '/content/images/2017/07/ghost-logo.png', var filePath = '/content/images/2017/07/ghost-logo.png',
result; result;
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
result = storageUtils.getLocalFileStoragePath(filePath); result = storageUtils.getLocalFileStoragePath(filePath);
@ -83,9 +83,9 @@ describe('storage utils', function () {
var filePath = '/blog/content/images/2017/07/ghost-logo.png', var filePath = '/blog/content/images/2017/07/ghost-logo.png',
result; result;
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns('/blog'); urlGetSubdirStub.returns('/blog');
result = storageUtils.getLocalFileStoragePath(filePath); result = storageUtils.getLocalFileStoragePath(filePath);
@ -97,9 +97,9 @@ describe('storage utils', function () {
var url = 'http://example-blog.com/ghost-logo.png', var url = 'http://example-blog.com/ghost-logo.png',
result; result;
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
result = storageUtils.getLocalFileStoragePath(url); result = storageUtils.getLocalFileStoragePath(url);
@ -113,9 +113,9 @@ describe('storage utils', function () {
var url = 'http://myblog.com/content/images/2017/07/ghost-logo.png', var url = 'http://myblog.com/content/images/2017/07/ghost-logo.png',
result; result;
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
result = storageUtils.isLocalImage(url); result = storageUtils.isLocalImage(url);
@ -130,9 +130,9 @@ describe('storage utils', function () {
var url = 'https://myblog.com/content/images/2017/07/ghost-logo.png', var url = 'https://myblog.com/content/images/2017/07/ghost-logo.png',
result; result;
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
result = storageUtils.isLocalImage(url); result = storageUtils.isLocalImage(url);
@ -144,9 +144,9 @@ describe('storage utils', function () {
var url = 'http://myblog.com/blog/content/images/2017/07/ghost-logo.png', var url = 'http://myblog.com/blog/content/images/2017/07/ghost-logo.png',
result; result;
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns('/blog'); urlGetSubdirStub.returns('/blog');
result = storageUtils.isLocalImage(url); result = storageUtils.isLocalImage(url);
@ -158,9 +158,9 @@ describe('storage utils', function () {
var url = '/content/images/2017/07/ghost-logo.png', var url = '/content/images/2017/07/ghost-logo.png',
result; result;
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
result = storageUtils.isLocalImage(url); result = storageUtils.isLocalImage(url);
@ -172,9 +172,9 @@ describe('storage utils', function () {
var url = '/blog/content/images/2017/07/ghost-logo.png', var url = '/blog/content/images/2017/07/ghost-logo.png',
result; result;
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns('/blog'); urlGetSubdirStub.returns('/blog');
result = storageUtils.isLocalImage(url); result = storageUtils.isLocalImage(url);
@ -186,9 +186,9 @@ describe('storage utils', function () {
var url = 'http://somewebsite.com/ghost-logo.png', var url = 'http://somewebsite.com/ghost-logo.png',
result; result;
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
result = storageUtils.isLocalImage(url); result = storageUtils.isLocalImage(url);

View File

@ -6,6 +6,7 @@ var should = require('should'),
authStrategies = require('../../../server/auth/auth-strategies'), authStrategies = require('../../../server/auth/auth-strategies'),
Models = require('../../../server/models'), Models = require('../../../server/models'),
errors = require('../../../server/errors'), errors = require('../../../server/errors'),
urlService = require('../../../server/services/url'),
globalUtils = require('../../../server/utils'), globalUtils = require('../../../server/utils'),
sandbox = sinon.sandbox.create(), sandbox = sinon.sandbox.create(),

View File

@ -1,7 +1,7 @@
var should = require('should'), // jshint ignore:line var should = require('should'), // jshint ignore:line
ghostSdk = require('../../server/public/ghost-sdk'), ghostSdk = require('../../server/public/ghost-sdk'),
configUtils = require('../utils/configUtils'), configUtils = require('../utils/configUtils'),
utils = require('../../server/utils'); urlService = require('../../server/services/url');
describe('Ghost Ajax Helper', function () { describe('Ghost Ajax Helper', function () {
beforeEach(function () { beforeEach(function () {
@ -27,7 +27,7 @@ describe('Ghost Ajax Helper', function () {
ghostSdk.init({ ghostSdk.init({
clientId: '', clientId: '',
clientSecret: '', clientSecret: '',
url: utils.url.urlFor('api', {cors: true}, true) url: urlService.utils.urlFor('api', {cors: true}, true)
}); });
ghostSdk.url.api().should.equal('//testblog.com/ghost/api/v0.1/'); ghostSdk.url.api().should.equal('//testblog.com/ghost/api/v0.1/');
@ -41,7 +41,7 @@ describe('Ghost Ajax Helper', function () {
ghostSdk.init({ ghostSdk.init({
clientId: '', clientId: '',
clientSecret: '', clientSecret: '',
url: utils.url.urlFor('api', {cors: true}, true) url: urlService.utils.urlFor('api', {cors: true}, true)
}); });
ghostSdk.url.api().should.equal('https://testblog.com/ghost/api/v0.1/'); ghostSdk.url.api().should.equal('https://testblog.com/ghost/api/v0.1/');
@ -58,7 +58,7 @@ describe('Ghost Ajax Helper', function () {
ghostSdk.init({ ghostSdk.init({
clientId: '', clientId: '',
clientSecret: '', clientSecret: '',
url: utils.url.urlFor('api', {cors: true}, true) url: urlService.utils.urlFor('api', {cors: true}, true)
}); });
ghostSdk.url.api().should.equal('https://admin.testblog.com/ghost/api/v0.1/'); ghostSdk.url.api().should.equal('https://admin.testblog.com/ghost/api/v0.1/');
@ -68,7 +68,7 @@ describe('Ghost Ajax Helper', function () {
ghostSdk.init({ ghostSdk.init({
clientId: '', clientId: '',
clientSecret: '', clientSecret: '',
url: utils.url.urlFor('api', {cors: true}, true) url: urlService.utils.urlFor('api', {cors: true}, true)
}); });
ghostSdk.url.api('a/', '/b', '/c/').should.equal('//testblog.com/ghost/api/v0.1/a/b/c/'); ghostSdk.url.api('a/', '/b', '/c/').should.equal('//testblog.com/ghost/api/v0.1/a/b/c/');
@ -78,7 +78,7 @@ describe('Ghost Ajax Helper', function () {
ghostSdk.init({ ghostSdk.init({
clientId: 'ghost-frontend', clientId: 'ghost-frontend',
clientSecret: 'notasecret', clientSecret: 'notasecret',
url: utils.url.urlFor('api', {cors: true}, true) url: urlService.utils.urlFor('api', {cors: true}, true)
}); });
ghostSdk.url.api().should.equal('//testblog.com/ghost/api/v0.1/?client_id=ghost-frontend&client_secret=notasecret'); ghostSdk.url.api().should.equal('//testblog.com/ghost/api/v0.1/?client_id=ghost-frontend&client_secret=notasecret');
@ -88,7 +88,7 @@ describe('Ghost Ajax Helper', function () {
ghostSdk.init({ ghostSdk.init({
clientId: 'ghost-frontend', clientId: 'ghost-frontend',
clientSecret: 'notasecret', clientSecret: 'notasecret',
url: utils.url.urlFor('api', {cors: true}, true) url: urlService.utils.urlFor('api', {cors: true}, true)
}); });
var rendered = ghostSdk.url.api({a: 'string', b: 5, c: 'en coded'}); var rendered = ghostSdk.url.api({a: 'string', b: 5, c: 'en coded'});
@ -126,7 +126,7 @@ describe('Ghost Ajax Helper', function () {
ghostSdk.init({ ghostSdk.init({
clientId: 'ghost-frontend', clientId: 'ghost-frontend',
clientSecret: 'notasecret', clientSecret: 'notasecret',
url: utils.url.urlFor('api', {cors: true}, true) url: urlService.utils.urlFor('api', {cors: true}, true)
}); });
var rendered = ghostSdk.url.api('posts/', '/tags/', '/count', {include: 'tags,tests', page: 2}); var rendered = ghostSdk.url.api('posts/', '/tags/', '/count', {include: 'tags,tests', page: 2});
@ -146,7 +146,7 @@ describe('Ghost Ajax Helper', function () {
ghostSdk.init({ ghostSdk.init({
clientId: 'ghost-frontend', clientId: 'ghost-frontend',
clientSecret: 'notasecret', clientSecret: 'notasecret',
url: utils.url.urlFor('api', true) url: urlService.utils.urlFor('api', true)
}); });
var rendered = ghostSdk.url.api('posts/', '/tags/', '/count', {include: 'tags,tests', page: 2}); var rendered = ghostSdk.url.api('posts/', '/tags/', '/count', {include: 'tags,tests', page: 2});
@ -165,7 +165,7 @@ describe('Ghost Ajax Helper', function () {
ghostSdk.init({ ghostSdk.init({
clientId: 'ghost-frontend', clientId: 'ghost-frontend',
clientSecret: 'notasecret', clientSecret: 'notasecret',
url: utils.url.urlFor('api', true) url: urlService.utils.urlFor('api', true)
}); });
var rendered = ghostSdk.url.api('posts/', '/tags/', '/count', {include: 'tags,tests', page: 2}); var rendered = ghostSdk.url.api('posts/', '/tags/', '/count', {include: 'tags,tests', page: 2});
@ -185,7 +185,7 @@ describe('Ghost Ajax Helper', function () {
ghostSdk.init({ ghostSdk.init({
clientId: 'ghost-frontend', clientId: 'ghost-frontend',
clientSecret: 'notasecret', clientSecret: 'notasecret',
url: utils.url.urlFor('api', {cors: true}, true) url: urlService.utils.urlFor('api', {cors: true}, true)
}); });
var rendered = ghostSdk.url.api('posts', {limit: 3}), var rendered = ghostSdk.url.api('posts', {limit: 3}),

View File

@ -10,7 +10,7 @@ var should = require('should'), // jshint ignore:line,
// Stuff we test // Stuff we test
slack = rewire('../../../server/services/slack'), slack = rewire('../../../server/services/slack'),
events = require('../../../server/events'), events = require('../../../server/events'),
utils = require('../../../server/utils'), urlService = require('../../../server/services/url'),
schema = require('../../../server/data/schema').checks, schema = require('../../../server/data/schema').checks,
settingsCache = require('../../../server/settings/cache'), settingsCache = require('../../../server/settings/cache'),
@ -165,7 +165,7 @@ describe('Slack', function () {
beforeEach(function () { beforeEach(function () {
isPostStub = sandbox.stub(schema, 'isPost'); isPostStub = sandbox.stub(schema, 'isPost');
urlForSpy = sandbox.spy(utils.url, 'urlFor'); urlForSpy = sandbox.spy(urlService.utils, 'urlFor');
settingsCacheStub = sandbox.stub(settingsCache, 'get'); settingsCacheStub = sandbox.stub(settingsCache, 'get');

View File

@ -6,7 +6,7 @@ var should = require('should'),
// Stuff we are testing // Stuff we are testing
api = require('../../../server/api'), api = require('../../../server/api'),
utils = require('../../../server/utils'), urlService = require('../../../server/services/url'),
BaseGenerator = require('../../../server/data/xml/sitemap/base-generator'), BaseGenerator = require('../../../server/data/xml/sitemap/base-generator'),
PostGenerator = require('../../../server/data/xml/sitemap/post-generator'), PostGenerator = require('../../../server/data/xml/sitemap/post-generator'),
PageGenerator = require('../../../server/data/xml/sitemap/page-generator'), PageGenerator = require('../../../server/data/xml/sitemap/page-generator'),
@ -237,7 +237,7 @@ describe('Generators', function () {
generator.init().then(function () { generator.init().then(function () {
should.exist(generator.siteMapContent); should.exist(generator.siteMapContent);
generator.siteMapContent.should.containEql('<loc>' + utils.url.urlFor('home', true) + '</loc>'); generator.siteMapContent.should.containEql('<loc>' + urlService.utils.urlFor('home', true) + '</loc>');
// <loc> should exist exactly one time // <loc> should exist exactly one time
generator.siteMapContent.indexOf('<loc>').should.eql(generator.siteMapContent.lastIndexOf('<loc>')); generator.siteMapContent.indexOf('<loc>').should.eql(generator.siteMapContent.lastIndexOf('<loc>'));
@ -259,8 +259,8 @@ describe('Generators', function () {
generator.init().then(function () { generator.init().then(function () {
should.exist(generator.siteMapContent); should.exist(generator.siteMapContent);
generator.siteMapContent.should.containEql('<loc>' + utils.url.urlFor('home', true) + '</loc>'); generator.siteMapContent.should.containEql('<loc>' + urlService.utils.urlFor('home', true) + '</loc>');
generator.siteMapContent.should.containEql('<loc>' + utils.url.urlFor('page', {url: 'magic'}, true) + '</loc>'); generator.siteMapContent.should.containEql('<loc>' + urlService.utils.urlFor('page', {url: 'magic'}, true) + '</loc>');
done(); done();
}).catch(done); }).catch(done);

View File

@ -2,11 +2,11 @@ var should = require('should'),
sinon = require('sinon'), sinon = require('sinon'),
rewire = require('rewire'), rewire = require('rewire'),
nock = require('nock'), nock = require('nock'),
path = require('path'),
configUtils = require('../../utils/configUtils'), configUtils = require('../../utils/configUtils'),
utils = require('../../../server/utils'), urlService = require('../../../server/services/url'),
errors = require('../../../server/errors'), errors = require('../../../server/errors'),
storage = require('../../../server/adapters/storage'), storage = require('../../../server/adapters/storage'),
path = require('path'),
// Stuff we are testing // Stuff we are testing
imageSize = rewire('../../../server/utils/image-size'), imageSize = rewire('../../../server/utils/image-size'),
@ -151,9 +151,9 @@ describe('Image Size', function () {
width: 100 width: 100
}; };
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
requestMock = nock('http://myblog.com') requestMock = nock('http://myblog.com')
@ -264,10 +264,10 @@ describe('Image Size', function () {
}; };
storage.getStorage().storagePath = path.join(__dirname, '../../../test/utils/fixtures/images/'); storage.getStorage().storagePath = path.join(__dirname, '../../../test/utils/fixtures/images/');
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('image').returns('http://myblog.com/content/images/favicon.png'); urlForStub.withArgs('image').returns('http://myblog.com/content/images/favicon.png');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
requestMock = nock('http://myblog.com') requestMock = nock('http://myblog.com')
@ -371,10 +371,10 @@ describe('Image Size', function () {
}; };
storage.getStorage().storagePath = path.join(__dirname, '../../../test/utils/fixtures/images/'); storage.getStorage().storagePath = path.join(__dirname, '../../../test/utils/fixtures/images/');
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('image').returns('http://myblog.com/content/images/ghost-logo.png'); urlForStub.withArgs('image').returns('http://myblog.com/content/images/ghost-logo.png');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
result = imageSize.getImageSizeFromFilePath(url).then(function (res) { result = imageSize.getImageSizeFromFilePath(url).then(function (res) {
@ -401,10 +401,10 @@ describe('Image Size', function () {
}; };
storage.getStorage().storagePath = path.join(__dirname, '../../../test/utils/fixtures/images/'); storage.getStorage().storagePath = path.join(__dirname, '../../../test/utils/fixtures/images/');
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('image').returns('http://myblog.com/blog/content/images/favicon_too_large.png'); urlForStub.withArgs('image').returns('http://myblog.com/blog/content/images/favicon_too_large.png');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns('/blog'); urlGetSubdirStub.returns('/blog');
result = imageSize.getImageSizeFromFilePath(url).then(function (res) { result = imageSize.getImageSizeFromFilePath(url).then(function (res) {
@ -431,10 +431,10 @@ describe('Image Size', function () {
}; };
storage.getStorage().storagePath = path.join(__dirname, '../../../test/utils/fixtures/images/'); storage.getStorage().storagePath = path.join(__dirname, '../../../test/utils/fixtures/images/');
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('image').returns('http://myblog.com/content/images/favicon_multi_sizes.ico'); urlForStub.withArgs('image').returns('http://myblog.com/content/images/favicon_multi_sizes.ico');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
result = imageSize.getImageSizeFromFilePath(url).then(function (res) { result = imageSize.getImageSizeFromFilePath(url).then(function (res) {
@ -455,10 +455,10 @@ describe('Image Size', function () {
urlGetSubdirStub; urlGetSubdirStub;
storage.getStorage().storagePath = path.join(__dirname, '../../../test/utils/fixtures/images/'); storage.getStorage().storagePath = path.join(__dirname, '../../../test/utils/fixtures/images/');
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('image').returns('http://myblog.com/content/images/not-existing-image.png'); urlForStub.withArgs('image').returns('http://myblog.com/content/images/not-existing-image.png');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
result = imageSize.getImageSizeFromFilePath(url) result = imageSize.getImageSizeFromFilePath(url)
@ -479,10 +479,10 @@ describe('Image Size', function () {
imageSize.__set__('sizeOf', sizeOfStub); imageSize.__set__('sizeOf', sizeOfStub);
storage.getStorage().storagePath = path.join(__dirname, '../../../test/utils/fixtures/images/'); storage.getStorage().storagePath = path.join(__dirname, '../../../test/utils/fixtures/images/');
urlForStub = sandbox.stub(utils.url, 'urlFor'); urlForStub = sandbox.stub(urlService.utils, 'urlFor');
urlForStub.withArgs('image').returns('http://myblog.com/content/images/ghost-logo.pngx'); urlForStub.withArgs('image').returns('http://myblog.com/content/images/ghost-logo.pngx');
urlForStub.withArgs('home').returns('http://myblog.com/'); urlForStub.withArgs('home').returns('http://myblog.com/');
urlGetSubdirStub = sandbox.stub(utils.url, 'getSubdir'); urlGetSubdirStub = sandbox.stub(urlService.utils, 'getSubdir');
urlGetSubdirStub.returns(''); urlGetSubdirStub.returns('');
result = imageSize.getImageSizeFromFilePath(url) result = imageSize.getImageSizeFromFilePath(url)

View File

@ -1,11 +1,11 @@
var should = require('should'), var should = require('should'),
utils = require('../../../server/utils'),
path = require('path'), path = require('path'),
globalUtils = require('../../../server/utils'),
csvPath = path.join(__dirname, '../../utils/fixtures/csv/'); csvPath = path.join(__dirname, '../../utils/fixtures/csv/');
describe('read csv', function () { describe('read csv', function () {
it('read csv: one column', function (done) { it('read csv: one column', function (done) {
utils.readCSV({ globalUtils.readCSV({
path: csvPath + 'single-column-with-header.csv', path: csvPath + 'single-column-with-header.csv',
columnsToExtract: [{name: 'email', lookup: /email/i}] columnsToExtract: [{name: 'email', lookup: /email/i}]
}).then(function (result) { }).then(function (result) {
@ -19,7 +19,7 @@ describe('read csv', function () {
}); });
it('read csv: two columns, 1 filter', function (done) { it('read csv: two columns, 1 filter', function (done) {
utils.readCSV({ globalUtils.readCSV({
path: csvPath + 'two-columns-with-header.csv', path: csvPath + 'two-columns-with-header.csv',
columnsToExtract: [{name: 'email', lookup: /email/i}] columnsToExtract: [{name: 'email', lookup: /email/i}]
}).then(function (result) { }).then(function (result) {
@ -34,7 +34,7 @@ describe('read csv', function () {
}); });
it('read csv: two columns, 2 filters', function (done) { it('read csv: two columns, 2 filters', function (done) {
utils.readCSV({ globalUtils.readCSV({
path: csvPath + 'two-columns-obscure-header.csv', path: csvPath + 'two-columns-obscure-header.csv',
columnsToExtract: [ columnsToExtract: [
{name: 'email', lookup: /email/i}, {name: 'email', lookup: /email/i},

View File

@ -3,7 +3,8 @@ var should = require('should'),
sinon = require('sinon'), sinon = require('sinon'),
_ = require('lodash'), _ = require('lodash'),
moment = require('moment-timezone'), moment = require('moment-timezone'),
utils = require('../../../server/utils'), urlService = require('../../../server/services/url'),
globalUtils = require('../../../server/utils'),
settingsCache = require('../../../server/settings/cache'), settingsCache = require('../../../server/settings/cache'),
configUtils = require('../../utils/configUtils'), configUtils = require('../../utils/configUtils'),
testUtils = require('../../utils'), testUtils = require('../../utils'),
@ -23,180 +24,192 @@ describe('Url', function () {
describe('getProtectedSlugs', function () { describe('getProtectedSlugs', function () {
it('defaults', function () { it('defaults', function () {
utils.url.getProtectedSlugs().should.eql(['ghost', 'rss', 'amp']); urlService.utils.getProtectedSlugs().should.eql(['ghost', 'rss', 'amp']);
}); });
it('url has subdir', function () { it('url has subdir', function () {
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
utils.url.getProtectedSlugs().should.eql(['ghost', 'rss', 'amp', 'blog']); urlService.utils.getProtectedSlugs().should.eql(['ghost', 'rss', 'amp', 'blog']);
}); });
}); });
describe('getSubdir', function () { describe('getSubdir', function () {
it('url has no subdir', function () { it('url has no subdir', function () {
utils.url.getSubdir().should.eql(''); urlService.utils.getSubdir().should.eql('');
}); });
it('url has subdir', function () { it('url has subdir', function () {
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
utils.url.getSubdir().should.eql('/blog'); urlService.utils.getSubdir().should.eql('/blog');
configUtils.set({url: 'http://my-ghost-blog.com/blog/'}); configUtils.set({url: 'http://my-ghost-blog.com/blog/'});
utils.url.getSubdir().should.eql('/blog'); urlService.utils.getSubdir().should.eql('/blog');
configUtils.set({url: 'http://my-ghost-blog.com/my/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/my/blog'});
utils.url.getSubdir().should.eql('/my/blog'); urlService.utils.getSubdir().should.eql('/my/blog');
configUtils.set({url: 'http://my-ghost-blog.com/my/blog/'}); configUtils.set({url: 'http://my-ghost-blog.com/my/blog/'});
utils.url.getSubdir().should.eql('/my/blog'); urlService.utils.getSubdir().should.eql('/my/blog');
}); });
it('should not return a slash for subdir', function () { it('should not return a slash for subdir', function () {
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
utils.url.getSubdir().should.eql(''); urlService.utils.getSubdir().should.eql('');
configUtils.set({url: 'http://my-ghost-blog.com/'}); configUtils.set({url: 'http://my-ghost-blog.com/'});
utils.url.getSubdir().should.eql(''); urlService.utils.getSubdir().should.eql('');
}); });
}); });
describe('urlJoin', function () { describe('urlJoin', function () {
it('should deduplicate slashes', function () { it('should deduplicate slashes', function () {
configUtils.set({url: 'http://my-ghost-blog.com/'}); configUtils.set({url: 'http://my-ghost-blog.com/'});
utils.url.urlJoin('/', '/my/', '/blog/').should.equal('/my/blog/'); urlService.utils.urlJoin('/', '/my/', '/blog/').should.equal('/my/blog/');
utils.url.urlJoin('/', '//my/', '/blog/').should.equal('/my/blog/'); urlService.utils.urlJoin('/', '//my/', '/blog/').should.equal('/my/blog/');
utils.url.urlJoin('/', '/', '/').should.equal('/'); urlService.utils.urlJoin('/', '/', '/').should.equal('/');
}); });
it('should not deduplicate slashes in protocol', function () { it('should not deduplicate slashes in protocol', function () {
configUtils.set({url: 'http://my-ghost-blog.com/'}); configUtils.set({url: 'http://my-ghost-blog.com/'});
utils.url.urlJoin('http://myurl.com', '/rss').should.equal('http://myurl.com/rss'); urlService.utils.urlJoin('http://myurl.com', '/rss').should.equal('http://myurl.com/rss');
utils.url.urlJoin('https://myurl.com/', '/rss').should.equal('https://myurl.com/rss'); urlService.utils.urlJoin('https://myurl.com/', '/rss').should.equal('https://myurl.com/rss');
}); });
it('should permit schemeless protocol', function () { it('should permit schemeless protocol', function () {
configUtils.set({url: 'http://my-ghost-blog.com/'}); configUtils.set({url: 'http://my-ghost-blog.com/'});
utils.url.urlJoin('/', '/').should.equal('/'); urlService.utils.urlJoin('/', '/').should.equal('/');
utils.url.urlJoin('//myurl.com', '/rss').should.equal('//myurl.com/rss'); urlService.utils.urlJoin('//myurl.com', '/rss').should.equal('//myurl.com/rss');
utils.url.urlJoin('//myurl.com/', '/rss').should.equal('//myurl.com/rss'); urlService.utils.urlJoin('//myurl.com/', '/rss').should.equal('//myurl.com/rss');
utils.url.urlJoin('//myurl.com//', 'rss').should.equal('//myurl.com/rss'); urlService.utils.urlJoin('//myurl.com//', 'rss').should.equal('//myurl.com/rss');
utils.url.urlJoin('', '//myurl.com', 'rss').should.equal('//myurl.com/rss'); urlService.utils.urlJoin('', '//myurl.com', 'rss').should.equal('//myurl.com/rss');
}); });
it('should deduplicate subdir', function () { it('should deduplicate subdir', function () {
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
utils.url.urlJoin('blog', 'blog/about').should.equal('blog/about'); urlService.utils.urlJoin('blog', 'blog/about').should.equal('blog/about');
utils.url.urlJoin('blog/', 'blog/about').should.equal('blog/about'); urlService.utils.urlJoin('blog/', 'blog/about').should.equal('blog/about');
configUtils.set({url: 'http://my-ghost-blog.com/my/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/my/blog'});
utils.url.urlJoin('my/blog', 'my/blog/about').should.equal('my/blog/about'); urlService.utils.urlJoin('my/blog', 'my/blog/about').should.equal('my/blog/about');
utils.url.urlJoin('my/blog/', 'my/blog/about').should.equal('my/blog/about'); urlService.utils.urlJoin('my/blog/', 'my/blog/about').should.equal('my/blog/about');
}); });
}); });
describe('urlFor', function () { describe('urlFor', function () {
it('should return the home url with no options', function () { it('should return the home url with no options', function () {
utils.url.urlFor().should.equal('/'); urlService.utils.urlFor().should.equal('/');
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
utils.url.urlFor().should.equal('/blog/'); urlService.utils.urlFor().should.equal('/blog/');
configUtils.set({url: 'http://my-ghost-blog.com/blog/'}); configUtils.set({url: 'http://my-ghost-blog.com/blog/'});
utils.url.urlFor().should.equal('/blog/'); urlService.utils.urlFor().should.equal('/blog/');
}); });
it('should return home url when asked for', function () { it('should return home url when asked for', function () {
var testContext = 'home'; var testContext = 'home';
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
utils.url.urlFor(testContext).should.equal('/'); urlService.utils.urlFor(testContext).should.equal('/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/');
utils.url.urlFor(testContext, {secure: true}, true).should.equal('https://my-ghost-blog.com/'); urlService.utils.urlFor(testContext, {secure: true}, true).should.equal('https://my-ghost-blog.com/');
configUtils.set({url: 'http://my-ghost-blog.com/'}); configUtils.set({url: 'http://my-ghost-blog.com/'});
utils.url.urlFor(testContext).should.equal('/'); urlService.utils.urlFor(testContext).should.equal('/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/');
utils.url.urlFor(testContext, {secure: true}, true).should.equal('https://my-ghost-blog.com/'); urlService.utils.urlFor(testContext, {secure: true}, true).should.equal('https://my-ghost-blog.com/');
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
utils.url.urlFor(testContext).should.equal('/blog/'); urlService.utils.urlFor(testContext).should.equal('/blog/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/');
utils.url.urlFor(testContext, {secure: true}, true).should.equal('https://my-ghost-blog.com/blog/'); urlService.utils.urlFor(testContext, {secure: true}, true).should.equal('https://my-ghost-blog.com/blog/');
configUtils.set({url: 'http://my-ghost-blog.com/blog/'}); configUtils.set({url: 'http://my-ghost-blog.com/blog/'});
utils.url.urlFor(testContext).should.equal('/blog/'); urlService.utils.urlFor(testContext).should.equal('/blog/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/');
utils.url.urlFor(testContext, {secure: true}, true).should.equal('https://my-ghost-blog.com/blog/'); urlService.utils.urlFor(testContext, {secure: true}, true).should.equal('https://my-ghost-blog.com/blog/');
// Output blog url without trailing slash // Output blog url without trailing slash
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
utils.url.urlFor(testContext).should.equal('/'); urlService.utils.urlFor(testContext).should.equal('/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/');
utils.url.urlFor(testContext, {secure: true, trailingSlash: false}, true).should.equal('https://my-ghost-blog.com'); urlService.utils.urlFor(testContext, {
secure: true,
trailingSlash: false
}, true).should.equal('https://my-ghost-blog.com');
configUtils.set({url: 'http://my-ghost-blog.com/'}); configUtils.set({url: 'http://my-ghost-blog.com/'});
utils.url.urlFor(testContext).should.equal('/'); urlService.utils.urlFor(testContext).should.equal('/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/');
utils.url.urlFor(testContext, {secure: true, trailingSlash: false}, true).should.equal('https://my-ghost-blog.com'); urlService.utils.urlFor(testContext, {
secure: true,
trailingSlash: false
}, true).should.equal('https://my-ghost-blog.com');
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
utils.url.urlFor(testContext).should.equal('/blog/'); urlService.utils.urlFor(testContext).should.equal('/blog/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/');
utils.url.urlFor(testContext, {secure: true, trailingSlash: false}, true).should.equal('https://my-ghost-blog.com/blog'); urlService.utils.urlFor(testContext, {
secure: true,
trailingSlash: false
}, true).should.equal('https://my-ghost-blog.com/blog');
configUtils.set({url: 'http://my-ghost-blog.com/blog/'}); configUtils.set({url: 'http://my-ghost-blog.com/blog/'});
utils.url.urlFor(testContext).should.equal('/blog/'); urlService.utils.urlFor(testContext).should.equal('/blog/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/');
utils.url.urlFor(testContext, {secure: true, trailingSlash: false}, true).should.equal('https://my-ghost-blog.com/blog'); urlService.utils.urlFor(testContext, {
secure: true,
trailingSlash: false
}, true).should.equal('https://my-ghost-blog.com/blog');
}); });
it('should return rss url when asked for', function () { it('should return rss url when asked for', function () {
var testContext = 'rss'; var testContext = 'rss';
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
utils.url.urlFor(testContext).should.equal('/rss/'); urlService.utils.urlFor(testContext).should.equal('/rss/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/rss/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/rss/');
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
utils.url.urlFor(testContext).should.equal('/blog/rss/'); urlService.utils.urlFor(testContext).should.equal('/blog/rss/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/rss/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/rss/');
}); });
it('should handle weird cases by always returning /', function () { it('should handle weird cases by always returning /', function () {
utils.url.urlFor('').should.equal('/'); urlService.utils.urlFor('').should.equal('/');
utils.url.urlFor('post', {}).should.equal('/'); urlService.utils.urlFor('post', {}).should.equal('/');
utils.url.urlFor('post', {post: {}}).should.equal('/'); urlService.utils.urlFor('post', {post: {}}).should.equal('/');
utils.url.urlFor(null).should.equal('/'); urlService.utils.urlFor(null).should.equal('/');
utils.url.urlFor(undefined).should.equal('/'); urlService.utils.urlFor(undefined).should.equal('/');
utils.url.urlFor({}).should.equal('/'); urlService.utils.urlFor({}).should.equal('/');
utils.url.urlFor({relativeUrl: ''}).should.equal('/'); urlService.utils.urlFor({relativeUrl: ''}).should.equal('/');
utils.url.urlFor({relativeUrl: null}).should.equal('/'); urlService.utils.urlFor({relativeUrl: null}).should.equal('/');
utils.url.urlFor({relativeUrl: undefined}).should.equal('/'); urlService.utils.urlFor({relativeUrl: undefined}).should.equal('/');
}); });
it('should return url for a random path when asked for', function () { it('should return url for a random path when asked for', function () {
var testContext = {relativeUrl: '/about/'}; var testContext = {relativeUrl: '/about/'};
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
utils.url.urlFor(testContext).should.equal('/about/'); urlService.utils.urlFor(testContext).should.equal('/about/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/about/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/about/');
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
utils.url.urlFor(testContext).should.equal('/blog/about/'); urlService.utils.urlFor(testContext).should.equal('/blog/about/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/about/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/about/');
}); });
it('should deduplicate subdirectories in paths', function () { it('should deduplicate subdirectories in paths', function () {
var testContext = {relativeUrl: '/blog/about/'}; var testContext = {relativeUrl: '/blog/about/'};
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
utils.url.urlFor(testContext).should.equal('/blog/about/'); urlService.utils.urlFor(testContext).should.equal('/blog/about/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/about/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/about/');
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
utils.url.urlFor(testContext).should.equal('/blog/about/'); urlService.utils.urlFor(testContext).should.equal('/blog/about/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/about/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/about/');
configUtils.set({url: 'http://my-ghost-blog.com/blog/'}); configUtils.set({url: 'http://my-ghost-blog.com/blog/'});
utils.url.urlFor(testContext).should.equal('/blog/about/'); urlService.utils.urlFor(testContext).should.equal('/blog/about/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/about/'); urlService.utils.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/about/');
}); });
it('should return url for a post from post object', function () { it('should return url for a post from post object', function () {
@ -206,16 +219,16 @@ describe('Url', function () {
// url is now provided on the postmodel, permalinkSetting tests are in the model_post_spec.js test // url is now provided on the postmodel, permalinkSetting tests are in the model_post_spec.js test
testData.post.url = '/short-and-sweet/'; testData.post.url = '/short-and-sweet/';
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
utils.url.urlFor(testContext, testData).should.equal('/short-and-sweet/'); urlService.utils.urlFor(testContext, testData).should.equal('/short-and-sweet/');
utils.url.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/short-and-sweet/'); urlService.utils.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/short-and-sweet/');
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
utils.url.urlFor(testContext, testData).should.equal('/blog/short-and-sweet/'); urlService.utils.urlFor(testContext, testData).should.equal('/blog/short-and-sweet/');
utils.url.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/blog/short-and-sweet/'); urlService.utils.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/blog/short-and-sweet/');
testData.post.url = '/blog-one/'; testData.post.url = '/blog-one/';
utils.url.urlFor(testContext, testData).should.equal('/blog/blog-one/'); urlService.utils.urlFor(testContext, testData).should.equal('/blog/blog-one/');
utils.url.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/blog/blog-one/'); urlService.utils.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/blog/blog-one/');
}); });
it('should return url for a tag when asked for', function () { it('should return url for a tag when asked for', function () {
@ -223,12 +236,12 @@ describe('Url', function () {
testData = {tag: testUtils.DataGenerator.Content.tags[0]}; testData = {tag: testUtils.DataGenerator.Content.tags[0]};
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
utils.url.urlFor(testContext, testData).should.equal('/tag/kitchen-sink/'); urlService.utils.urlFor(testContext, testData).should.equal('/tag/kitchen-sink/');
utils.url.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/tag/kitchen-sink/'); urlService.utils.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/tag/kitchen-sink/');
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
utils.url.urlFor(testContext, testData).should.equal('/blog/tag/kitchen-sink/'); urlService.utils.urlFor(testContext, testData).should.equal('/blog/tag/kitchen-sink/');
utils.url.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/blog/tag/kitchen-sink/'); urlService.utils.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/blog/tag/kitchen-sink/');
}); });
it('should return url for an author when asked for', function () { it('should return url for an author when asked for', function () {
@ -236,12 +249,12 @@ describe('Url', function () {
testData = {author: testUtils.DataGenerator.Content.users[0]}; testData = {author: testUtils.DataGenerator.Content.users[0]};
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
utils.url.urlFor(testContext, testData).should.equal('/author/joe-bloggs/'); urlService.utils.urlFor(testContext, testData).should.equal('/author/joe-bloggs/');
utils.url.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/author/joe-bloggs/'); urlService.utils.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/author/joe-bloggs/');
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
utils.url.urlFor(testContext, testData).should.equal('/blog/author/joe-bloggs/'); urlService.utils.urlFor(testContext, testData).should.equal('/blog/author/joe-bloggs/');
utils.url.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/blog/author/joe-bloggs/'); urlService.utils.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/blog/author/joe-bloggs/');
}); });
it('should return url for an image when asked for', function () { it('should return url for an image when asked for', function () {
@ -251,34 +264,34 @@ describe('Url', function () {
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
testData = {image: '/content/images/my-image.jpg'}; testData = {image: '/content/images/my-image.jpg'};
utils.url.urlFor(testContext, testData).should.equal('/content/images/my-image.jpg'); urlService.utils.urlFor(testContext, testData).should.equal('/content/images/my-image.jpg');
utils.url.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/content/images/my-image.jpg'); urlService.utils.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/content/images/my-image.jpg');
testData = {image: 'http://placekitten.com/500/200'}; testData = {image: 'http://placekitten.com/500/200'};
utils.url.urlFor(testContext, testData).should.equal('http://placekitten.com/500/200'); urlService.utils.urlFor(testContext, testData).should.equal('http://placekitten.com/500/200');
utils.url.urlFor(testContext, testData, true).should.equal('http://placekitten.com/500/200'); urlService.utils.urlFor(testContext, testData, true).should.equal('http://placekitten.com/500/200');
testData = {image: '/blog/content/images/my-image2.jpg'}; testData = {image: '/blog/content/images/my-image2.jpg'};
utils.url.urlFor(testContext, testData).should.equal('/blog/content/images/my-image2.jpg'); urlService.utils.urlFor(testContext, testData).should.equal('/blog/content/images/my-image2.jpg');
// We don't make image urls absolute if they don't look like images relative to the image path // We don't make image urls absolute if they don't look like images relative to the image path
utils.url.urlFor(testContext, testData, true).should.equal('/blog/content/images/my-image2.jpg'); urlService.utils.urlFor(testContext, testData, true).should.equal('/blog/content/images/my-image2.jpg');
configUtils.set({url: 'http://my-ghost-blog.com/blog/'}); configUtils.set({url: 'http://my-ghost-blog.com/blog/'});
testData = {image: '/content/images/my-image3.jpg'}; testData = {image: '/content/images/my-image3.jpg'};
utils.url.urlFor(testContext, testData).should.equal('/content/images/my-image3.jpg'); urlService.utils.urlFor(testContext, testData).should.equal('/content/images/my-image3.jpg');
// We don't make image urls absolute if they don't look like images relative to the image path // We don't make image urls absolute if they don't look like images relative to the image path
utils.url.urlFor(testContext, testData, true).should.equal('/content/images/my-image3.jpg'); urlService.utils.urlFor(testContext, testData, true).should.equal('/content/images/my-image3.jpg');
testData = {image: '/blog/content/images/my-image4.jpg'}; testData = {image: '/blog/content/images/my-image4.jpg'};
utils.url.urlFor(testContext, testData).should.equal('/blog/content/images/my-image4.jpg'); urlService.utils.urlFor(testContext, testData).should.equal('/blog/content/images/my-image4.jpg');
utils.url.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/blog/content/images/my-image4.jpg'); urlService.utils.urlFor(testContext, testData, true).should.equal('http://my-ghost-blog.com/blog/content/images/my-image4.jpg');
// Test case for blogs with optional https - // Test case for blogs with optional https -
// they may be configured with http url but the actual connection may be over https (#8373) // they may be configured with http url but the actual connection may be over https (#8373)
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
testData = {image: '/content/images/my-image.jpg', secure: true}; testData = {image: '/content/images/my-image.jpg', secure: true};
utils.url.urlFor(testContext, testData, true).should.equal('https://my-ghost-blog.com/content/images/my-image.jpg'); urlService.utils.urlFor(testContext, testData, true).should.equal('https://my-ghost-blog.com/content/images/my-image.jpg');
}); });
it('should return a url for a nav item when asked for it', function () { it('should return a url for a nav item when asked for it', function () {
@ -288,65 +301,65 @@ describe('Url', function () {
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
testData = {nav: {url: 'http://my-ghost-blog.com/'}}; testData = {nav: {url: 'http://my-ghost-blog.com/'}};
utils.url.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com/'); urlService.utils.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com/');
testData = {nav: {url: 'http://my-ghost-blog.com/short-and-sweet/'}}; testData = {nav: {url: 'http://my-ghost-blog.com/short-and-sweet/'}};
utils.url.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com/short-and-sweet/'); urlService.utils.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com/short-and-sweet/');
testData = {nav: {url: 'http://my-ghost-blog.com//short-and-sweet/'}, secure: true}; testData = {nav: {url: 'http://my-ghost-blog.com//short-and-sweet/'}, secure: true};
utils.url.urlFor(testContext, testData).should.equal('https://my-ghost-blog.com/short-and-sweet/'); urlService.utils.urlFor(testContext, testData).should.equal('https://my-ghost-blog.com/short-and-sweet/');
testData = {nav: {url: 'http://my-ghost-blog.com:3000/'}}; testData = {nav: {url: 'http://my-ghost-blog.com:3000/'}};
utils.url.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com:3000/'); urlService.utils.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com:3000/');
testData = {nav: {url: 'http://my-ghost-blog.com:3000/short-and-sweet/'}}; testData = {nav: {url: 'http://my-ghost-blog.com:3000/short-and-sweet/'}};
utils.url.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com:3000/short-and-sweet/'); urlService.utils.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com:3000/short-and-sweet/');
testData = {nav: {url: 'http://sub.my-ghost-blog.com/'}}; testData = {nav: {url: 'http://sub.my-ghost-blog.com/'}};
utils.url.urlFor(testContext, testData).should.equal('http://sub.my-ghost-blog.com/'); urlService.utils.urlFor(testContext, testData).should.equal('http://sub.my-ghost-blog.com/');
testData = {nav: {url: '//sub.my-ghost-blog.com/'}}; testData = {nav: {url: '//sub.my-ghost-blog.com/'}};
utils.url.urlFor(testContext, testData).should.equal('//sub.my-ghost-blog.com/'); urlService.utils.urlFor(testContext, testData).should.equal('//sub.my-ghost-blog.com/');
testData = {nav: {url: 'mailto:sub@my-ghost-blog.com/'}}; testData = {nav: {url: 'mailto:sub@my-ghost-blog.com/'}};
utils.url.urlFor(testContext, testData).should.equal('mailto:sub@my-ghost-blog.com/'); urlService.utils.urlFor(testContext, testData).should.equal('mailto:sub@my-ghost-blog.com/');
testData = {nav: {url: '#this-anchor'}}; testData = {nav: {url: '#this-anchor'}};
utils.url.urlFor(testContext, testData).should.equal('#this-anchor'); urlService.utils.urlFor(testContext, testData).should.equal('#this-anchor');
testData = {nav: {url: 'http://some-external-page.com/my-ghost-blog.com'}}; testData = {nav: {url: 'http://some-external-page.com/my-ghost-blog.com'}};
utils.url.urlFor(testContext, testData).should.equal('http://some-external-page.com/my-ghost-blog.com'); urlService.utils.urlFor(testContext, testData).should.equal('http://some-external-page.com/my-ghost-blog.com');
testData = {nav: {url: 'http://some-external-page.com/stuff-my-ghost-blog.com-around'}}; testData = {nav: {url: 'http://some-external-page.com/stuff-my-ghost-blog.com-around'}};
utils.url.urlFor(testContext, testData).should.equal('http://some-external-page.com/stuff-my-ghost-blog.com-around'); urlService.utils.urlFor(testContext, testData).should.equal('http://some-external-page.com/stuff-my-ghost-blog.com-around');
testData = {nav: {url: 'mailto:marshmallow@my-ghost-blog.com'}}; testData = {nav: {url: 'mailto:marshmallow@my-ghost-blog.com'}};
utils.url.urlFor(testContext, testData).should.equal('mailto:marshmallow@my-ghost-blog.com'); urlService.utils.urlFor(testContext, testData).should.equal('mailto:marshmallow@my-ghost-blog.com');
configUtils.set({url: 'http://my-ghost-blog.com/blog'}); configUtils.set({url: 'http://my-ghost-blog.com/blog'});
testData = {nav: {url: 'http://my-ghost-blog.com/blog/'}}; testData = {nav: {url: 'http://my-ghost-blog.com/blog/'}};
utils.url.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com/blog/'); urlService.utils.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com/blog/');
testData = {nav: {url: 'http://my-ghost-blog.com/blog/short-and-sweet/'}}; testData = {nav: {url: 'http://my-ghost-blog.com/blog/short-and-sweet/'}};
utils.url.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com/blog/short-and-sweet/'); urlService.utils.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com/blog/short-and-sweet/');
testData = {nav: {url: 'http://my-ghost-blog.com:3000/blog/'}}; testData = {nav: {url: 'http://my-ghost-blog.com:3000/blog/'}};
utils.url.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com:3000/blog/'); urlService.utils.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com:3000/blog/');
testData = {nav: {url: 'http://my-ghost-blog.com:3000/blog/short-and-sweet/'}}; testData = {nav: {url: 'http://my-ghost-blog.com:3000/blog/short-and-sweet/'}};
utils.url.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com:3000/blog/short-and-sweet/'); urlService.utils.urlFor(testContext, testData).should.equal('http://my-ghost-blog.com:3000/blog/short-and-sweet/');
testData = {nav: {url: 'http://sub.my-ghost-blog.com/blog/'}}; testData = {nav: {url: 'http://sub.my-ghost-blog.com/blog/'}};
utils.url.urlFor(testContext, testData).should.equal('http://sub.my-ghost-blog.com/blog/'); urlService.utils.urlFor(testContext, testData).should.equal('http://sub.my-ghost-blog.com/blog/');
testData = {nav: {url: '//sub.my-ghost-blog.com/blog/'}}; testData = {nav: {url: '//sub.my-ghost-blog.com/blog/'}};
utils.url.urlFor(testContext, testData).should.equal('//sub.my-ghost-blog.com/blog/'); urlService.utils.urlFor(testContext, testData).should.equal('//sub.my-ghost-blog.com/blog/');
}); });
it('sitemap: should return other known paths when requested', function () { it('sitemap: should return other known paths when requested', function () {
configUtils.set({url: 'http://my-ghost-blog.com'}); configUtils.set({url: 'http://my-ghost-blog.com'});
utils.url.urlFor('sitemap_xsl').should.equal('/sitemap.xsl'); urlService.utils.urlFor('sitemap_xsl').should.equal('/sitemap.xsl');
utils.url.urlFor('sitemap_xsl', true).should.equal('http://my-ghost-blog.com/sitemap.xsl'); urlService.utils.urlFor('sitemap_xsl', true).should.equal('http://my-ghost-blog.com/sitemap.xsl');
}); });
it('admin: relative', function () { it('admin: relative', function () {
@ -354,7 +367,7 @@ describe('Url', function () {
url: 'http://my-ghost-blog.com' url: 'http://my-ghost-blog.com'
}); });
utils.url.urlFor('admin').should.equal('/ghost/'); urlService.utils.urlFor('admin').should.equal('/ghost/');
}); });
it('admin: url is http', function () { it('admin: url is http', function () {
@ -362,7 +375,7 @@ describe('Url', function () {
url: 'http://my-ghost-blog.com' url: 'http://my-ghost-blog.com'
}); });
utils.url.urlFor('admin', true).should.equal('http://my-ghost-blog.com/ghost/'); urlService.utils.urlFor('admin', true).should.equal('http://my-ghost-blog.com/ghost/');
}); });
it('admin: custom admin url is set', function () { it('admin: custom admin url is set', function () {
@ -373,7 +386,7 @@ describe('Url', function () {
} }
}); });
utils.url.urlFor('admin', true).should.equal('https://admin.my-ghost-blog.com/ghost/'); urlService.utils.urlFor('admin', true).should.equal('https://admin.my-ghost-blog.com/ghost/');
}); });
it('admin: blog is on subdir', function () { it('admin: blog is on subdir', function () {
@ -381,7 +394,7 @@ describe('Url', function () {
url: 'http://my-ghost-blog.com/blog' url: 'http://my-ghost-blog.com/blog'
}); });
utils.url.urlFor('admin', true).should.equal('http://my-ghost-blog.com/blog/ghost/'); urlService.utils.urlFor('admin', true).should.equal('http://my-ghost-blog.com/blog/ghost/');
}); });
it('admin: blog is on subdir', function () { it('admin: blog is on subdir', function () {
@ -389,7 +402,7 @@ describe('Url', function () {
url: 'http://my-ghost-blog.com/blog/' url: 'http://my-ghost-blog.com/blog/'
}); });
utils.url.urlFor('admin', true).should.equal('http://my-ghost-blog.com/blog/ghost/'); urlService.utils.urlFor('admin', true).should.equal('http://my-ghost-blog.com/blog/ghost/');
}); });
it('admin: blog is on subdir', function () { it('admin: blog is on subdir', function () {
@ -397,7 +410,7 @@ describe('Url', function () {
url: 'http://my-ghost-blog.com/blog' url: 'http://my-ghost-blog.com/blog'
}); });
utils.url.urlFor('admin').should.equal('/blog/ghost/'); urlService.utils.urlFor('admin').should.equal('/blog/ghost/');
}); });
it('admin: blog is on subdir', function () { it('admin: blog is on subdir', function () {
@ -408,7 +421,7 @@ describe('Url', function () {
} }
}); });
utils.url.urlFor('admin', true).should.equal('http://something.com/blog/ghost/'); urlService.utils.urlFor('admin', true).should.equal('http://something.com/blog/ghost/');
}); });
it('admin: blog is on subdir', function () { it('admin: blog is on subdir', function () {
@ -419,7 +432,7 @@ describe('Url', function () {
} }
}); });
utils.url.urlFor('admin', true).should.equal('http://something.com/blog/ghost/'); urlService.utils.urlFor('admin', true).should.equal('http://something.com/blog/ghost/');
}); });
it('admin: blog is on subdir', function () { it('admin: blog is on subdir', function () {
@ -430,7 +443,7 @@ describe('Url', function () {
} }
}); });
utils.url.urlFor('admin', true).should.equal('http://something.com/blog/ghost/'); urlService.utils.urlFor('admin', true).should.equal('http://something.com/blog/ghost/');
}); });
it('admin: blog is on subdir', function () { it('admin: blog is on subdir', function () {
@ -441,7 +454,7 @@ describe('Url', function () {
} }
}); });
utils.url.urlFor('admin', true).should.equal('http://something.com/blog/ghost/'); urlService.utils.urlFor('admin', true).should.equal('http://something.com/blog/ghost/');
}); });
it('api: should return admin url is set', function () { it('api: should return admin url is set', function () {
@ -452,7 +465,7 @@ describe('Url', function () {
} }
}); });
utils.url.urlFor('api', true).should.eql('https://something.de/ghost/api/v0.1/'); urlService.utils.urlFor('api', true).should.eql('https://something.de/ghost/api/v0.1/');
}); });
it('api: url has subdir', function () { it('api: url has subdir', function () {
@ -460,11 +473,11 @@ describe('Url', function () {
url: 'http://my-ghost-blog.com/blog' url: 'http://my-ghost-blog.com/blog'
}); });
utils.url.urlFor('api', true).should.eql('http://my-ghost-blog.com/blog/ghost/api/v0.1/'); urlService.utils.urlFor('api', true).should.eql('http://my-ghost-blog.com/blog/ghost/api/v0.1/');
}); });
it('api: relative path is correct', function () { it('api: relative path is correct', function () {
utils.url.urlFor('api').should.eql('/ghost/api/v0.1/'); urlService.utils.urlFor('api').should.eql('/ghost/api/v0.1/');
}); });
it('api: relative path with subdir is correct', function () { it('api: relative path with subdir is correct', function () {
@ -472,7 +485,7 @@ describe('Url', function () {
url: 'http://my-ghost-blog.com/blog' url: 'http://my-ghost-blog.com/blog'
}); });
utils.url.urlFor('api').should.eql('/blog/ghost/api/v0.1/'); urlService.utils.urlFor('api').should.eql('/blog/ghost/api/v0.1/');
}); });
it('api: should return http if config.url is http', function () { it('api: should return http if config.url is http', function () {
@ -480,7 +493,7 @@ describe('Url', function () {
url: 'http://my-ghost-blog.com' url: 'http://my-ghost-blog.com'
}); });
utils.url.urlFor('api', true).should.eql('http://my-ghost-blog.com/ghost/api/v0.1/'); urlService.utils.urlFor('api', true).should.eql('http://my-ghost-blog.com/ghost/api/v0.1/');
}); });
it('api: should return https if config.url is https', function () { it('api: should return https if config.url is https', function () {
@ -488,7 +501,7 @@ describe('Url', function () {
url: 'https://my-ghost-blog.com' url: 'https://my-ghost-blog.com'
}); });
utils.url.urlFor('api', true).should.eql('https://my-ghost-blog.com/ghost/api/v0.1/'); urlService.utils.urlFor('api', true).should.eql('https://my-ghost-blog.com/ghost/api/v0.1/');
}); });
it('api: with cors, blog url is http: should return no protocol', function () { it('api: with cors, blog url is http: should return no protocol', function () {
@ -496,7 +509,7 @@ describe('Url', function () {
url: 'http://my-ghost-blog.com' url: 'http://my-ghost-blog.com'
}); });
utils.url.urlFor('api', {cors: true}, true).should.eql('//my-ghost-blog.com/ghost/api/v0.1/'); urlService.utils.urlFor('api', {cors: true}, true).should.eql('//my-ghost-blog.com/ghost/api/v0.1/');
}); });
it('api: with cors, admin url is http: cors should return no protocol', function () { it('api: with cors, admin url is http: cors should return no protocol', function () {
@ -507,7 +520,7 @@ describe('Url', function () {
} }
}); });
utils.url.urlFor('api', {cors: true}, true).should.eql('//admin.ghost.example/ghost/api/v0.1/'); urlService.utils.urlFor('api', {cors: true}, true).should.eql('//admin.ghost.example/ghost/api/v0.1/');
}); });
it('api: with cors, admin url is https: should return with protocol', function () { it('api: with cors, admin url is https: should return with protocol', function () {
@ -518,7 +531,7 @@ describe('Url', function () {
} }
}); });
utils.url.urlFor('api', {cors: true}, true).should.eql('https://admin.ghost.example/ghost/api/v0.1/'); urlService.utils.urlFor('api', {cors: true}, true).should.eql('https://admin.ghost.example/ghost/api/v0.1/');
}); });
it('api: with cors, blog url is https: should return with protocol', function () { it('api: with cors, blog url is https: should return with protocol', function () {
@ -526,7 +539,7 @@ describe('Url', function () {
url: 'https://my-ghost-blog.com' url: 'https://my-ghost-blog.com'
}); });
utils.url.urlFor('api', {cors: true}, true).should.eql('https://my-ghost-blog.com/ghost/api/v0.1/'); urlService.utils.urlFor('api', {cors: true}, true).should.eql('https://my-ghost-blog.com/ghost/api/v0.1/');
}); });
}); });
@ -545,7 +558,7 @@ describe('Url', function () {
var testData = testUtils.DataGenerator.Content.posts[2], var testData = testUtils.DataGenerator.Content.posts[2],
postLink = '/short-and-sweet/'; postLink = '/short-and-sweet/';
utils.url.urlPathForPost(testData).should.equal(postLink); urlService.utils.urlPathForPost(testData).should.equal(postLink);
}); });
it('permalink is /:year/:month/:day/:slug, blog timezone is Los Angeles', function () { it('permalink is /:year/:month/:day/:slug, blog timezone is Los Angeles', function () {
@ -556,7 +569,7 @@ describe('Url', function () {
postLink = '/2016/05/17/short-and-sweet/'; postLink = '/2016/05/17/short-and-sweet/';
testData.published_at = new Date('2016-05-18T06:30:00.000Z'); testData.published_at = new Date('2016-05-18T06:30:00.000Z');
utils.url.urlPathForPost(testData).should.equal(postLink); urlService.utils.urlPathForPost(testData).should.equal(postLink);
}); });
it('permalink is /:year/:month/:day/:slug, blog timezone is Asia Tokyo', function () { it('permalink is /:year/:month/:day/:slug, blog timezone is Asia Tokyo', function () {
@ -567,7 +580,7 @@ describe('Url', function () {
postLink = '/2016/05/18/short-and-sweet/'; postLink = '/2016/05/18/short-and-sweet/';
testData.published_at = new Date('2016-05-18T06:30:00.000Z'); testData.published_at = new Date('2016-05-18T06:30:00.000Z');
utils.url.urlPathForPost(testData).should.equal(postLink); urlService.utils.urlPathForPost(testData).should.equal(postLink);
}); });
it('post is page, no permalink usage allowed at all', function () { it('post is page, no permalink usage allowed at all', function () {
@ -577,7 +590,7 @@ describe('Url', function () {
var testData = testUtils.DataGenerator.Content.posts[5], var testData = testUtils.DataGenerator.Content.posts[5],
postLink = '/static-page-test/'; postLink = '/static-page-test/';
utils.url.urlPathForPost(testData).should.equal(postLink); urlService.utils.urlPathForPost(testData).should.equal(postLink);
}); });
it('permalink is /:year/:id:/:author', function () { it('permalink is /:year/:id:/:author', function () {
@ -588,7 +601,7 @@ describe('Url', function () {
postLink = '/2015/3/joe-blog/'; postLink = '/2015/3/joe-blog/';
testData.published_at = new Date('2016-01-01T00:00:00.000Z'); testData.published_at = new Date('2016-01-01T00:00:00.000Z');
utils.url.urlPathForPost(testData).should.equal(postLink); urlService.utils.urlPathForPost(testData).should.equal(postLink);
}); });
it('permalink is /:year/:id:/:author', function () { it('permalink is /:year/:id:/:author', function () {
@ -599,7 +612,7 @@ describe('Url', function () {
postLink = '/2016/3/joe-blog/'; postLink = '/2016/3/joe-blog/';
testData.published_at = new Date('2016-01-01T00:00:00.000Z'); testData.published_at = new Date('2016-01-01T00:00:00.000Z');
utils.url.urlPathForPost(testData).should.equal(postLink); urlService.utils.urlPathForPost(testData).should.equal(postLink);
}); });
it('permalink is /:primary_tag/:slug/ and there is a primary_tag', function () { it('permalink is /:primary_tag/:slug/ and there is a primary_tag', function () {
@ -610,7 +623,7 @@ describe('Url', function () {
postLink = '/bitcoin/short-and-sweet/'; postLink = '/bitcoin/short-and-sweet/';
testData.published_at = new Date('2016-01-01T00:00:00.000Z'); testData.published_at = new Date('2016-01-01T00:00:00.000Z');
utils.url.urlPathForPost(testData).should.equal(postLink); urlService.utils.urlPathForPost(testData).should.equal(postLink);
}); });
it('permalink is /:primary_tag/:slug/ and there is NO primary_tag', function () { it('permalink is /:primary_tag/:slug/ and there is NO primary_tag', function () {
@ -621,7 +634,7 @@ describe('Url', function () {
postLink = '/all/short-and-sweet/'; postLink = '/all/short-and-sweet/';
testData.published_at = new Date('2016-01-01T00:00:00.000Z'); testData.published_at = new Date('2016-01-01T00:00:00.000Z');
utils.url.urlPathForPost(testData).should.equal(postLink); urlService.utils.urlPathForPost(testData).should.equal(postLink);
}); });
it('shows "undefined" for unknown route segments', function () { it('shows "undefined" for unknown route segments', function () {
@ -633,7 +646,7 @@ describe('Url', function () {
postLink = '/undefined/short-and-sweet/'; postLink = '/undefined/short-and-sweet/';
testData.published_at = new Date('2016-01-01T00:00:00.000Z'); testData.published_at = new Date('2016-01-01T00:00:00.000Z');
utils.url.urlPathForPost(testData).should.equal(postLink); urlService.utils.urlPathForPost(testData).should.equal(postLink);
}); });
it('post is not published yet', function () { it('post is not published yet', function () {
@ -648,16 +661,16 @@ describe('Url', function () {
postLink = postLink.replace('MM', nowMoment.format('MM')); postLink = postLink.replace('MM', nowMoment.format('MM'));
postLink = postLink.replace('DD', nowMoment.format('DD')); postLink = postLink.replace('DD', nowMoment.format('DD'));
utils.url.urlPathForPost(testData).should.equal(postLink); urlService.utils.urlPathForPost(testData).should.equal(postLink);
}); });
}); });
describe('isSSL', function () { describe('isSSL', function () {
it('detects https protocol correctly', function () { it('detects https protocol correctly', function () {
utils.url.isSSL('https://my.blog.com').should.be.true(); urlService.utils.isSSL('https://my.blog.com').should.be.true();
utils.url.isSSL('http://my.blog.com').should.be.false(); urlService.utils.isSSL('http://my.blog.com').should.be.false();
utils.url.isSSL('http://my.https.com').should.be.false(); urlService.utils.isSSL('http://my.https.com').should.be.false();
}); });
}); });
describe('redirects', function () { describe('redirects', function () {
@ -669,12 +682,12 @@ describe('Url', function () {
res.redirect = function (code, path) { res.redirect = function (code, path) {
code.should.equal(301); code.should.equal(301);
path.should.eql('my/awesome/path'); path.should.eql('my/awesome/path');
res.set.calledWith({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S}).should.be.true(); res.set.calledWith({'Cache-Control': 'public, max-age=' + globalUtils.ONE_YEAR_S}).should.be.true();
done(); done();
}; };
utils.url.redirect301(res, 'my/awesome/path'); urlService.utils.redirect301(res, 'my/awesome/path');
}); });
it('performs an admin 301 redirect correctly', function (done) { it('performs an admin 301 redirect correctly', function (done) {
@ -685,12 +698,12 @@ describe('Url', function () {
res.redirect = function (code, path) { res.redirect = function (code, path) {
code.should.equal(301); code.should.equal(301);
path.should.eql('/ghost/#/my/awesome/path/'); path.should.eql('/ghost/#/my/awesome/path/');
res.set.calledWith({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S}).should.be.true(); res.set.calledWith({'Cache-Control': 'public, max-age=' + globalUtils.ONE_YEAR_S}).should.be.true();
done(); done();
}; };
utils.url.redirectToAdmin(301, res, '#/my/awesome/path'); urlService.utils.redirectToAdmin(301, res, '#/my/awesome/path');
}); });
it('performs an admin 302 redirect correctly', function (done) { it('performs an admin 302 redirect correctly', function (done) {
@ -705,7 +718,7 @@ describe('Url', function () {
done(); done();
}; };
utils.url.redirectToAdmin(302, res, '#/my/awesome/path'); urlService.utils.redirectToAdmin(302, res, '#/my/awesome/path');
}); });
}); });
}); });

View File

@ -17,7 +17,7 @@ var Promise = require('bluebird'),
schema = require('../../server/data/schema').tables, schema = require('../../server/data/schema').tables,
schemaTables = Object.keys(schema), schemaTables = Object.keys(schema),
models = require('../../server/models'), models = require('../../server/models'),
utils = require('../../server/utils'), urlService = require('../../server/services/url'),
events = require('../../server/events'), events = require('../../server/events'),
SettingsLib = require('../../server/settings'), SettingsLib = require('../../server/settings'),
customRedirectsMiddleware = require('../../server/web/middleware/custom-redirects'), customRedirectsMiddleware = require('../../server/web/middleware/custom-redirects'),
@ -904,7 +904,7 @@ startGhost = function startGhost(options) {
if (options.subdir) { if (options.subdir) {
parentApp = express(); parentApp = express();
parentApp.use(utils.url.getSubdir(), ghostServer.rootApp); parentApp.use(urlService.utils.getSubdir(), ghostServer.rootApp);
return ghostServer.start(parentApp); return ghostServer.start(parentApp);
} }

View File

@ -3,7 +3,7 @@
var startTime = Date.now(), var startTime = Date.now(),
debug = require('ghost-ignition').debug('boot:index'), debug = require('ghost-ignition').debug('boot:index'),
ghost, express, logging, errors, utils, parentApp; ghost, express, logging, errors, urlService, parentApp;
debug('First requires...'); debug('First requires...');
@ -14,13 +14,13 @@ debug('Required ghost');
express = require('express'); express = require('express');
logging = require('./core/server/logging'); logging = require('./core/server/logging');
errors = require('./core/server/errors'); errors = require('./core/server/errors');
utils = require('./core/server/utils'); urlService = require('./core/server/services/url');
parentApp = express(); parentApp = express();
debug('Initialising Ghost'); debug('Initialising Ghost');
ghost().then(function (ghostServer) { ghost().then(function (ghostServer) {
// Mount our Ghost instance on our desired subdirectory path if it exists. // Mount our Ghost instance on our desired subdirectory path if it exists.
parentApp.use(utils.url.getSubdir(), ghostServer.rootApp); parentApp.use(urlService.utils.getSubdir(), ghostServer.rootApp);
debug('Starting Ghost'); debug('Starting Ghost');
// Let Ghost handle starting our server instance. // Let Ghost handle starting our server instance.