Files
gositemap/sitemap.go

108 lines
2.4 KiB
Go

package gositemap
import (
"encoding/xml"
"fmt"
"math"
"path"
)
type ChangeFrequency string
const (
Always ChangeFrequency = "always"
Hourly ChangeFrequency = "hourly"
Daily ChangeFrequency = "daily"
Weekly ChangeFrequency = "weekly"
Monthly ChangeFrequency = "monthly"
Yearly ChangeFrequency = "yearly"
Never ChangeFrequency = "never"
)
func (f ChangeFrequency) String() string {
return string(f)
}
type urlSetXML struct {
XMLName xml.Name `xml:"http://www.sitemaps.org/schemas/sitemap/0.9 urlset"`
URLs []*urlXML `xml:"url"`
}
type urlXML struct {
Loc string `xml:"loc"`
LastMod *string `xml:"lastmod,omitempty"`
ChangeFreq *ChangeFrequency `xml:"changefreq,omitempty"`
Priority *float64 `xml:"priority,omitempty"`
}
type siteMapIndexXML struct {
XMLName xml.Name `xml:"http://www.sitemaps.org/schemas/sitemap/0.9 sitemapindex"`
SiteMaps []*sitemapXML `xml:"sitemap"`
}
type sitemapXML struct {
Loc string `xml:"loc"`
LastMod *string `xml:"lastmod,omitempty"`
}
type SiteMap struct {
urls []*urlXML
BaseURL string
MaxURLPerSiteMap int
}
func (m *SiteMap) AddURL(url string, lastMod *string, freq *ChangeFrequency, prio *float64) {
m.urls = append(m.urls, &urlXML{
Loc: fmt.Sprintf("https://%s", path.Join(m.BaseURL, url)),
LastMod: lastMod,
ChangeFreq: freq,
Priority: prio,
})
}
func prefixXML(content []byte) []byte {
return append([]byte(xml.Header), content...)
}
func (m *SiteMap) SiteMapIndex() ([]byte, error) {
nSiteMaps := int(math.Floor(float64(len(m.urls))/float64(m.MaxURLPerSiteMap) + 1))
index := &siteMapIndexXML{}
for i := 0; i < nSiteMaps; i++ {
index.SiteMaps = append(index.SiteMaps, &sitemapXML{
Loc: fmt.Sprintf("https://%s/sitemap/%d", m.BaseURL, i),
})
}
res, err := xml.Marshal(index)
if err != nil {
return nil, err
}
return prefixXML(res), nil
}
func (m *SiteMap) SiteMap(id int) ([]byte, error) {
if m.MaxURLPerSiteMap*(id) >= len(m.urls) {
return nil, nil
}
siteMap := &urlSetXML{}
var urls []*urlXML
if m.MaxURLPerSiteMap*(id+1) >= len(m.urls) {
urls = m.urls[m.MaxURLPerSiteMap*id:]
} else {
urls = m.urls[m.MaxURLPerSiteMap*id : m.MaxURLPerSiteMap*(id+1)]
}
siteMap.URLs = append(siteMap.URLs, urls...)
res, err := xml.Marshal(siteMap)
if err != nil {
return nil, err
}
return prefixXML(res), nil
}