sitemap.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package sitemap
  2. import (
  3. "context"
  4. "path"
  5. "strings"
  6. )
  7. const (
  8. FreqNever = "never"
  9. FreqYearly = "yearly"
  10. FreqMonthly = "monthly"
  11. FreqWeekly = "weekly"
  12. FreqDaily = "daily"
  13. FreqHourly = "hourly"
  14. FreqAlways = "always"
  15. )
  16. type ContextFunc func(context.Context) []URL
  17. type ModelInferface interface {
  18. Sitemap(context.Context) []URL
  19. }
  20. type SiteMapIndexBuilder struct {
  21. pathName string
  22. siteMaps []*SiteMapBuilder
  23. }
  24. type SiteMapBuilder struct {
  25. pathName string
  26. urls []URL
  27. contextFuncs []ContextFunc
  28. models []ModelInferface
  29. }
  30. type URL struct {
  31. Loc string
  32. LastMod string
  33. Changefreq string
  34. Priority float32
  35. }
  36. func SiteMapIndex(names ...string) (s *SiteMapIndexBuilder) {
  37. var namePath string
  38. if len(names) == 0 {
  39. namePath = "/sitemap.xml"
  40. } else {
  41. if names[0] == "" {
  42. namePath = "/sitemap.xml"
  43. }
  44. if !strings.HasPrefix(names[0], "/") {
  45. namePath = "/" + names[0]
  46. }
  47. if !strings.HasSuffix(names[0], ".xml") {
  48. namePath = names[0] + ".xml"
  49. }
  50. }
  51. return &SiteMapIndexBuilder{
  52. pathName: namePath,
  53. }
  54. }
  55. func (index *SiteMapIndexBuilder) RegisterSiteMap(sites ...*SiteMapBuilder) (s *SiteMapIndexBuilder) {
  56. index.siteMaps = append(index.siteMaps, sites...)
  57. return index
  58. }
  59. func (index *SiteMapIndexBuilder) ToUrl(ctx context.Context) string {
  60. if h, ok := ctx.Value(hostWithSchemeKey).(string); ok {
  61. return path.Join(h, index.pathName)
  62. }
  63. return index.pathName
  64. }
  65. func SiteMap(names ...string) (s *SiteMapBuilder) {
  66. var namePath string
  67. if len(names) == 0 {
  68. namePath = "/sitemap.xml"
  69. } else {
  70. namePath = names[0]
  71. if namePath == "" {
  72. namePath = "/sitemap.xml"
  73. }
  74. if !strings.HasPrefix(namePath, "/") {
  75. namePath = "/" + namePath
  76. }
  77. if !strings.HasSuffix(namePath, ".xml") {
  78. namePath = namePath + ".xml"
  79. }
  80. }
  81. return &SiteMapBuilder{
  82. pathName: namePath,
  83. }
  84. }
  85. func (site *SiteMapBuilder) RegisterRawString(rs ...string) (s *SiteMapBuilder) {
  86. for _, s := range rs {
  87. site.urls = append(site.urls, URL{Loc: s})
  88. }
  89. return site
  90. }
  91. func (site *SiteMapBuilder) RegisterURL(urls ...URL) (s *SiteMapBuilder) {
  92. site.urls = append(site.urls, urls...)
  93. return site
  94. }
  95. func (site *SiteMapBuilder) RegisterContextFunc(funcs ...ContextFunc) (s *SiteMapBuilder) {
  96. site.contextFuncs = append(site.contextFuncs, funcs...)
  97. return site
  98. }
  99. func (site *SiteMapBuilder) RegisterModel(models ...ModelInferface) (s *SiteMapBuilder) {
  100. site.models = append(site.models, models...)
  101. return site
  102. }
  103. func (site *SiteMapBuilder) ToUrl(ctx context.Context) string {
  104. if h, ok := ctx.Value(hostWithSchemeKey).(string); ok {
  105. return path.Join(h, site.pathName)
  106. }
  107. return site.pathName
  108. }
  109. func WithHost(host string, ctxs ...context.Context) context.Context {
  110. if len(ctxs) == 0 {
  111. return context.WithValue(context.TODO(), hostWithSchemeKey, host)
  112. }
  113. return context.WithValue(ctxs[0], hostWithSchemeKey, host)
  114. }