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 }