File size: 4,365 Bytes
e1ae2c6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
const fs = require('node:fs');
const path = require('node:path');
const Handlebars = require('handlebars');

const { registerAllHelpers } = require('../../helpers');
const { createLogger, isVerbose } = require('../utils/logger');

const log = createLogger('template');

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.`
      );
    }

    if (isVerbose()) {
      log.info('页面模板不存在,已回退到通用模板 page.hbs', { template: `${templateName}.hbs` });
    } else {
      log.warn('页面模板不存在,已回退到通用模板 page.hbs', { template: `${templateName}.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,
};