package classes import ( "encoding/json" "strings" "git.golem15.com/golem15/sm-sitemap-plugin/models" "git.golem15.com/golem15/summercms/modules/backpack" "gorm.io/gorm" ) // SiteURLConfigKey is the config key of the site address the sitemaps use // when the setting is empty. const SiteURLConfigKey = "golem15.sitemap.site_url" // LoadSettings reads the settings row; without one the defaults apply. func LoadSettings(db *gorm.DB) (models.Settings, error) { var rows []models.Settings if err := db.Where("id = ?", 1).Limit(1).Find(&rows).Error; err != nil { return models.Settings{}, err } if len(rows) == 0 { return models.DefaultSettings(), nil } return rows[0], nil } // SiteURL is the absolute site address every starts with, without a // trailing slash: the site_url setting, else the config key // golem15.sitemap.site_url, else app.url (CONTEXT 2026-10-28). A value that // is not an absolute http(s) URL (models.AllowedFrontendURL) is skipped. // The request's Host header is never used; "" means no site address is // configured. func SiteURL(app *backpack.App, s models.Settings) string { candidates := []string{models.Text(s.SiteURL)} if app != nil && app.Config != nil { candidates = append(candidates, app.Config.String(SiteURLConfigKey), app.Config.String("app.url")) } for _, c := range candidates { c = strings.TrimRight(strings.TrimSpace(c), "/") if c != "" && models.AllowedFrontendURL(c) { return c } } return "" } // Absolute turns a stored address into the absolute URL of a : a path // starting with a single / is put on site; an absolute http(s) URL is kept. // Anything else, or a path without a site address, is "". func Absolute(site, u string) string { switch { case strings.HasPrefix(u, "/") && !strings.HasPrefix(u, "//"): if site == "" { return "" } return site + u case models.AllowedFrontendURL(u): return u } return "" } // MergeHTMLPaths merges submitted HTML sitemap addresses (locale to path) // into the stored ones: a sent locale replaces its address, a blank one // removes it, the others keep theirs. problem is true when a sent address // is not a models.ValidHTMLPath; nothing is merged then. func MergeHTMLPaths(db *gorm.DB, sent map[string]string) (map[string]string, bool) { settings, err := LoadSettings(db) if err != nil { return nil, true } merged := settings.EffectiveHTMLPaths() for locale, path := range sent { locale, path = strings.TrimSpace(locale), strings.TrimSpace(path) if locale == "" { continue } if path == "" { delete(merged, locale) continue } if !models.ValidHTMLPath(path) { return nil, true } merged[locale] = path } return merged, false } // StoreHTMLPaths writes the HTML sitemap addresses to settings row 1. func StoreHTMLPaths(db *gorm.DB, paths map[string]string) error { raw, err := json.Marshal(paths) if err != nil { return err } return db.Exec(`UPDATE golem15_sitemap_settings SET html_paths = ?::jsonb WHERE id = 1`, string(raw)).Error }