Ghost/core/server/helpers/navigation.js
Katharina Irrgang d81bc91bd2 Error creation (#7477)
refs #7116, refs #2001

- Changes the way Ghost errors are implemented to benefit from proper inheritance
- Moves all error definitions into a single file
- Changes the error constructor to take an options object, rather than needing the arguments to be passed in the correct order.
- Provides a wrapper so that any errors that haven't already been converted to GhostErrors get converted before they are displayed.

Summary of changes:

* 🐛  set NODE_ENV in config handler
*   add GhostError implementation (core/server/errors.js)
  - register all errors in one file
  - inheritance from GhostError
  - option pattern
* 🔥  remove all error files
*   wrap all errors into GhostError in case of HTTP
* 🎨  adaptions
  - option pattern for errors
  - use GhostError when needed
* 🎨  revert debug deletion and add TODO for error id's
2016-10-06 13:27:35 +01:00

80 lines
2.3 KiB
JavaScript

// ### Navigation Helper
// `{{navigation}}`
// Outputs navigation menu of static urls
var _ = require('lodash'),
hbs = require('express-hbs'),
i18n = require('../i18n'),
errors = require('../errors'),
template = require('./template'),
navigation;
navigation = function (options) {
/*jshint unused:false*/
var navigationData = options.data.blog.navigation,
currentUrl = options.data.root.relativeUrl,
self = this,
output,
data;
if (!_.isObject(navigationData) || _.isFunction(navigationData)) {
throw new errors.IncorrectUsageError({
message: i18n.t('warnings.helpers.navigation.invalidData')
});
}
if (navigationData.filter(function (e) {
return (_.isUndefined(e.label) || _.isUndefined(e.url));
}).length > 0) {
throw new errors.IncorrectUsageError({
message: i18n.t('warnings.helpers.navigation.valuesMustBeDefined')
});
}
// check for non-null string values
if (navigationData.filter(function (e) {
return ((!_.isNull(e.label) && !_.isString(e.label)) ||
(!_.isNull(e.url) && !_.isString(e.url)));
}).length > 0) {
throw new errors.IncorrectUsageError({
message: i18n.t('warnings.helpers.navigation.valuesMustBeString')
});
}
function _slugify(label) {
return label.toLowerCase().replace(/[^\w ]+/g, '').replace(/ +/g, '-');
}
// strips trailing slashes and compares urls
function _isCurrentUrl(href, currentUrl) {
if (!currentUrl) {
return false;
}
var strippedHref = href.replace(/\/+$/, ''),
strippedCurrentUrl = currentUrl.replace(/\/+$/, '');
return strippedHref === strippedCurrentUrl;
}
// {{navigation}} should no-op if no data passed in
if (navigationData.length === 0) {
return new hbs.SafeString('');
}
output = navigationData.map(function (e) {
var out = {};
out.current = _isCurrentUrl(e.url, currentUrl);
out.label = e.label;
out.slug = _slugify(e.label);
out.url = hbs.handlebars.Utils.escapeExpression(e.url);
out.secure = self.secure;
return out;
});
data = _.merge({}, {navigation: output});
return template.execute('navigation', data, options);
};
module.exports = navigation;