Ghost/core/frontend/services/themes/preview.js
Hannah Wolfe 1c7c246616 🐛 Fixed theme preview not decoding values properly
- Theme preview was not showing the same behaviour as a real theme because nulls were being encoded and decoded incorrectly causing nulls/empty strings to be treasted as truthy values
- Swap from using split to using proper query param parsing so that the code is more robust
- this still creates empty strings and the string 'null' so added a small function to decode these back to real nulls
- moved to its own file ready to be split out - there needs to be a bigger picture plan for this
- added unit tests to cover the known issues + some potential breakages from converting the header string to a query param object
2021-03-01 11:54:50 +00:00

48 lines
1.4 KiB
JavaScript

// @TODO: put together a plan for how the frontend should exist as modules and move this out
// The preview header contains a query string with the custom preview data
// This is deliberately slightly obscure & means we don't need to add body parsing to the frontend :D
// If we start passing in strings like title or description we will probably need to change this
const PREVIEW_HEADER_NAME = 'x-ghost-preview';
const _ = require('lodash');
function decodeValue(value) {
if (value === '' || value === 'null' || value === 'undefined') {
return null;
}
return value;
}
function getPreviewData(previewHeader, siteData) {
// Keep the string shorter with short codes for certain parameters
const supportedSettings = {
c: 'accent_color',
icon: 'icon',
logo: 'logo',
cover: 'cover_image'
};
let opts = new URLSearchParams(previewHeader);
opts.forEach((value, key) => {
value = decodeValue(value);
if (supportedSettings[key]) {
_.set(siteData, supportedSettings[key], value);
}
});
siteData._preview = previewHeader;
return siteData;
}
module.exports._PREVIEW_HEADER_NAME = PREVIEW_HEADER_NAME;
module.exports.handle = (req, siteData) => {
if (req && req.header(PREVIEW_HEADER_NAME)) {
siteData = getPreviewData(req.header(PREVIEW_HEADER_NAME), siteData);
}
return siteData;
};