feat: HTML sitemap groups API
- 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
This commit is contained in:
@@ -92,7 +92,7 @@ func (Settings) TableName() string { return "golem15_sitemap_settings" }
|
||||
|
||||
// Fillable lists the columns the settings form edits.
|
||||
func (Settings) Fillable() []string {
|
||||
return []string{"site_url", "file_size", "extra_urls", "images_enabled", "news_enabled", "news_publication", "news_sources", "indexnow_enabled"}
|
||||
return []string{"site_url", "file_size", "extra_urls", "images_enabled", "news_enabled", "news_publication", "news_sources", "indexnow_enabled", "html_enabled", "html_page_size"}
|
||||
}
|
||||
|
||||
// Rules is empty: the settings controller runs Validate before a save.
|
||||
@@ -105,6 +105,8 @@ const (
|
||||
errLastmod = "golem15.sitemap::lang.errors.lastmod"
|
||||
errNewsName = "golem15.sitemap::lang.errors.news_publication"
|
||||
errNewsSrc = "golem15.sitemap::lang.errors.news_source"
|
||||
errHTMLPath = "golem15.sitemap::lang.errors.html_path"
|
||||
errPageSize = "golem15.sitemap::lang.errors.page_size"
|
||||
)
|
||||
|
||||
// MaxNewsPublication is the longest publication name.
|
||||
@@ -128,7 +130,9 @@ func (s Settings) Validate() error {
|
||||
// Problems lists the settings' refusals by field (UI-SPEC C26): a site
|
||||
// address that AllowedFrontendURL refuses, a file size outside 1..MaxFileSize and an additional
|
||||
// address that is not a path or an http(s) URL (extra_urls.<i>.url) or
|
||||
// whose lastmod is not a date (extra_urls.<i>.lastmod).
|
||||
// whose lastmod is not a date (extra_urls.<i>.lastmod), a publication name
|
||||
// over 255 characters, a malformed News source, an HTML sitemap address
|
||||
// that ValidHTMLPath refuses (html_path) and a page size outside 50..500.
|
||||
func (s Settings) Problems() map[string][]string {
|
||||
out := map[string][]string{}
|
||||
if !AllowedFrontendURL(Text(s.SiteURL)) {
|
||||
@@ -154,9 +158,42 @@ func (s Settings) Problems() map[string][]string {
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, p := range s.HTMLPaths.Get() {
|
||||
if p = strings.TrimSpace(p); p != "" && !ValidHTMLPath(p) {
|
||||
out["html_path"] = []string{errHTMLPath}
|
||||
break
|
||||
}
|
||||
}
|
||||
if s.HTMLPageSize < MinHTMLPageSize || s.HTMLPageSize > MaxHTMLPageSize {
|
||||
out["html_page_size"] = []string{errPageSize}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// HTMLPathProblem is the refusal of an HTML sitemap address (errors.html_path).
|
||||
const HTMLPathProblem = errHTMLPath
|
||||
|
||||
// ValidHTMLPath reports whether p may be the HTML sitemap's address: a
|
||||
// path that starts with a single /, at most 255 characters of letters,
|
||||
// digits and - _ . ~ / (no query, fragment, "//" or ".." segment), and not
|
||||
// the site root.
|
||||
func ValidHTMLPath(p string) bool {
|
||||
if len(p) < 2 || len(p) > 255 || p[0] != '/' || strings.Contains(p, "//") {
|
||||
return false
|
||||
}
|
||||
for _, seg := range strings.Split(p[1:], "/") {
|
||||
if seg == "." || seg == ".." {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for _, r := range p {
|
||||
if !(r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r >= '0' && r <= '9' || strings.ContainsRune("-_.~/", r)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// The prefixes of the news_sources values (P33-15): type:<type key> and
|
||||
// category:<type key>:<id>.
|
||||
const (
|
||||
|
||||
Reference in New Issue
Block a user