ghost 4.41.3 → 4.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/content/themes/casper/package.json +2 -3
- package/content/themes/casper/partials/post-card.hbs +1 -1
- package/core/built/assets/ghost-dark-1933079797e24ccb8839657020830be5.css +1 -0
- package/core/built/assets/{ghost.min-1abf114ca26a71e8e1f09054f3592614.js → ghost.min-2a278873d60d6a13a4c05a396e5bed5e.js} +533 -398
- package/core/built/assets/ghost.min-38f3c38c0c6a1864f57079b068a0b0ce.css +1 -0
- package/core/built/assets/{vendor.min-9094db77ba3190cb10876f8e42e1d90d.js → vendor.min-21f79c68a284acb1b70039f3f63e5507.js} +68 -68
- package/core/built/assets/{vendor.min-2c8ad32b7960bb605ebc20097fee5ebd.css → vendor.min-ba66b98f7c24fa40e061c7ffc94f4e23.css} +214 -0
- package/core/frontend/apps/amp/lib/helpers/amp_analytics.js +1 -1
- package/core/frontend/apps/amp/lib/helpers/amp_components.js +1 -1
- package/core/frontend/apps/amp/lib/helpers/amp_content.js +1 -1
- package/core/frontend/apps/amp/lib/helpers/amp_style.js +1 -1
- package/core/frontend/apps/amp/lib/router.js +6 -5
- package/core/frontend/apps/private-blogging/lib/helpers/input_password.js +1 -1
- package/core/frontend/apps/private-blogging/lib/router.js +2 -2
- package/core/frontend/helpers/asset.js +1 -1
- package/core/frontend/helpers/author.js +1 -1
- package/core/frontend/helpers/authors.js +1 -1
- package/core/frontend/helpers/body_class.js +1 -1
- package/core/frontend/helpers/cancel_link.js +1 -1
- package/core/frontend/helpers/concat.js +1 -1
- package/core/frontend/helpers/content.js +1 -1
- package/core/frontend/helpers/date.js +1 -1
- package/core/frontend/helpers/encode.js +1 -1
- package/core/frontend/helpers/excerpt.js +1 -1
- package/core/frontend/helpers/facebook_url.js +1 -1
- package/core/frontend/helpers/foreach.js +2 -2
- package/core/frontend/helpers/get.js +1 -1
- package/core/frontend/helpers/ghost_foot.js +1 -1
- package/core/frontend/helpers/ghost_head.js +1 -1
- package/core/frontend/helpers/lang.js +1 -1
- package/core/frontend/helpers/link.js +1 -1
- package/core/frontend/helpers/link_class.js +1 -1
- package/core/frontend/helpers/match.js +1 -1
- package/core/frontend/helpers/navigation.js +1 -1
- package/core/frontend/helpers/pagination.js +1 -1
- package/core/frontend/helpers/plural.js +1 -1
- package/core/frontend/helpers/post_class.js +1 -1
- package/core/frontend/helpers/prev_post.js +6 -5
- package/core/frontend/helpers/price.js +1 -0
- package/core/frontend/helpers/products.js +1 -1
- package/core/frontend/helpers/reading_time.js +2 -2
- package/core/frontend/helpers/t.js +1 -1
- package/core/frontend/helpers/tags.js +1 -1
- package/core/frontend/helpers/tiers.js +1 -1
- package/core/frontend/helpers/title.js +1 -1
- package/core/frontend/helpers/twitter_url.js +1 -1
- package/core/frontend/helpers/url.js +1 -1
- package/core/frontend/meta/url.js +4 -4
- package/core/{server/data/schema → frontend/services/data}/checks.js +4 -4
- package/core/frontend/services/{routing/helpers → data}/entry-lookup.js +3 -3
- package/core/frontend/services/{routing/helpers → data}/fetch-data.js +3 -3
- package/core/frontend/services/data/index.js +5 -0
- package/core/frontend/services/{rendering.js → handlebars.js} +2 -1
- package/core/frontend/services/helpers/handlebars.js +1 -1
- package/core/frontend/services/proxy.js +2 -4
- package/core/frontend/services/{routing/helpers → rendering}/context.js +0 -0
- package/core/frontend/services/{routing/helpers → rendering}/error.js +0 -0
- package/core/frontend/services/{routing/helpers → rendering}/format-response.js +1 -1
- package/core/frontend/services/{routing/helpers → rendering}/index.js +0 -8
- package/core/frontend/services/{routing/helpers → rendering}/render-entries.js +1 -1
- package/core/frontend/services/{routing/helpers → rendering}/render-entry.js +1 -1
- package/core/frontend/services/{routing/helpers → rendering}/renderer.js +1 -1
- package/core/frontend/services/{routing/helpers → rendering}/secure.js +0 -0
- package/core/frontend/services/{routing/helpers → rendering}/templates.js +2 -2
- package/core/frontend/services/routing/CollectionRouter.js +1 -1
- package/core/frontend/services/routing/controllers/channel.js +9 -9
- package/core/frontend/services/routing/controllers/collection.js +9 -9
- package/core/frontend/services/routing/controllers/email-post.js +5 -6
- package/core/frontend/services/routing/controllers/entry.js +6 -6
- package/core/frontend/services/routing/controllers/preview.js +5 -6
- package/core/frontend/services/routing/controllers/rss.js +4 -3
- package/core/frontend/services/routing/controllers/static.js +5 -5
- package/core/frontend/services/routing/controllers/unsubscribe.js +2 -2
- package/core/frontend/services/routing/index.js +0 -4
- package/core/frontend/web/middleware/error-handler.js +2 -2
- package/core/server/api/canary/email-preview.js +2 -1
- package/core/server/api/canary/{email.js → emails.js} +0 -0
- package/core/server/api/canary/index.js +9 -1
- package/core/server/api/canary/members.js +0 -45
- package/core/server/api/canary/newsletters.js +45 -0
- package/core/server/api/canary/stats.js +23 -0
- package/core/server/api/canary/utils/serializers/output/email-previews.js +7 -0
- package/core/server/api/canary/utils/serializers/output/index.js +2 -22
- package/core/server/api/canary/utils/serializers/output/mappers/index.js +1 -0
- package/core/server/api/canary/utils/serializers/output/mappers/snippets.js +36 -0
- package/core/server/api/canary/utils/serializers/output/members.js +5 -2
- package/core/server/api/canary/utils/serializers/output/oembed.js +2 -2
- package/core/server/api/canary/utils/serializers/output/redirects.js +2 -2
- package/core/server/api/canary/utils/serializers/output/schedules.js +2 -2
- package/core/server/api/canary/utils/serializers/output/slack.js +2 -2
- package/core/server/api/canary/utils/serializers/output/themes.js +2 -2
- package/core/server/api/canary/utils/serializers/output/users.js +0 -23
- package/core/server/api/canary/utils/validators/input/index.js +6 -0
- package/core/server/api/shared/http.js +52 -51
- package/core/server/api/shared/serializers/handle.js +25 -26
- package/core/server/data/exporter/table-lists.js +2 -0
- package/core/server/data/migrations/utils.js +34 -2
- package/core/server/data/migrations/versions/4.42/2022-03-21-17-17-add.js +25 -0
- package/core/server/data/migrations/versions/4.42/2022-03-30-15-44-add-newsletter-permissions.js +28 -0
- package/core/server/data/migrations/versions/4.43/2022-03-28-19-26-recreate-newsletter-table.js +29 -0
- package/core/server/data/migrations/versions/4.43/2022-03-29-14-45-add-members-newsletters-table.js +7 -0
- package/core/server/data/migrations/versions/4.43/2022-04-01-10-13-add-post-newsletter-relation.js +108 -0
- package/core/server/data/migrations/versions/4.43/2022-04-06-09-47-add-type-column-to-paid-subscription-events.js +7 -0
- package/core/server/data/migrations/versions/4.43/2022-04-06-14-56-add-email-newsletter-relation.js +8 -0
- package/core/server/data/migrations/versions/4.43/2022-04-08-10-45-add-subscription-id-to-mrr-events.js +7 -0
- package/core/server/data/schema/commands.js +19 -14
- package/core/server/data/schema/index.js +0 -1
- package/core/server/data/schema/schema.js +36 -0
- package/core/server/models/base/bookshelf.js +1 -1
- package/core/server/models/base/plugins/crud.js +8 -0
- package/core/server/models/member.js +18 -1
- package/core/server/models/newsletter.js +43 -0
- package/core/server/models/post.js +4 -1
- package/core/server/services/auth/setup.js +4 -1
- package/core/server/services/mega/template.js +25 -13
- package/core/server/services/members/api.js +3 -1
- package/core/server/services/members/middleware.js +13 -3
- package/core/server/services/members/service.js +2 -1
- package/core/server/services/members/utils.js +13 -1
- package/core/server/services/newsletters/index.js +10 -0
- package/core/server/services/newsletters/service.js +24 -0
- package/core/server/services/slack.js +11 -3
- package/core/server/services/stats/index.js +1 -0
- package/core/server/services/stats/lib/members-stats-service.js +161 -0
- package/core/server/services/stats/lib/mrr-stats-service.js +154 -0
- package/core/server/services/stats/service.js +8 -0
- package/core/server/services/stripe/service.js +1 -0
- package/core/server/services/webhooks/webhooks-service.js +3 -1
- package/core/server/web/admin/views/default-prod.html +5 -5
- package/core/server/web/admin/views/default.html +5 -5
- package/core/server/web/api/canary/admin/routes.js +9 -2
- package/core/shared/config/defaults.json +2 -2
- package/core/shared/config/env/config.development.json +26 -0
- package/core/shared/config/env/config.production.json +21 -0
- package/core/shared/config/env/config.testing-mysql.json +59 -0
- package/core/shared/config/env/config.testing.json +58 -0
- package/package.json +50 -50
- package/yarn.lock +700 -769
- package/content/themes/casper/assets/css/csscomb.json +0 -240
- package/core/built/assets/ghost-dark-146c4c688b47d45c4aa018ee0f79cebc.css +0 -1
- package/core/built/assets/ghost.min-a73b150c7eecc4641d377cc73fb5eecd.css +0 -1
- package/core/server/api/canary/utils/serializers/output/email-preview.js +0 -10
- package/core/server/api/canary/utils/serializers/output/emails.js +0 -22
- package/core/server/api/canary/utils/serializers/output/identities.js +0 -7
- package/core/server/api/canary/utils/serializers/output/member-signin-urls.js +0 -7
- package/core/server/api/canary/utils/serializers/output/snippets.js +0 -107
- package/core/server/api/canary/utils/serializers/output/webhooks.js +0 -15
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
// Overrides the standard behaviour of `{[title}}` to ensure the content is correctly escaped
|
|
5
5
|
|
|
6
|
-
const {SafeString, escapeExpression} = require('../services/
|
|
6
|
+
const {SafeString, escapeExpression} = require('../services/handlebars');
|
|
7
7
|
|
|
8
8
|
module.exports = function title() {
|
|
9
9
|
return new SafeString(escapeExpression(this.title || ''));
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
// Output a url for a twitter username
|
|
5
5
|
const {socialUrls} = require('../services/proxy');
|
|
6
|
-
const {localUtils} = require('../services/
|
|
6
|
+
const {localUtils} = require('../services/handlebars');
|
|
7
7
|
|
|
8
8
|
// We use the name twitter_url to match the helper for consistency:
|
|
9
9
|
module.exports = function twitter_url(username, options) { // eslint-disable-line camelcase
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// `absolute` flag outputs absolute URL, else URL is relative
|
|
6
6
|
|
|
7
7
|
const {metaData} = require('../services/proxy');
|
|
8
|
-
const {SafeString} = require('../services/
|
|
8
|
+
const {SafeString} = require('../services/handlebars');
|
|
9
9
|
const logging = require('@tryghost/logging');
|
|
10
10
|
const sentry = require('../../shared/sentry');
|
|
11
11
|
const errors = require('@tryghost/errors');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const schema = require('../../server/data/schema').checks;
|
|
2
1
|
const urlUtils = require('../../shared/url-utils');
|
|
3
2
|
const urlService = require('../../server/services/url');
|
|
3
|
+
const {checks} = require('../services/data');
|
|
4
4
|
|
|
5
5
|
// This cleans the url from any `/amp` postfixes, so we'll never
|
|
6
6
|
// output a url with `/amp` in the end, except for the needed `amphtml`
|
|
@@ -13,7 +13,7 @@ function sanitizeAmpUrl(url) {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
function getUrl(data, absolute) {
|
|
16
|
-
if (
|
|
16
|
+
if (checks.isPost(data)) {
|
|
17
17
|
/**
|
|
18
18
|
* @NOTE
|
|
19
19
|
*
|
|
@@ -33,11 +33,11 @@ function getUrl(data, absolute) {
|
|
|
33
33
|
return urlService.getUrlByResourceId(data.id, {secure: data.secure, absolute: absolute, withSubdirectory: true});
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
if (
|
|
36
|
+
if (checks.isTag(data) || checks.isUser(data)) {
|
|
37
37
|
return urlService.getUrlByResourceId(data.id, {secure: data.secure, absolute: absolute, withSubdirectory: true});
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
if (
|
|
40
|
+
if (checks.isNav(data)) {
|
|
41
41
|
return urlUtils.urlFor('nav', {nav: data, secure: data.secure}, absolute);
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const _ = require('lodash');
|
|
2
2
|
const Promise = require('bluebird');
|
|
3
3
|
const url = require('url');
|
|
4
|
-
const debug = require('@tryghost/debug')('services:
|
|
4
|
+
const debug = require('@tryghost/debug')('services:data:entry-lookup');
|
|
5
5
|
const routeMatch = require('path-match')();
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Query API for a single entry/resource.
|
|
9
9
|
* @param {String} postUrl
|
|
10
10
|
* @param {Object} routerOptions
|
|
11
11
|
* @param {Object} locals
|
|
@@ -14,7 +14,7 @@ const routeMatch = require('path-match')();
|
|
|
14
14
|
function entryLookup(postUrl, routerOptions, locals) {
|
|
15
15
|
debug(postUrl);
|
|
16
16
|
|
|
17
|
-
const api = require('
|
|
17
|
+
const api = require('../proxy').api[locals.apiVersion];
|
|
18
18
|
const targetPath = url.parse(postUrl).path;
|
|
19
19
|
const permalinks = routerOptions.permalinks;
|
|
20
20
|
let isEditURL = false;
|
|
@@ -34,7 +34,7 @@ const defaultPostQuery = _.cloneDeep(queryDefaults);
|
|
|
34
34
|
defaultPostQuery.options = defaultQueryOptions.options;
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
37
|
+
* Process query request.
|
|
38
38
|
*
|
|
39
39
|
* Takes a 'query' object, ensures that type, resource and options are set
|
|
40
40
|
* Replaces occurrences of `%s` in options with slugParam
|
|
@@ -45,7 +45,7 @@ defaultPostQuery.options = defaultQueryOptions.options;
|
|
|
45
45
|
* @returns {Promise}
|
|
46
46
|
*/
|
|
47
47
|
function processQuery(query, slugParam, locals) {
|
|
48
|
-
const api = require('
|
|
48
|
+
const api = require('../proxy').api[locals.apiVersion];
|
|
49
49
|
|
|
50
50
|
query = _.cloneDeep(query);
|
|
51
51
|
|
|
@@ -62,7 +62,7 @@ function processQuery(query, slugParam, locals) {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
/**
|
|
65
|
-
*
|
|
65
|
+
* Fetch data from API helper for controllers.
|
|
66
66
|
*
|
|
67
67
|
* Calls out to get posts per page, builds the final posts query & builds any additional queries
|
|
68
68
|
* Wraps the queries using Promise.props to ensure it gets named responses
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* This is a loose concept of a frontend
|
|
2
|
+
* This is a loose concept of a frontend handlebars toolkit
|
|
3
3
|
* Note: everything here gets deep-required from the theme-engine
|
|
4
4
|
* This indicates that the theme engine is a set of services, rather than a single service
|
|
5
5
|
* and could do with a further refactor.
|
|
@@ -17,6 +17,7 @@ module.exports = {
|
|
|
17
17
|
templates: require('./theme-engine/handlebars/template'),
|
|
18
18
|
|
|
19
19
|
// Theme i18n
|
|
20
|
+
// @TODO: this should live somewhere else...
|
|
20
21
|
themeI18n: require('./theme-engine/i18n'),
|
|
21
22
|
|
|
22
23
|
// TODO: these need a more sensible home
|
|
@@ -2,7 +2,7 @@ const Promise = require('bluebird');
|
|
|
2
2
|
const errors = require('@tryghost/errors');
|
|
3
3
|
const logging = require('@tryghost/logging');
|
|
4
4
|
|
|
5
|
-
const {hbs} = require('../
|
|
5
|
+
const {hbs} = require('../handlebars');
|
|
6
6
|
|
|
7
7
|
// Register an async handlebars helper for a given handlebars instance
|
|
8
8
|
function asyncHelperWrapper(hbsInstance, name, fn) {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
const settingsCache = require('../../shared/settings-cache');
|
|
3
3
|
const config = require('../../shared/config');
|
|
4
4
|
|
|
5
|
-
// Require from the
|
|
6
|
-
const {SafeString} = require('./
|
|
5
|
+
// Require from the handlebars framework
|
|
6
|
+
const {SafeString} = require('./handlebars');
|
|
7
7
|
|
|
8
8
|
module.exports = {
|
|
9
9
|
/**
|
|
@@ -22,8 +22,6 @@ module.exports = {
|
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
},
|
|
25
|
-
// This is used to decide e.g. if a JSON object is a Post, Page, Tag etc
|
|
26
|
-
checks: require('../../server/data/schema').checks,
|
|
27
25
|
|
|
28
26
|
/**
|
|
29
27
|
* Section three: Core API
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -6,8 +6,8 @@ const _ = require('lodash');
|
|
|
6
6
|
|
|
7
7
|
const path = require('path');
|
|
8
8
|
const url = require('url');
|
|
9
|
-
const config = require('
|
|
10
|
-
const themeEngine = require('
|
|
9
|
+
const config = require('../../../shared/config');
|
|
10
|
+
const themeEngine = require('../theme-engine');
|
|
11
11
|
const _private = {};
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -30,7 +30,7 @@ class CollectionRouter extends ParentRouter {
|
|
|
30
30
|
value: object.permalink
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
// @NOTE: see
|
|
33
|
+
// @NOTE: see renderer/templates - we use unshift to prepend the templates
|
|
34
34
|
this.templates = (object.templates || []).reverse();
|
|
35
35
|
|
|
36
36
|
this.filter = object.filter;
|
|
@@ -4,7 +4,8 @@ const tpl = require('@tryghost/tpl');
|
|
|
4
4
|
const errors = require('@tryghost/errors');
|
|
5
5
|
const security = require('@tryghost/security');
|
|
6
6
|
const themeEngine = require('../../theme-engine');
|
|
7
|
-
const
|
|
7
|
+
const dataService = require('../../data');
|
|
8
|
+
const renderer = require('../../rendering');
|
|
8
9
|
|
|
9
10
|
const messages = {
|
|
10
11
|
pageNotFound: 'Page not found.'
|
|
@@ -50,7 +51,7 @@ module.exports = function channelController(req, res, next) {
|
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
return
|
|
54
|
+
return dataService.fetchData(pathOptions, res.routerOptions, res.locals)
|
|
54
55
|
.then(function handleResult(result) {
|
|
55
56
|
// CASE: requested page is greater than number of pages we have
|
|
56
57
|
if (pathOptions.page > result.meta.pagination.pages) {
|
|
@@ -60,16 +61,15 @@ module.exports = function channelController(req, res, next) {
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
// Format data 1
|
|
63
|
-
// @TODO: See
|
|
64
|
-
|
|
64
|
+
// @TODO: See renderer/secure for explanation.
|
|
65
|
+
renderer.secure(req, result.posts);
|
|
65
66
|
|
|
66
|
-
// @TODO: See
|
|
67
|
+
// @TODO: See renderer/secure for explanation.
|
|
67
68
|
_.each(result.data, function (data) {
|
|
68
|
-
|
|
69
|
+
renderer.secure(req, data);
|
|
69
70
|
});
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
return renderer(result);
|
|
72
|
+
return renderer.renderEntries(req, res)(result);
|
|
73
73
|
})
|
|
74
|
-
.catch(
|
|
74
|
+
.catch(renderer.handleError(next));
|
|
75
75
|
};
|
|
@@ -5,7 +5,8 @@ const errors = require('@tryghost/errors');
|
|
|
5
5
|
const security = require('@tryghost/security');
|
|
6
6
|
const {routerManager} = require('../');
|
|
7
7
|
const themeEngine = require('../../theme-engine');
|
|
8
|
-
const
|
|
8
|
+
const renderer = require('../../rendering');
|
|
9
|
+
const dataService = require('../../data');
|
|
9
10
|
|
|
10
11
|
const messages = {
|
|
11
12
|
pageNotFound: 'Page not found.'
|
|
@@ -49,7 +50,7 @@ module.exports = function collectionController(req, res, next) {
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
debug('fetching data');
|
|
52
|
-
return
|
|
53
|
+
return dataService.fetchData(pathOptions, res.routerOptions, res.locals)
|
|
53
54
|
.then(function handleResult(result) {
|
|
54
55
|
// CASE: requested page is greater than number of pages we have
|
|
55
56
|
if (pathOptions.page > result.meta.pagination.pages) {
|
|
@@ -80,16 +81,15 @@ module.exports = function collectionController(req, res, next) {
|
|
|
80
81
|
});
|
|
81
82
|
|
|
82
83
|
// Format data 1
|
|
83
|
-
// @TODO: See
|
|
84
|
-
|
|
84
|
+
// @TODO: See renderer/secure for explanation.
|
|
85
|
+
renderer.secure(req, result.posts);
|
|
85
86
|
|
|
86
|
-
// @TODO: See
|
|
87
|
+
// @TODO: See renderer/secure for explanation.
|
|
87
88
|
_.each(result.data, function (data) {
|
|
88
|
-
|
|
89
|
+
renderer.secure(req, data);
|
|
89
90
|
});
|
|
90
91
|
|
|
91
|
-
|
|
92
|
-
return renderer(result);
|
|
92
|
+
return renderer.renderEntries(req, res)(result);
|
|
93
93
|
})
|
|
94
|
-
.catch(
|
|
94
|
+
.catch(renderer.handleError(next));
|
|
95
95
|
};
|
|
@@ -2,7 +2,7 @@ const debug = require('@tryghost/debug')('services:routing:controllers:emailpost
|
|
|
2
2
|
const config = require('../../../../shared/config');
|
|
3
3
|
const {routerManager} = require('../');
|
|
4
4
|
const urlUtils = require('../../../../shared/url-utils');
|
|
5
|
-
const
|
|
5
|
+
const renderer = require('../../rendering');
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @description Email Post Controller.
|
|
@@ -55,11 +55,10 @@ module.exports = function emailPostController(req, res, next) {
|
|
|
55
55
|
post.access = !!post.html;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
// @TODO: See
|
|
59
|
-
|
|
58
|
+
// @TODO: See renderer/secure
|
|
59
|
+
renderer.secure(req, post);
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
return renderer(post);
|
|
61
|
+
return renderer.renderEntry(req, res)(post);
|
|
63
62
|
})
|
|
64
|
-
.catch(
|
|
63
|
+
.catch(renderer.handleError(next));
|
|
65
64
|
};
|
|
@@ -3,7 +3,8 @@ const url = require('url');
|
|
|
3
3
|
const config = require('../../../../shared/config');
|
|
4
4
|
const {routerManager} = require('../');
|
|
5
5
|
const urlUtils = require('../../../../shared/url-utils');
|
|
6
|
-
const
|
|
6
|
+
const dataService = require('../../data');
|
|
7
|
+
const renderer = require('../../rendering');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* @description Entry controller.
|
|
@@ -15,7 +16,7 @@ const helpers = require('../helpers');
|
|
|
15
16
|
module.exports = function entryController(req, res, next) {
|
|
16
17
|
debug('entryController', res.routerOptions);
|
|
17
18
|
|
|
18
|
-
return
|
|
19
|
+
return dataService.entryLookup(req.path, res.routerOptions, res.locals)
|
|
19
20
|
.then(function then(lookup) {
|
|
20
21
|
// Format data 1
|
|
21
22
|
const entry = lookup ? lookup.entry : false;
|
|
@@ -83,10 +84,9 @@ module.exports = function entryController(req, res, next) {
|
|
|
83
84
|
}));
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
|
|
87
|
+
renderer.secure(req, entry);
|
|
87
88
|
|
|
88
|
-
|
|
89
|
-
return renderer(entry);
|
|
89
|
+
return renderer.renderEntry(req, res)(entry);
|
|
90
90
|
})
|
|
91
|
-
.catch(
|
|
91
|
+
.catch(renderer.handleError(next));
|
|
92
92
|
};
|
|
@@ -2,7 +2,7 @@ const debug = require('@tryghost/debug')('services:routing:controllers:preview')
|
|
|
2
2
|
const config = require('../../../../shared/config');
|
|
3
3
|
const {routerManager} = require('../');
|
|
4
4
|
const urlUtils = require('../../../../shared/url-utils');
|
|
5
|
-
const
|
|
5
|
+
const renderer = require('../../rendering');
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @description Preview Controller.
|
|
@@ -57,11 +57,10 @@ module.exports = function previewController(req, res, next) {
|
|
|
57
57
|
post.access = !!post.html;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
// @TODO: See
|
|
61
|
-
|
|
60
|
+
// @TODO: See renderer/secure
|
|
61
|
+
renderer.secure(req, post);
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
return renderer(post);
|
|
63
|
+
return renderer.renderEntry(req, res)(post);
|
|
65
64
|
})
|
|
66
|
-
.catch(
|
|
65
|
+
.catch(renderer.handleError(next));
|
|
67
66
|
};
|
|
@@ -4,7 +4,8 @@ const url = require('url');
|
|
|
4
4
|
const security = require('@tryghost/security');
|
|
5
5
|
const settingsCache = require('../../../../shared/settings-cache');
|
|
6
6
|
const rssService = require('../../rss');
|
|
7
|
-
const
|
|
7
|
+
const renderer = require('../../rendering');
|
|
8
|
+
const dataService = require('../../data');
|
|
8
9
|
|
|
9
10
|
// @TODO: is this really correct? Should we be using meta data title?
|
|
10
11
|
function getTitle(relatedData) {
|
|
@@ -35,7 +36,7 @@ module.exports = function rssController(req, res, next) {
|
|
|
35
36
|
// @TODO: This belongs to the rss service O_o
|
|
36
37
|
const baseUrl = url.parse(req.originalUrl).pathname;
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
dataService.fetchData(pathOptions, res.routerOptions, res.locals)
|
|
39
40
|
.then(function formatResult(result) {
|
|
40
41
|
const response = _.pick(result, ['posts', 'meta']);
|
|
41
42
|
|
|
@@ -47,5 +48,5 @@ module.exports = function rssController(req, res, next) {
|
|
|
47
48
|
.then(function (data) {
|
|
48
49
|
return rssService.render(res, baseUrl, data);
|
|
49
50
|
})
|
|
50
|
-
.catch(
|
|
51
|
+
.catch(renderer.handleError(next));
|
|
51
52
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const _ = require('lodash');
|
|
2
2
|
const Promise = require('bluebird');
|
|
3
3
|
const debug = require('@tryghost/debug')('services:routing:controllers:static');
|
|
4
|
-
const
|
|
4
|
+
const renderer = require('../../rendering');
|
|
5
5
|
|
|
6
6
|
function processQuery(query, locals) {
|
|
7
7
|
const api = require('../../proxy').api[locals.apiVersion];
|
|
@@ -60,12 +60,12 @@ module.exports = function staticController(req, res, next) {
|
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
// @TODO: See
|
|
63
|
+
// @TODO: See renderer/secure for more context.
|
|
64
64
|
_.each(response.data, function (data) {
|
|
65
|
-
|
|
65
|
+
renderer.secure(req, data);
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
renderer.renderer(req, res, renderer.formatResponse.entries(response));
|
|
69
69
|
})
|
|
70
|
-
.catch(
|
|
70
|
+
.catch(renderer.handleError(next));
|
|
71
71
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const debug = require('@tryghost/debug')('services:routing:controllers:unsubscribe');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const megaService = require('../../../../server/services/mega');
|
|
4
|
-
const
|
|
4
|
+
const renderer = require('../../rendering');
|
|
5
5
|
|
|
6
6
|
module.exports = async function unsubscribeController(req, res) {
|
|
7
7
|
debug('unsubscribeController');
|
|
@@ -22,5 +22,5 @@ module.exports = async function unsubscribeController(req, res) {
|
|
|
22
22
|
defaultTemplate: path.resolve(__dirname, '../../../views/', templateName)
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
return
|
|
25
|
+
return renderer.renderer(req, res, data);
|
|
26
26
|
};
|
|
@@ -4,7 +4,7 @@ const tpl = require('@tryghost/tpl');
|
|
|
4
4
|
const sentry = require('../../../shared/sentry');
|
|
5
5
|
|
|
6
6
|
const config = require('../../../shared/config');
|
|
7
|
-
const
|
|
7
|
+
const renderer = require('../../services/rendering');
|
|
8
8
|
|
|
9
9
|
// @TODO: make this properly shared code
|
|
10
10
|
const {prepareError, prepareStack} = require('@tryghost/mw-error-handler');
|
|
@@ -55,7 +55,7 @@ const themeErrorRenderer = (err, req, res, next) => {
|
|
|
55
55
|
|
|
56
56
|
// Template
|
|
57
57
|
// @TODO: very dirty !!!!!!
|
|
58
|
-
|
|
58
|
+
renderer.templates.setTemplate(req, res);
|
|
59
59
|
|
|
60
60
|
// It can be that something went wrong with the theme or otherwise loading handlebars
|
|
61
61
|
// This ensures that no matter what res.render will work here
|
|
File without changes
|
|
@@ -158,7 +158,7 @@ module.exports = {
|
|
|
158
158
|
},
|
|
159
159
|
|
|
160
160
|
get emails() {
|
|
161
|
-
return shared.pipeline(require('./
|
|
161
|
+
return shared.pipeline(require('./emails'), localUtils);
|
|
162
162
|
},
|
|
163
163
|
|
|
164
164
|
get site() {
|
|
@@ -169,6 +169,10 @@ module.exports = {
|
|
|
169
169
|
return shared.pipeline(require('./snippets'), localUtils);
|
|
170
170
|
},
|
|
171
171
|
|
|
172
|
+
get stats() {
|
|
173
|
+
return shared.pipeline(require('./stats'), localUtils);
|
|
174
|
+
},
|
|
175
|
+
|
|
172
176
|
get customThemeSettings() {
|
|
173
177
|
return shared.pipeline(require('./custom-theme-settings'), localUtils);
|
|
174
178
|
},
|
|
@@ -177,6 +181,10 @@ module.exports = {
|
|
|
177
181
|
return require('./utils/serializers');
|
|
178
182
|
},
|
|
179
183
|
|
|
184
|
+
get newsletters() {
|
|
185
|
+
return shared.pipeline(require('./newsletters'), localUtils);
|
|
186
|
+
},
|
|
187
|
+
|
|
180
188
|
/**
|
|
181
189
|
* Content API Controllers
|
|
182
190
|
*
|
|
@@ -452,51 +452,6 @@ module.exports = {
|
|
|
452
452
|
};
|
|
453
453
|
}
|
|
454
454
|
},
|
|
455
|
-
subscriberStats: {
|
|
456
|
-
permissions: {
|
|
457
|
-
method: 'browse'
|
|
458
|
-
},
|
|
459
|
-
async query() {
|
|
460
|
-
const statsData = await membersService.api.events.getSubscriptions();
|
|
461
|
-
const totalSubscriptions = (_.last(statsData) && _.last(statsData).subscribed) || 0;
|
|
462
|
-
statsData.forEach((d) => {
|
|
463
|
-
d.date = moment(d.date).format('YYYY-MM-DD');
|
|
464
|
-
});
|
|
465
|
-
return {
|
|
466
|
-
resource: 'subscribers',
|
|
467
|
-
total: totalSubscriptions,
|
|
468
|
-
data: statsData.map((d) => {
|
|
469
|
-
return Object.assign({}, {
|
|
470
|
-
date: moment(d.date).format('YYYY-MM-DD'),
|
|
471
|
-
value: d.subscribed
|
|
472
|
-
});
|
|
473
|
-
})
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
},
|
|
477
|
-
grossVolumeStats: {
|
|
478
|
-
permissions: {
|
|
479
|
-
method: 'browse'
|
|
480
|
-
},
|
|
481
|
-
async query() {
|
|
482
|
-
const volumeData = await membersService.api.events.getVolume();
|
|
483
|
-
const volumeStats = Object.keys(volumeData).map((curr) => {
|
|
484
|
-
return {
|
|
485
|
-
currency: curr,
|
|
486
|
-
data: volumeData[curr].map((d) => {
|
|
487
|
-
return Object.assign({}, {
|
|
488
|
-
date: moment(d.date).format('YYYY-MM-DD'),
|
|
489
|
-
value: d.volume
|
|
490
|
-
});
|
|
491
|
-
})
|
|
492
|
-
};
|
|
493
|
-
});
|
|
494
|
-
return {
|
|
495
|
-
resource: 'gross-volume',
|
|
496
|
-
data: volumeStats
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
},
|
|
500
455
|
|
|
501
456
|
activityFeed: {
|
|
502
457
|
options: [
|