qoder优化。

This commit is contained in:
2026-02-12 15:45:11 +08:00
parent bc59f616fd
commit d448e48ba3
6 changed files with 131 additions and 314 deletions

View File

@@ -139,48 +139,40 @@ func fileExists(path string) (bool, error) {
func (m *ThemeManager) parseTemplates(themePath string) (map[string]*template.Template, error) {
templates := make(map[string]*template.Template)
// 加载公共基础模板(可选)
baseTpl := template.New("base").Funcs(template.FuncMap{
"safeHTML": func(s string) template.HTML { return template.HTML(s) },
})
// 从主题目录加载模板
tplDir := filepath.Join(themePath, "templates")
// 首先读取所有模板文件内容
type tplFile struct {
name string
path string
content []byte
}
var tplFiles []tplFile
err := filepath.WalkDir(tplDir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err // 返回错误以停止 WalkDir
return err
}
if d.IsDir() {
return nil // 跳过目录
return nil
}
// 支持 .html 和 .tmpl 扩展名
lowerPath := strings.ToLower(path)
if !strings.HasSuffix(lowerPath, ".html") && !strings.HasSuffix(lowerPath, ".tmpl") {
return nil // 非模板文件,跳过
return nil
}
// 读取模板内容
content, err := readFile(path)
if err != nil {
return fmt.Errorf("failed to read template file %s: %w", path, err)
}
// 生成模板名称(相对路径,不含扩展名)
name := strings.TrimPrefix(path, tplDir+string(filepath.Separator))
name = strings.TrimSuffix(name, filepath.Ext(name))
// 克隆基础模板并解析
tpl, err := baseTpl.Clone()
if err != nil {
return fmt.Errorf("failed to clone base template for %s: %w", name, err)
}
tpl, err = tpl.Parse(string(content))
if err != nil {
return fmt.Errorf("parse error in %s (file: %s): %w", name, path, err)
}
templates[name] = tpl
tplFiles = append(tplFiles, tplFile{name: name, path: path, content: content})
return nil
})
@@ -188,10 +180,53 @@ func (m *ThemeManager) parseTemplates(themePath string) (map[string]*template.Te
return nil, err
}
if len(templates) == 0 {
if len(tplFiles) == 0 {
return nil, ErrNoValidTemplates
}
// 创建包含所有模板的根模板
funcMap := template.FuncMap{
"safeHTML": func(s string) template.HTML { return template.HTML(s) },
}
// 首先解析基础模板base.tmpl 和 header.tmpl
var baseContent strings.Builder
for _, tf := range tplFiles {
if tf.name == "base" || tf.name == "header" {
baseContent.WriteString(string(tf.content))
baseContent.WriteString("\n")
}
}
rootTpl, err := template.New("root").Funcs(funcMap).Parse(baseContent.String())
if err != nil {
return nil, fmt.Errorf("failed to parse base templates: %w", err)
}
// 为每个页面模板单独解析,继承基础模板
for _, tf := range tplFiles {
// 跳过基础模板,它们已经在 rootTpl 中
if tf.name == "base" || tf.name == "header" {
templates[tf.name] = rootTpl
continue
}
// 克隆基础模板并添加页面特定内容
tpl, err := rootTpl.Clone()
if err != nil {
return nil, fmt.Errorf("failed to clone base template for %s: %w", tf.name, err)
}
// 解析页面特定内容,使用页面名称作为 define 名称
pageContent := string(tf.content)
_, err = tpl.Parse(pageContent)
if err != nil {
return nil, fmt.Errorf("failed to parse template %s: %w", tf.name, err)
}
templates[tf.name] = tpl
}
return templates, nil
}