package cms import ( "fmt" "io/fs" "os" "path/filepath" "strconv" "strings" ) func CreateWidget(root string, opts WidgetOptions) (string, error) { path, data, err := renderWidgetConfig(root, opts) if err != nil { return "", err } return path, writeNewFile(path, data) } func UpsertWidget(root string, opts WidgetOptions) (string, error) { path, data, err := renderWidgetConfig(root, opts) if err != nil { return "", err } return path, writeFile(path, data) } func renderWidgetConfig(root string, opts WidgetOptions) (string, []byte, error) { widgetType := slugify(opts.Type) if widgetType == "" || widgetType == "untitled" { return "", nil, fmt.Errorf("widget type is required") } name := slugify(opts.Name) if name == "" || name == "untitled" { name = widgetType } section := slugify(opts.Section) if section == "" || section == "untitled" { section = "articles" } limit := opts.Limit if limit < 1 { limit = 5 } path := filepath.Join(root, "site/widgets", name+".toml") data := "name = " + formatString(name) + "\n" + "type = " + formatString(widgetType) + "\n" + "section = " + formatString(section) + "\n" + "limit = " + strconv.Itoa(limit) + "\n" return path, []byte(data), nil } func LoadWidgets(root string) (map[string]Widget, error) { dir := filepath.Join(root, "site/widgets") widgets := map[string]Widget{} if _, err := os.Stat(dir); err != nil { if os.IsNotExist(err) { return widgets, nil } return nil, err } err := filepath.WalkDir(dir, func(path string, entry fs.DirEntry, err error) error { if err != nil { return err } if entry.IsDir() || filepath.Ext(path) != ".toml" { return nil } widget, err := loadWidget(path) if err != nil { return err } widgets[widget.Name] = widget return nil }) return widgets, err } func loadWidget(path string) (Widget, error) { data, err := os.ReadFile(path) if err != nil { return Widget{}, err } table, err := parseSimpleTable(string(data)) if err != nil { return Widget{}, fmt.Errorf("%s: %w", path, err) } limit, _ := strconv.Atoi(table.values["limit"]) if limit < 1 { limit = 5 } name := table.values["name"] if name == "" { name = strings.TrimSuffix(filepath.Base(path), filepath.Ext(path)) } section := table.values["section"] if section == "" { section = "articles" } return Widget{ Name: name, Type: table.values["type"], Section: section, Limit: limit, }, nil }