gpreview
Version:
Preview Ghost themes locally without a full Ghost installation
179 lines • 6.6 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HandlebarsRenderer = void 0;
const express_handlebars_1 = require("express-handlebars");
const handlebars_1 = __importDefault(require("handlebars"));
const helpers_1 = require("../helpers");
const path_1 = __importDefault(require("path"));
class HandlebarsRenderer {
hbs;
theme;
compiledTemplates = new Map();
async initialize(theme) {
if (!theme) {
return;
}
this.theme = theme;
this.hbs = (0, express_handlebars_1.create)({
extname: '.hbs',
defaultLayout: false,
partialsDir: path_1.default.join(theme.themePath, 'partials'),
helpers: {},
});
(0, helpers_1.registerHelpers)(handlebars_1.default);
await this.registerPartials();
await this.compileTemplates();
}
async registerPartials() {
if (!this.theme)
return;
for (const [name, partial] of this.theme.partials) {
if (partial.content) {
handlebars_1.default.registerPartial(name, partial.content);
}
}
}
async compileTemplates() {
if (!this.theme)
return;
for (const [name, template] of this.theme.templates) {
if (template.content) {
try {
const compiled = handlebars_1.default.compile(template.content, { strict: false });
this.compiledTemplates.set(name, compiled);
}
catch (error) {
console.error(`Failed to compile template ${name}:`, error);
}
}
}
}
async render(templateName, data, options = {}) {
if (!this.theme) {
throw new Error('Theme not initialized');
}
if (!this.compiledTemplates.has(templateName)) {
if (process.env.NODE_ENV !== 'test') {
console.warn(`Template ${templateName} not found, falling back to index`);
}
templateName = 'index';
}
const context = this.prepareContext(data, options);
const template = this.compiledTemplates.get(templateName);
if (!template) {
throw new Error(`Template ${templateName} not found`);
}
const templateContent = this.theme.templates.get(templateName)?.content || '';
const extendsDefault = templateContent.includes('{{!< default}}');
if (extendsDefault && this.compiledTemplates.has('default')) {
const defaultTemplate = this.compiledTemplates.get('default');
if (defaultTemplate) {
const body = template(context);
context.body = new handlebars_1.default.SafeString(body);
return defaultTemplate(context, {
data: {
site: data.site,
config: {
posts_per_page: 10,
},
custom: {
site_background_color: '#ffffff',
title_font: 'Modern sans',
body_font: 'Modern sans',
navigation_layout: 'Default',
show_images_in_feed: true,
show_author: true,
show_publish_date: true,
accent_color: '#15171A',
show_featured_posts: true,
featured_title: 'Featured',
},
post: context['@post'],
page: context['@page'],
tag: context['@tag'],
author: context['@author'],
}
});
}
}
return template(context, {
data: {
site: data.site,
config: {
posts_per_page: 10,
},
custom: {
site_background_color: '#ffffff',
title_font: 'Modern sans',
body_font: 'Modern sans',
navigation_layout: 'Default',
show_images_in_feed: true,
show_author: true,
show_publish_date: true,
accent_color: '#15171A',
show_featured_posts: true,
featured_title: 'Featured',
},
post: context['@post'],
page: context['@page'],
tag: context['@tag'],
author: context['@author'],
}
});
}
prepareContext(data, options) {
const context = {
...data,
'@site': data.site,
'@config': {
posts_per_page: 10,
},
'@custom': {
site_background_color: '#ffffff',
title_font: 'Modern sans',
body_font: 'Modern sans',
navigation_layout: 'Default',
show_images_in_feed: true,
show_author: true,
show_publish_date: true,
accent_color: '#15171A',
show_featured_posts: true,
featured_title: 'Featured',
},
body_class: options.bodyClass || '',
post_class: options.postClass || '',
context: options.context || [],
};
if (data.post) {
context['@post'] = data.post;
context.is_post = true;
}
if (data.page) {
context['@page'] = data.page;
context.is_page = true;
}
if (data.tag) {
context['@tag'] = data.tag;
context.is_tag = true;
}
if (data.author) {
context['@author'] = data.author;
context.is_author = true;
}
if (options.bodyClass?.includes('home-template')) {
context.is_home = true;
}
return context;
}
getAvailableTemplates() {
return Array.from(this.compiledTemplates.keys());
}
hasTemplate(name) {
return this.compiledTemplates.has(name);
}
}
exports.HandlebarsRenderer = HandlebarsRenderer;
//# sourceMappingURL=handlebarsRenderer.js.map