UNPKG

@restorecommerce/handlebars-helperized

Version:

Opinionated handlebars based templating engine for rendering e-mail like content

107 lines 3.9 kB
import juice from 'juice'; // the basic building block is the handlebars rendering engine import hbs from 'handlebars'; import { localizationHandlebarsExtension } from './helpers/l10n-helpers.js'; import { numberHandlebarsExtension } from './helpers/number-helpers.js'; import { datetimeHandlebarsExtensions } from './helpers/datetime-helpers.js'; import { momentHandlebarsExtension } from './helpers/moment-helpers.js'; // deprecated! import { listHandlebarsExtensions } from './helpers/list-helpers.js'; import { customHandlebarsExtensions } from './helpers/custom-helpers.js'; // @ts-expect-error no types import handlebarsLayouts from 'handlebars-layouts'; const defaultOpts = { locale: 'en-US', texts: {} }; // Initializes and configures a custom handlebars instance const init = async (options, customHelpersList) => { // default values if nothing given const opts = { ...defaultOpts, ...options, }; // more functionality directly added via custom plugins from ./lib localizationHandlebarsExtension(opts); // localization numberHandlebarsExtension(opts); // numbers & currencies momentHandlebarsExtension(opts); // dates, times & durations // deprecated! datetimeHandlebarsExtensions(opts); // dates, times & durations listHandlebarsExtensions(opts); // utillities for lists customHandlebarsExtensions(opts); // everything else // add custom helpers from rendering-srv for (const customHelper of (customHelpersList ?? [])) { const filePath = customHelper; // require(filePath)(hbs, opts); // check for double default try { const fileImport = await import(filePath); if (fileImport?.default?.default) { await fileImport.default.default(hbs, opts); } else { await fileImport.default(hbs, opts); } } catch (err) { const { code, message, stack } = err; console.log(`Error importing file ${filePath}`, { code, message, stack }); } } // extend rendering with layout functionality handlebarsLayouts.register(hbs); return hbs; }; class Renderer { style; /** @param {String} template the template @param {String} layout the optional layout @param {String} style the style @param {Object} opts handlebars options @param {Array} customHelpersList contains a list of custom helpers (optional) */ loadingHbs; template; constructor(template, layout, style, opts, customHelpersList) { this.style = style; this.loadingHbs = init(opts, customHelpersList).then((hbs) => { if (layout) { hbs.registerPartial('layout', layout); } if (template) { this.template = hbs.compile(template); } else { throw new Error('Template not provided!'); } }); } /** * Wait for the renderer to initialize */ async waitLoad() { return await this.loadingHbs; } /** @param {Object} context: required data for the placeholders @return {String} html */ async render(context) { await this.waitLoad(); let html = this.template(context); if (html && this.style) { html = juice.inlineContent(html, this.style, { inlinePseudoElements: true, preserveImportant: true, preserveMediaQueries: true, preserveFontFaces: true, applyWidthAttributes: true, applyHeightAttributes: true, insertPreservedExtraCss: true, extraCss: this.style // to enable inlining of media queries }); } return html; } } export { Renderer }; //# sourceMappingURL=index.js.map