mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-04-15 03:01:37 -05:00
Removed use of i18n from helpers in favour of tpl
- i18n is an old pattern that failed - we are slowly replacing i18n with the tpl helper
This commit is contained in:
parent
1c8c55992a
commit
870bf27394
16 changed files with 113 additions and 41 deletions
|
@ -2,16 +2,20 @@
|
|||
// Usage: `{{asset "css/screen.css"}}`
|
||||
//
|
||||
// Returns the path to the specified asset.
|
||||
const {SafeString, metaData, errors, i18n} = require('../services/proxy');
|
||||
const {SafeString, metaData, errors, tpl} = require('../services/proxy');
|
||||
const get = require('lodash/get');
|
||||
const {getAssetUrl} = metaData;
|
||||
|
||||
const messages = {
|
||||
pathIsRequired: 'The {{asset}} helper must be passed a path'
|
||||
};
|
||||
|
||||
module.exports = function asset(path, options) {
|
||||
const hasMinFile = get(options, 'hash.hasMinFile');
|
||||
|
||||
if (!path) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.asset.pathIsRequired')
|
||||
message: tpl(messages.pathIsRequired)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -6,13 +6,17 @@
|
|||
//
|
||||
// Defaults to class="cancel-subscription-link" errorClass="cancel-subscription-error" cancelLabel="Cancel subscription" continueLabel="Continue subscription"
|
||||
|
||||
const {templates, errors, i18n, labs} = require('../services/proxy');
|
||||
const {templates, errors, tpl, labs} = require('../services/proxy');
|
||||
|
||||
const messages = {
|
||||
invalidData: 'The {{cancel_link}} helper was used outside of a subscription context. See https://ghost.org/docs/themes/members/#cancel-links.'
|
||||
};
|
||||
|
||||
function cancel_link(options) { // eslint-disable-line camelcase
|
||||
let truncateOptions = (options || {}).hash || {};
|
||||
|
||||
if (this.id === undefined || this.cancel_at_period_end === undefined) {
|
||||
throw new errors.IncorrectUsageError({message: i18n.t('warnings.helpers.cancel_link.invalidData')});
|
||||
throw new errors.IncorrectUsageError({message: tpl(messages.invalidData)});
|
||||
}
|
||||
|
||||
const data = {
|
||||
|
|
|
@ -3,13 +3,17 @@
|
|||
//
|
||||
// Block helper designed for looping through posts
|
||||
const _ = require('lodash');
|
||||
const {logging, i18n, hbs, checks} = require('../services/proxy');
|
||||
const {logging, tpl, hbs, checks} = require('../services/proxy');
|
||||
const {Utils: hbsUtils, handlebars: {createFrame}} = hbs;
|
||||
const ghostHelperUtils = require('@tryghost/helpers').utils;
|
||||
|
||||
const messages = {
|
||||
iteratorNeeded: 'Need to pass an iterator to {{#foreach}}'
|
||||
};
|
||||
|
||||
module.exports = function foreach(items, options) {
|
||||
if (!options) {
|
||||
logging.warn(i18n.t('warnings.helpers.foreach.iteratorNeeded'));
|
||||
logging.warn(tpl(messages.iteratorNeeded));
|
||||
}
|
||||
|
||||
if (hbsUtils.isFunction(items)) {
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
// # Get Helper
|
||||
// Usage: `{{#get "posts" limit="5"}}`, `{{#get "tags" limit="all"}}`
|
||||
// Fetches data from the API
|
||||
const {config, logging, errors, i18n, hbs, api, prepareContextResource} = require('../services/proxy');
|
||||
const {config, logging, errors, tpl, hbs, api, prepareContextResource} = require('../services/proxy');
|
||||
const _ = require('lodash');
|
||||
const Promise = require('bluebird');
|
||||
const jsonpath = require('jsonpath');
|
||||
|
||||
const messages = {
|
||||
mustBeCalledAsBlock: 'The {{{helperName}}} helper must be called as a block. E.g. {{#{helperName}}}...{{/{helperName}}}',
|
||||
invalidResource: 'Invalid resource given to get helper'
|
||||
};
|
||||
|
||||
const createFrame = hbs.handlebars.createFrame;
|
||||
|
||||
const RESOURCES = {
|
||||
|
@ -121,13 +126,13 @@ module.exports = function get(resource, options) {
|
|||
let returnedRowsCount;
|
||||
|
||||
if (!options.fn) {
|
||||
data.error = i18n.t('warnings.helpers.mustBeCalledAsBlock', {helperName: 'get'});
|
||||
data.error = tpl(messages.mustBeCalledAsBlock, {helperName: 'get'});
|
||||
logging.warn(data.error);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (!RESOURCES[resource]) {
|
||||
data.error = i18n.t('warnings.helpers.get.invalidResource');
|
||||
data.error = tpl(messages.invalidResource);
|
||||
logging.warn(data.error);
|
||||
return Promise.resolve(options.inverse(self, {data: data}));
|
||||
}
|
||||
|
|
|
@ -4,9 +4,13 @@
|
|||
//
|
||||
// Checks if a post has a particular property
|
||||
|
||||
const {logging, i18n} = require('../services/proxy');
|
||||
const {logging, tpl} = require('../services/proxy');
|
||||
const _ = require('lodash');
|
||||
const validAttrs = ['tag', 'author', 'slug','visibility', 'id', 'number', 'index', 'any', 'all'];
|
||||
const validAttrs = ['tag', 'author', 'slug', 'visibility', 'id', 'number', 'index', 'any', 'all'];
|
||||
|
||||
const messages = {
|
||||
invalidAttribute: 'Invalid or no attribute given to has helper'
|
||||
};
|
||||
|
||||
function handleCount(ctxAttr, data) {
|
||||
if (!data || !_.isFinite(data.length)) {
|
||||
|
@ -155,7 +159,7 @@ module.exports = function has(options) {
|
|||
let result;
|
||||
|
||||
if (_.isEmpty(attrs)) {
|
||||
logging.warn(i18n.t('warnings.helpers.has.invalidAttribute'));
|
||||
logging.warn(tpl(messages.invalidAttribute));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,21 +9,25 @@
|
|||
|
||||
const url = require('url');
|
||||
const _ = require('lodash');
|
||||
const {urlUtils, logging, i18n} = require('../services/proxy');
|
||||
const {urlUtils, logging, tpl} = require('../services/proxy');
|
||||
|
||||
const messages = {
|
||||
attrIsRequired: 'Attribute is required e.g. {{img_url feature_image}}'
|
||||
};
|
||||
|
||||
const STATIC_IMAGE_URL_PREFIX = `${urlUtils.STATIC_IMAGE_URL_PREFIX}`;
|
||||
|
||||
module.exports = function imgUrl(requestedImageUrl, options) {
|
||||
// CASE: if no url is passed, e.g. `{{img_url}}` we show a warning
|
||||
if (arguments.length < 2) {
|
||||
logging.warn(i18n.t('warnings.helpers.img_url.attrIsRequired'));
|
||||
logging.warn(tpl(messages.attrIsRequired));
|
||||
return;
|
||||
}
|
||||
|
||||
// CASE: if url is passed, but it is undefined, then the attribute was
|
||||
// an unknown value, e.g. {{img_url feature_img}} and we also show a warning
|
||||
if (requestedImageUrl === undefined) {
|
||||
logging.warn(i18n.t('warnings.helpers.img_url.attrIsRequired'));
|
||||
logging.warn(tpl(messages.attrIsRequired));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
// # Is Helper
|
||||
// Usage: `{{#is "paged"}}`, `{{#is "index, paged"}}`
|
||||
// Checks whether we're in a given context.
|
||||
const {logging, i18n} = require('../services/proxy');
|
||||
const {logging, tpl} = require('../services/proxy');
|
||||
const _ = require('lodash');
|
||||
|
||||
const messages = {
|
||||
invalidAttribute: 'Invalid or no attribute given to is helper'
|
||||
};
|
||||
|
||||
module.exports = function is(context, options) {
|
||||
options = options || {};
|
||||
|
||||
const currentContext = options.data.root.context;
|
||||
|
||||
if (!_.isString(context)) {
|
||||
logging.warn(i18n.t('warnings.helpers.is.invalidAttribute'));
|
||||
logging.warn(tpl(messages.invalidAttribute));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
// # link helper
|
||||
const _ = require('lodash');
|
||||
const {config, SafeString, errors, i18n, localUtils} = require('../services/proxy');
|
||||
const {config, SafeString, errors, tpl, localUtils} = require('../services/proxy');
|
||||
const {buildLinkClasses} = localUtils;
|
||||
|
||||
const messages = {
|
||||
hrefIsRequired: 'The {{#link}}{{/link}} helper requires an href="" attribute.'
|
||||
};
|
||||
|
||||
const managedAttributes = ['href', 'class', 'activeClass', 'parentActiveClass'];
|
||||
|
||||
function _formatAttrs(attributes) {
|
||||
|
@ -25,7 +29,7 @@ module.exports = function link(options) {
|
|||
// If there is no href provided, this is theme dev error, so we throw an error to make this clear.
|
||||
if (!_.has(options.hash, 'href')) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.link.hrefIsRequired')
|
||||
message: tpl(messages.hrefIsRequired)
|
||||
});
|
||||
}
|
||||
// If the href attribute is empty, this is probably a dynamic data problem, hard for theme devs to track down
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
// # link_class helper
|
||||
const _ = require('lodash');
|
||||
const {config, SafeString, errors, i18n, localUtils} = require('../services/proxy');
|
||||
const {config, SafeString, errors, tpl, localUtils} = require('../services/proxy');
|
||||
const {buildLinkClasses} = localUtils;
|
||||
|
||||
const messages = {
|
||||
forIsRequired: 'The {{link_class}} helper requires a for="" attribute.'
|
||||
};
|
||||
|
||||
module.exports = function link_class(options) { // eslint-disable-line camelcase
|
||||
options = options || {};
|
||||
options.hash = options.hash || {};
|
||||
|
@ -11,7 +15,7 @@ module.exports = function link_class(options) { // eslint-disable-line camelcase
|
|||
// If there is no for provided, this is theme dev error, so we throw an error to make this clear.
|
||||
if (!_.has(options.hash, 'for')) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.link_class.forIsRequired')
|
||||
message: tpl(messages.forIsRequired)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
const {logging, i18n, SafeString, labs} = require('../services/proxy');
|
||||
const {logging, tpl, SafeString, labs} = require('../services/proxy');
|
||||
const _ = require('lodash');
|
||||
|
||||
const messages = {
|
||||
invalidAttribute: 'Invalid or no attribute given to match helper'
|
||||
};
|
||||
|
||||
/**
|
||||
* This is identical to the built-in if helper, except inverse/fn calls are replaced with false/true
|
||||
* https://github.com/handlebars-lang/handlebars.js/blob/19bdace85a8d0bc5ed3a4dec4071cb08c8d003f2/lib/handlebars/helpers/if.js#L9-L20
|
||||
|
@ -58,7 +62,7 @@ function match(...attrs) {
|
|||
let result;
|
||||
|
||||
if (_.isEmpty(attrs)) {
|
||||
logging.warn(i18n.t('warnings.helpers.has.invalidAttribute'));
|
||||
logging.warn(tpl(messages.invalidAttribute));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -68,7 +72,7 @@ function match(...attrs) {
|
|||
} else if (attrs.length === 3) {
|
||||
result = handleMatch(attrs[0], attrs[1], attrs[2], options);
|
||||
} else {
|
||||
logging.warn(i18n.t('warnings.helpers.has.invalidAttribute'));
|
||||
logging.warn(tpl(messages.invalidAttribute));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,16 @@
|
|||
// `{{navigation}}`
|
||||
// Outputs navigation menu of static urls
|
||||
|
||||
const {SafeString, i18n, errors, templates, hbs} = require('../services/proxy');
|
||||
const {SafeString, tpl, errors, templates, hbs} = require('../services/proxy');
|
||||
const {slugify} = require('@tryghost/string');
|
||||
const _ = require('lodash');
|
||||
|
||||
const messages = {
|
||||
invalidData: 'navigation data is not an object or is a function',
|
||||
valuesMustBeDefined: 'All values must be defined for label, url and current',
|
||||
valuesMustBeString: 'Invalid value, Url and Label must be strings'
|
||||
};
|
||||
|
||||
const createFrame = hbs.handlebars.createFrame;
|
||||
|
||||
module.exports = function navigation(options) {
|
||||
|
@ -25,7 +32,7 @@ module.exports = function navigation(options) {
|
|||
|
||||
if (!_.isObject(navigationData) || _.isFunction(navigationData)) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.navigation.invalidData')
|
||||
message: tpl(messages.invalidData)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -33,7 +40,7 @@ module.exports = function navigation(options) {
|
|||
return (_.isUndefined(e.label) || _.isUndefined(e.url));
|
||||
}).length > 0) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.navigation.valuesMustBeDefined')
|
||||
message: tpl(messages.valuesMustBeDefined)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -43,7 +50,7 @@ module.exports = function navigation(options) {
|
|||
(!_.isNull(e.url) && !_.isString(e.url)));
|
||||
}).length > 0) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.navigation.valuesMustBeString')
|
||||
message: tpl(messages.valuesMustBeString)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,16 @@
|
|||
// `{{pagination}}`
|
||||
// Outputs previous and next buttons, along with info about the current page
|
||||
|
||||
const {errors, i18n, templates, hbs} = require('../services/proxy');
|
||||
const {errors, tpl, templates, hbs} = require('../services/proxy');
|
||||
const _ = require('lodash');
|
||||
|
||||
const messages = {
|
||||
invalidData: 'The {{pagination}} helper was used outside of a paginated context. See https://ghost.org/docs/themes/helpers/pagination/.',
|
||||
valuesMustBeDefined: 'All values must be defined for page, pages, limit and total',
|
||||
nextPrevValuesMustBeNumeric: 'Invalid value, Next/Prev must be a number',
|
||||
valuesMustBeNumeric: 'Invalid value, check page, pages, limit and total are numbers'
|
||||
};
|
||||
|
||||
const createFrame = hbs.handlebars.createFrame;
|
||||
|
||||
module.exports = function pagination(options) {
|
||||
|
@ -14,7 +22,7 @@ module.exports = function pagination(options) {
|
|||
if (!_.isObject(this.pagination) || _.isFunction(this.pagination)) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
level: 'normal',
|
||||
message: i18n.t('warnings.helpers.pagination.invalidData'),
|
||||
message: tpl(messages.invalidData),
|
||||
help: 'https://ghost.org/docs/themes/helpers/pagination/'
|
||||
});
|
||||
}
|
||||
|
@ -22,20 +30,20 @@ module.exports = function pagination(options) {
|
|||
if (_.isUndefined(this.pagination.page) || _.isUndefined(this.pagination.pages) ||
|
||||
_.isUndefined(this.pagination.total) || _.isUndefined(this.pagination.limit)) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.pagination.valuesMustBeDefined')
|
||||
message: tpl(messages.valuesMustBeDefined)
|
||||
});
|
||||
}
|
||||
|
||||
if ((!_.isNull(this.pagination.next) && !_.isNumber(this.pagination.next)) ||
|
||||
(!_.isNull(this.pagination.prev) && !_.isNumber(this.pagination.prev))) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.pagination.nextPrevValuesMustBeNumeric')
|
||||
message: tpl(messages.nextPrevValuesMustBeNumeric)
|
||||
});
|
||||
}
|
||||
|
||||
if (!_.isNumber(this.pagination.page) || !_.isNumber(this.pagination.pages) ||
|
||||
!_.isNumber(this.pagination.total) || !_.isNumber(this.pagination.limit)) {
|
||||
throw new errors.IncorrectUsageError({message: i18n.t('warnings.helpers.pagination.valuesMustBeNumeric')});
|
||||
throw new errors.IncorrectUsageError({message: tpl(messages.valuesMustBeNumeric)});
|
||||
}
|
||||
|
||||
// CASE: The pagination helper should have access to the pagination properties at the top level.
|
||||
|
|
|
@ -10,14 +10,18 @@
|
|||
// The 3rd argument is the string that will be output if the variable's value is 1
|
||||
// The 4th argument is the string that will be output if the variable's value is 2+
|
||||
|
||||
const {errors, i18n, SafeString} = require('../services/proxy');
|
||||
const {errors, tpl, SafeString} = require('../services/proxy');
|
||||
const isUndefined = require('lodash/isUndefined');
|
||||
|
||||
const messages = {
|
||||
valuesMustBeDefined: 'All values must be defined for empty, singular and plural'
|
||||
};
|
||||
|
||||
module.exports = function plural(number, options) {
|
||||
if (isUndefined(options.hash) || isUndefined(options.hash.empty) ||
|
||||
isUndefined(options.hash.singular) || isUndefined(options.hash.plural)) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.plural.valuesMustBeDefined')
|
||||
message: tpl(messages.valuesMustBeDefined)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,15 @@
|
|||
// `{{#prev_post}}<a href ="{{url}}>previous post</a>{{/prev_post}}'
|
||||
// `{{#next_post}}<a href ="{{url absolute="true">next post</a>{{/next_post}}'
|
||||
|
||||
const {logging, i18n, api, hbs, checks} = require('../services/proxy');
|
||||
const {logging, tpl, api, hbs, checks} = require('../services/proxy');
|
||||
const get = require('lodash/get');
|
||||
const Promise = require('bluebird');
|
||||
const moment = require('moment');
|
||||
|
||||
const messages = {
|
||||
mustBeCalledAsBlock: 'The {{{helperName}}} helper must be called as a block. E.g. {{#{helperName}}}...{{/{helperName}}}'
|
||||
};
|
||||
|
||||
const createFrame = hbs.handlebars.createFrame;
|
||||
|
||||
const buildApiOptions = function buildApiOptions(options, post) {
|
||||
|
@ -78,7 +82,7 @@ module.exports = function prevNext(options) {
|
|||
|
||||
// Guard against incorrect usage of the helpers
|
||||
if (!options.fn || !options.inverse) {
|
||||
data.error = i18n.t('warnings.helpers.mustBeCalledAsBlock', {helperName: options.name});
|
||||
data.error = tpl(messages.mustBeCalledAsBlock, {helperName: options.name});
|
||||
logging.warn(data.error);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
|
|
@ -11,9 +11,14 @@
|
|||
// Returns amount equal to the dominant denomintation of the currency.
|
||||
// For example, if 2100 is passed, it will return 21.
|
||||
const isNumber = require('lodash/isNumber');
|
||||
const {errors, i18n} = require('../services/proxy');
|
||||
const {errors, tpl} = require('../services/proxy');
|
||||
const _ = require('lodash');
|
||||
|
||||
const messages = {
|
||||
attrIsRequired: 'Attribute is required e.g. {{price plan.amount}}',
|
||||
attrMustBeNumeric: 'Attribute value should be a number'
|
||||
};
|
||||
|
||||
function formatter({amount, currency, numberFormat = 'short', currencyFormat = 'symbol', locale}) {
|
||||
const formatterOptions = {
|
||||
style: 'currency',
|
||||
|
@ -77,20 +82,20 @@ module.exports = function price(planOrAmount, options) {
|
|||
// CASE: if no amount is passed, e.g. `{{price}}` we throw an error
|
||||
if (arguments.length < 2) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.price.attrIsRequired')
|
||||
message: tpl(messages.attrIsRequired)
|
||||
});
|
||||
}
|
||||
|
||||
// CASE: if amount is passed, but it is undefined we throw an error
|
||||
if (amount === undefined) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.price.attrIsRequired')
|
||||
message: tpl(messages.attrIsRequired)
|
||||
});
|
||||
}
|
||||
|
||||
if (!isNumber(amount)) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.price.attrMustBeNumeric')
|
||||
message: tpl(messages.attrMustBeNumeric)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// We can later refactor to enforce this something like we did in apps
|
||||
const hbs = require('./theme-engine/engine');
|
||||
const errors = require('@tryghost/errors');
|
||||
const tpl = require('@tryghost/tpl');
|
||||
|
||||
const i18n = require('../../shared/i18n');
|
||||
const logging = require('@tryghost/logging');
|
||||
|
@ -29,7 +30,9 @@ module.exports = {
|
|||
|
||||
// These 3 are kind of core and required all the time
|
||||
errors,
|
||||
// @deprecated
|
||||
i18n,
|
||||
tpl,
|
||||
logging,
|
||||
|
||||
// Theme i18n is separate to common i18n
|
||||
|
|
Loading…
Add table
Reference in a new issue