- GET /_sitemap/api/v1/html?locale= answers the overview: the listed
addresses of the XML sitemaps by group, in the order pages, offers,
services, categories (as a tree), posts (newest first), tags, authors,
other content types, each with its title in the locale, total, the
first html_page_size links and more
- GET /_sitemap/api/v1/html/{group}?locale=&page= answers one page of a
group; past the last page, an unknown group or the HTML sitemap off
answer 404; every answer is noindex; per-IP bucket sitemap-html
- the HTML sitemap tab: html_enabled, the address per locale (html_paths)
and html_page_size 50 to 500, with errors.html_path and errors.page_size
- contract.Listing.Settings answers HTMLEnabled, HTMLPaths, HTMLPageSize
and KeyFile
99 lines
3.0 KiB
Go
99 lines
3.0 KiB
Go
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 <loc> 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 <loc>: 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
|
|
}
|