refactor: 模块化重构 generator 和 runtime

This commit is contained in:
rbetree
2026-01-15 21:08:26 +08:00
parent bcfa6e6316
commit 1a90f8fbe3
38 changed files with 4881 additions and 4411 deletions

View File

@@ -0,0 +1,120 @@
const fs = require('node:fs');
const path = require('node:path');
const Handlebars = require('handlebars');
const { registerAllHelpers } = require('../../helpers');
const handlebars = Handlebars.create();
registerAllHelpers(handlebars);
function loadHandlebarsTemplates() {
const templatesDir = path.join(process.cwd(), 'templates');
if (!fs.existsSync(templatesDir)) {
throw new Error('Templates directory not found. Cannot proceed without templates.');
}
const layoutsDir = path.join(templatesDir, 'layouts');
if (!fs.existsSync(layoutsDir)) {
throw new Error('Layouts directory not found. Cannot proceed without layout templates.');
}
fs.readdirSync(layoutsDir)
.filter((file) => file.endsWith('.hbs'))
.sort()
.forEach((file) => {
const layoutName = path.basename(file, '.hbs');
const layoutPath = path.join(layoutsDir, file);
const layoutContent = fs.readFileSync(layoutPath, 'utf8');
handlebars.registerPartial(layoutName, layoutContent);
});
const componentsDir = path.join(templatesDir, 'components');
if (!fs.existsSync(componentsDir)) {
throw new Error('Components directory not found. Cannot proceed without component templates.');
}
fs.readdirSync(componentsDir)
.filter((file) => file.endsWith('.hbs'))
.sort()
.forEach((file) => {
const componentName = path.basename(file, '.hbs');
const componentPath = path.join(componentsDir, file);
const componentContent = fs.readFileSync(componentPath, 'utf8');
handlebars.registerPartial(componentName, componentContent);
});
const defaultLayoutPath = path.join(layoutsDir, 'default.hbs');
if (!fs.existsSync(defaultLayoutPath)) {
throw new Error('Default layout template not found. Cannot proceed without default layout.');
}
}
function getDefaultLayoutTemplate() {
const defaultLayoutPath = path.join(process.cwd(), 'templates', 'layouts', 'default.hbs');
if (!fs.existsSync(defaultLayoutPath)) {
throw new Error('Default layout template not found. Cannot proceed without default layout.');
}
try {
const layoutContent = fs.readFileSync(defaultLayoutPath, 'utf8');
const layoutTemplate = handlebars.compile(layoutContent);
return {
path: defaultLayoutPath,
template: layoutTemplate,
};
} catch (error) {
throw new Error(`Error loading default layout template: ${error.message}`);
}
}
function renderTemplate(templateName, data, useLayout = true) {
const templatePath = path.join(process.cwd(), 'templates', 'pages', `${templateName}.hbs`);
if (!fs.existsSync(templatePath)) {
const genericTemplatePath = path.join(process.cwd(), 'templates', 'pages', 'page.hbs');
if (!fs.existsSync(genericTemplatePath)) {
throw new Error(
`Template ${templateName}.hbs not found and generic template page.hbs not found. Cannot proceed without template.`
);
}
console.log(`模板 ${templateName}.hbs 不存在,使用通用模板 page.hbs 代替`);
const genericTemplateContent = fs.readFileSync(genericTemplatePath, 'utf8');
const genericTemplate = handlebars.compile(genericTemplateContent);
const enhancedData = {
...data,
pageId: data && data.pageId ? data.pageId : templateName,
};
const pageContent = genericTemplate(enhancedData);
if (!useLayout) return pageContent;
const { template: layoutTemplate } = getDefaultLayoutTemplate();
return layoutTemplate({ ...enhancedData, body: pageContent });
}
try {
const templateContent = fs.readFileSync(templatePath, 'utf8');
const template = handlebars.compile(templateContent);
const pageContent = template(data);
if (!useLayout) return pageContent;
const { template: layoutTemplate } = getDefaultLayoutTemplate();
return layoutTemplate({ ...data, body: pageContent });
} catch (error) {
throw new Error(`Error rendering template ${templateName}: ${error.message}`);
}
}
module.exports = {
handlebars,
loadHandlebarsTemplates,
getDefaultLayoutTemplate,
renderTemplate,
};