diff --git a/index.js b/index.js index e9c7860..c6a23a8 100644 --- a/index.js +++ b/index.js @@ -6,4 +6,5 @@ const setup = require('./lib/setup'), module.exports.render = render; module.exports.addResolveMedia = setup.addResolveMedia; module.exports.addHelpers = setup.addHelpers; +module.exports.addPlugins = setup.addPlugins; module.exports.configureRender = setup.configureRender; diff --git a/lib/media.js b/lib/media.js index 7138adb..28e6a33 100644 --- a/lib/media.js +++ b/lib/media.js @@ -126,7 +126,13 @@ function getMediaMap({ _components: componentList, _layoutData, locals }) { {site} = locals || {}, assetDir = site && site.assetDir || MEDIA_DIRECTORY, assetPath = site && site.assetPath || '', - assetHost = site && site.assetHost || ''; + assetHost = site && site.assetHost || '', + siteStyleguide = site && site.styleguide, + defaultLinkedFontPath = path.join(assetDir, 'css', '_linked-fonts._default.css'), + siteLinkedFontPath = path.join(assetDir, 'css', `_linked-fonts.${siteStyleguide}.css`), + defaultInlinedFontPath = path.join(assetDir, 'css', '_inlined-fonts._default.css'), + siteInlinedFontPath = path.join(assetDir, 'css', `_inlined-fonts.${siteStyleguide}.css`); + let componentStyles = flatMap(componentList, (componentName) => module.exports.getStyles(componentName, locals.site)); if (layoutName) { @@ -135,6 +141,12 @@ function getMediaMap({ _components: componentList, _layoutData, locals }) { componentStyles = _.concat(componentStyles, layoutStyles); } + // add any default and site font css + componentStyles.push(defaultLinkedFontPath); + componentStyles.push(siteLinkedFontPath); + componentStyles.push(defaultInlinedFontPath); + componentStyles.push(siteInlinedFontPath); + return { styles: _.map(_.filter(componentStyles, util.fileExists), pathJoin(assetHost, assetPath, assetDir)) }; diff --git a/lib/render.js b/lib/render.js index ca1c5a9..e088012 100644 --- a/lib/render.js +++ b/lib/render.js @@ -2,7 +2,8 @@ const _ = require('lodash'), clayUtils = require('clayutils'), - mediaService = require('./media'); + mediaService = require('./media'), + setup = require('./setup'); let log = require('./log').setup({ file: __filename }), amphoraFs = require('amphora-fs'), @@ -79,6 +80,51 @@ function makeHtml(state) { }; } +/** + * Applies `render` hooks. + * Render hooks each return `data` or a Promise for `data`. + * + * @param {String} ref + * @param {Object} data + * @param {Object} locals + * @returns {Object} data + */ +function applyRenderHooks(ref, data, locals) { + // skip render hooks in edit mode + if (locals.edit) { + return bluebird.resolve(data); + } + + return bluebird + .filter(setup.plugins, (plugin) => plugin.render) + .reduce((val, plugin) => { + return plugin.render(ref, val, locals); + }, data); +} + +/** + * Applies `postRender` hooks. + * Post Render hooks each returns `html`. + * + * @param {String} ref + * @param {Object} locals + * @returns {Function} + */ +function applyPostRenderHooks(ref, locals) { + return (html) => { + // skip postRender hooks in edit mode + if (locals.edit) { + return html; + } + + return setup.plugins + .filter((plugin) => plugin.postRender) + .reduce((val, plugin) => { + return plugin.postRender(ref, html, locals); + }, html); + }; +} + function render(data, meta, res) { const hrStart = process.hrtime(), state = makeState(data, meta); @@ -86,6 +132,7 @@ function render(data, meta, res) { return Promise.resolve(data) .then(makeHtml(state)) .then(mediaService.injectStyles(state)) + .then(applyPostRenderHooks(state._layoutRef || state.self, state.locals)) .then(result => { res.type('text/html'); res.send(result); diff --git a/lib/setup.js b/lib/setup.js index 297b663..419aa95 100644 --- a/lib/setup.js +++ b/lib/setup.js @@ -120,6 +120,23 @@ function addHelpers(payload) { }); } +/** + * + * @param {Plugin[]} pluginsArr + */ +function addPlugins(pluginsArr) { + pluginsArr.forEach((plugin, index) => { + if (plugin.render || plugin.postRender) { + module.exports.plugins.push(plugin); + } else { + log( + "error", + `Error in amphora-html addPlugins: No \`render\` or \`postRender\` func found for plugin at index ${index}` + ); + } + }); +} + /** * Pass settings to the renderer * @@ -150,6 +167,7 @@ module.exports.plugins = []; // Setup functions module.exports.init = init; module.exports.addHelpers = addHelpers; +module.exports.addPlugins = addPlugins; module.exports.configureRender = configureRender; module.exports.addResolveMedia = addResolveMedia; diff --git a/package-lock.json b/package-lock.json index 5cea254..09f9d76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "amphora-amp", - "version": "2.0.1", + "version": "2.0.2-beta.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3aef42b..ac71362 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "amphora-amp", - "version": "2.0.1", + "version": "2.0.2-beta.1", "description": "An AMPHTML renderer for component data", "main": "index.js", "scripts": {