formats/yaml/yaml.go (view raw)
1package yaml
2
3import (
4 "fmt"
5 "os"
6 "path/filepath"
7 gotmpl "text/template"
8 "time"
9
10 "git.icyphox.sh/vite/config"
11 "git.icyphox.sh/vite/template"
12 "git.icyphox.sh/vite/types"
13 "gopkg.in/yaml.v3"
14)
15
16type YAML struct {
17 Path string
18
19 meta map[string]string
20}
21
22func (*YAML) Ext() string { return ".yaml" }
23func (*YAML) Body() string { return "" }
24func (y *YAML) Basename() string { return filepath.Base(y.Path) }
25
26func (y *YAML) Frontmatter() map[string]string {
27 return y.meta
28}
29
30type templateData struct {
31 Cfg config.ConfigYaml
32 Meta map[string]string
33 Yaml map[string]interface{}
34 Body string
35}
36
37func (y *YAML) template(dest, tmplDir string, data interface{}) error {
38 metaTemplate := y.meta["template"]
39 if metaTemplate == "" {
40 metaTemplate = config.Config.DefaultTemplate
41 }
42
43 tmpl := template.NewTmpl()
44 tmpl.SetFuncs(gotmpl.FuncMap{
45 "parsedate": func(s string) time.Time {
46 date, _ := time.Parse("2006-01-02", s)
47 return date
48 },
49 })
50 if err := tmpl.Load(tmplDir); err != nil {
51 return err
52 }
53
54 return tmpl.Write(dest, metaTemplate, data)
55}
56
57func (y *YAML) Render(dest string, data interface{}) error {
58 yamlBytes, err := os.ReadFile(y.Path)
59 if err != nil {
60 return fmt.Errorf("yaml: failed to read file: %s: %w", y.Path, err)
61 }
62
63 yamlData := map[string]interface{}{}
64 err = yaml.Unmarshal(yamlBytes, yamlData)
65 if err != nil {
66 return fmt.Errorf("yaml: failed to unmarshal yaml file: %s: %w", y.Path, err)
67 }
68
69 metaInterface := yamlData["meta"].(map[string]interface{})
70
71 meta := make(map[string]string)
72 for k, v := range metaInterface {
73 vStr := convertToString(v)
74 meta[k] = vStr
75 }
76
77 y.meta = meta
78
79 err = y.template(dest, types.TemplatesDir, templateData{
80 config.Config,
81 y.meta,
82 yamlData,
83 "",
84 })
85 if err != nil {
86 return fmt.Errorf("yaml: failed to render to destination %s: %w", dest, err)
87 }
88
89 return nil
90}
91
92func convertToString(value interface{}) string {
93 // Infer type and convert to string
94 switch v := value.(type) {
95 case string:
96 return v
97 case time.Time:
98 return v.Format("2006-01-02")
99 default:
100 return fmt.Sprintf("%v", v)
101 }
102}