package builder import ( "embed" "html/template" "log" "path/filepath" "github.com/ficcdaf/zona/internal/util" "gopkg.in/yaml.v3" ) const ( DefConfigName = "config.yml" DefHeaderName = "header.md" DefFooterName = "footer.md" DefStylesheetName = "style.css" DefIconName = "icon.png" DefTemplateName = "default.html" ) //go:embed embed var embedDir embed.FS type Settings struct { Header template.HTML HeaderName string Footer template.HTML FooterName string Stylesheet []byte StylesheetName string Icon []byte IconName string DefaultTemplate template.HTML DefaultTemplateName string } func buildSettings(f []byte) (*Settings, error) { s := &Settings{} var c map[string]interface{} // Parse YAML if err := yaml.Unmarshal(f, &c); err != nil { return nil, err } if headerName, ok := c["header"].(string); ok { header, err := util.ReadFile(headerName) s.HeaderName = headerName if err != nil { return nil, util.ErrorPrepend("Could not read header specified in config: ", err) } s.Header = template.HTML(MdToHTML(header)) } else { header := readEmbed(DefHeaderName) s.Header = template.HTML(MdToHTML(header)) s.HeaderName = DefHeaderName } if footerName, ok := c["footer"].(string); ok { footer, err := util.ReadFile(footerName) s.FooterName = footerName if err != nil { return nil, util.ErrorPrepend("Could not read footer specified in config: ", err) } s.Footer = template.HTML(MdToHTML(footer)) } else { footer := readEmbed(DefFooterName) s.Footer = template.HTML(MdToHTML(footer)) s.FooterName = DefFooterName } if stylesheetName, ok := c["stylesheet"].(string); ok { stylesheet, err := util.ReadFile(stylesheetName) if err != nil { return nil, util.ErrorPrepend("Could not read stylesheet specified in config: ", err) } s.StylesheetName = stylesheetName s.Stylesheet = stylesheet } else { stylesheet := readEmbed(DefStylesheetName) s.Stylesheet = stylesheet s.StylesheetName = DefStylesheetName } if iconName, ok := c["icon"].(string); ok { icon, err := util.ReadFile(iconName) if err != nil { return nil, util.ErrorPrepend("Could not read icon specified in config: ", err) } s.Icon = icon s.IconName = iconName } else { icon := readEmbed(DefIconName) s.Icon = icon s.IconName = DefIconName } if return s, nil } // readEmbed reads a file inside the embedded dir func readEmbed(name string) []byte { f, err := embedDir.ReadFile(name) if err != nil { log.Fatalln("Fatal internal error: Could not read embedded default config!") } return f } func GetSettings(root string) *Settings { // TODO: Read a config file to override defaults // "Defaults" should be a default config file via embed package, // so the settings func should need to handle one case: // check if config file exists, if not, use embedded one var config []byte configPath := filepath.Join(root, DefConfigName) if !util.FileExists(configPath) { // Config file does not exist, we used embedded default config = readEmbed(configPath) } else { config, err := util.ReadFile(configPath) if err != nil { log.Fatalln("Fatal internal error: Config file exists but could not be read!") } } // return NewSettings(DefaultHeader, DefaultFooter, DefaultStylesheet, DefaultIcon, DefaultTemplate) }