summaryrefslogtreecommitdiffstats
path: root/internal/cms/widget.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/cms/widget.go')
-rw-r--r--internal/cms/widget.go106
1 files changed, 106 insertions, 0 deletions
diff --git a/internal/cms/widget.go b/internal/cms/widget.go
new file mode 100644
index 0000000..0b24075
--- /dev/null
+++ b/internal/cms/widget.go
@@ -0,0 +1,106 @@
+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
+}