Ghost/core/frontend/services/theme-engine/middleware/update-global-template-options.js
Fabien 'egg' O'Carroll 01f30eb632
Included benefits with theme product data (#14051)
refs https://github.com/TryGhost/Team/issues/1079

These were missing when benefits were added to products, and will allow
theme developers to make more useful custom subscribe pages.
2022-01-24 13:55:25 +02:00

120 lines
3.6 KiB
JavaScript

const hbs = require('../engine');
const urlUtils = require('../../../../shared/url-utils');
const {api} = require('../../proxy');
const settingsCache = require('../../../../shared/settings-cache');
const customThemeSettingsCache = require('../../../../shared/custom-theme-settings-cache');
const labs = require('../../../../shared/labs');
const activeTheme = require('../active');
function calculateLegacyPriceData(products) {
const defaultPrice = {
amount: 0,
currency: 'usd',
interval: 'year',
nickname: ''
};
function makePriceObject(price) {
const numberAmount = 0 + price.amount;
const dollarAmount = numberAmount ? Math.round(numberAmount / 100) : 0;
return {
valueOf() {
return dollarAmount;
},
amount: numberAmount,
currency: price.currency,
nickname: price.name,
interval: price.interval
};
}
const defaultProduct = products.find((product) => {
return product.type === 'paid';
}) || {};
const monthlyPrice = makePriceObject(defaultProduct.monthly_price || defaultPrice);
const yearlyPrice = makePriceObject(defaultProduct.yearly_price || defaultPrice);
const priceData = {
monthly: monthlyPrice,
yearly: yearlyPrice,
currency: monthlyPrice ? monthlyPrice.currency : defaultPrice.currency
};
return priceData;
}
async function getProductAndPricesData() {
try {
const page = await api.canary.productsPublic.browse({
include: ['monthly_price', 'yearly_price', 'benefits'],
limit: 'all',
filter: 'active:true'
});
return page.products;
} catch (err) {
return [];
}
}
function getSiteData() {
let siteData = settingsCache.getPublic();
// theme-only computed property added to @site
if (settingsCache.get('members_signup_access') === 'none') {
const escapedUrl = encodeURIComponent(urlUtils.urlFor({relativeUrl: '/rss/'}, true));
siteData.signup_url = `https://feedly.com/i/subscription/feed/${escapedUrl}`;
} else {
siteData.signup_url = '#/portal';
}
return siteData;
}
async function updateGlobalTemplateOptions(req, res, next) {
// Static information, same for every request unless the settings change
// @TODO: bind this once and then update based on events?
// @TODO: decouple theme layer from settings cache using the Content API
const siteData = getSiteData();
const labsData = labs.getAll();
const themeData = {
posts_per_page: activeTheme.get().config('posts_per_page'),
image_sizes: activeTheme.get().config('image_sizes')
};
const themeSettingsData = customThemeSettingsCache.getAll();
const productData = await getProductAndPricesData();
const priceData = calculateLegacyPriceData(productData);
let products = null;
let product = null;
if (productData.length === 1) {
product = productData[0];
} else {
products = productData;
}
// @TODO: only do this if something changed?
// @TODO: remove blog in a major where we are happy to break more themes
{
hbs.updateTemplateOptions({
data: {
blog: siteData,
site: siteData,
labs: labsData,
config: themeData,
price: priceData,
product,
products,
custom: themeSettingsData
}
});
}
next();
}
module.exports = updateGlobalTemplateOptions;