add pocketbase
This commit is contained in:
194
backend/custom/seo/feeds.go
Normal file
194
backend/custom/seo/feeds.go
Normal file
@ -0,0 +1,194 @@
|
||||
package seo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/pocketbase/pocketbase"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/router"
|
||||
)
|
||||
|
||||
type MenuRecord struct {
|
||||
Active bool `json:"active"`
|
||||
CollectionID string `json:"collectionId"`
|
||||
CollectionName string `json:"collectionName"`
|
||||
Created string `json:"created"`
|
||||
ID string `json:"id"`
|
||||
IDLang string `json:"id_lang"`
|
||||
IDPage string `json:"id_page"`
|
||||
IDParent string `json:"id_parent"`
|
||||
IsDefault bool `json:"is_default"`
|
||||
IsRoot bool `json:"is_root"`
|
||||
LinkRewrite string `json:"link_rewrite"`
|
||||
LinkTitle string `json:"link_title"`
|
||||
MetaDescription string `json:"meta_description"`
|
||||
MetaTitle string `json:"meta_title"`
|
||||
Name string `json:"name"`
|
||||
PageName string `json:"page_name"`
|
||||
PositionID int `json:"position_id"`
|
||||
Updated string `json:"updated"`
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
type UrlSet struct {
|
||||
XMLName xml.Name `xml:"urlset"`
|
||||
Xmlns string `xml:"xmlns,attr"`
|
||||
Urls []Url `xml:"url"`
|
||||
}
|
||||
|
||||
type Url struct {
|
||||
Loc string `xml:"loc"`
|
||||
LastMod string `xml:"lastmod,omitempty"`
|
||||
ChangeFreq string `xml:"changefreq,omitempty"`
|
||||
Priority string `xml:"priority,omitempty"`
|
||||
}
|
||||
|
||||
func ServeFeeds(app *pocketbase.PocketBase, se *core.ServeEvent) *router.Route[*core.RequestEvent] {
|
||||
return se.Router.GET("/feeds/{lang}/sitemap.xml", func(e *core.RequestEvent) error {
|
||||
|
||||
lang := e.Request.PathValue("lang")
|
||||
|
||||
urls, err := getLocations(app, lang)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
xx := UrlSet{
|
||||
Xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9",
|
||||
Urls: urls,
|
||||
}
|
||||
|
||||
bytes, err := xml.MarshalIndent(xx, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.Response.Header().Add("content-type", "text/xml")
|
||||
return e.String(http.StatusOK, xml.Header+string(bytes))
|
||||
})
|
||||
}
|
||||
|
||||
func getLocations(app *pocketbase.PocketBase, lang string) ([]Url, error) {
|
||||
records, err := app.FindRecordsByFilter("menu_view", fmt.Sprintf("id_lang='%s'&&active=true", lang), "position_id", 200, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
baseUrl, err := getBaseUrl(app)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
locations := []Url{}
|
||||
lastMod := time.Now().Add(time.Hour * 24 * 7 * -1).Format("2006-01-02")
|
||||
|
||||
for _, r := range records {
|
||||
rec := MenuRecord{}
|
||||
x, _ := r.MarshalJSON()
|
||||
json.Unmarshal(x, &rec)
|
||||
if rec.IsRoot {
|
||||
continue
|
||||
}
|
||||
if len(rec.Url) > 0 {
|
||||
continue
|
||||
}
|
||||
if rec.IsDefault {
|
||||
|
||||
locations = append(locations, Url{
|
||||
Loc: baseUrl + path.Join(lang),
|
||||
LastMod: lastMod,
|
||||
ChangeFreq: "weekly",
|
||||
Priority: "1.0",
|
||||
})
|
||||
}
|
||||
locations = append(locations, Url{
|
||||
Loc: baseUrl + path.Join(lang, rec.IDPage, rec.LinkRewrite),
|
||||
LastMod: lastMod,
|
||||
ChangeFreq: "weekly",
|
||||
Priority: "1.0",
|
||||
})
|
||||
}
|
||||
|
||||
return locations, nil
|
||||
}
|
||||
|
||||
type BaseUrl struct {
|
||||
BaseURL string `json:"baseUrl"`
|
||||
}
|
||||
|
||||
func getBaseUrl(app *pocketbase.PocketBase) (string, error) {
|
||||
record, err := app.FindFirstRecordByFilter("settings", "key='baseUrl'", nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
settings := BaseUrl{}
|
||||
json.Unmarshal([]byte(record.GetString("value")), &settings)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return settings.BaseURL, nil
|
||||
}
|
||||
|
||||
type SitemapIndex struct {
|
||||
XMLName xml.Name `xml:"sitemapindex"`
|
||||
Xmlns string `xml:"xmlns,attr"`
|
||||
Sitemaps []Sitemap `xml:"sitemap"`
|
||||
}
|
||||
|
||||
// Sitemap represents each <sitemap> entry
|
||||
type Sitemap struct {
|
||||
Loc string `xml:"loc"`
|
||||
LastMod string `xml:"lastmod"`
|
||||
}
|
||||
|
||||
func ServeFeedsIndex(app *pocketbase.PocketBase, se *core.ServeEvent) *router.Route[*core.RequestEvent] {
|
||||
return se.Router.GET("/feeds/index.xml", func(e *core.RequestEvent) error {
|
||||
index, err := makeSiteMapIndex(app)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bytes, err := xml.MarshalIndent(index, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.Response.Header().Add("content-type", "text/xml")
|
||||
return e.String(http.StatusOK, xml.Header+string(bytes))
|
||||
})
|
||||
}
|
||||
|
||||
func makeSiteMapIndex(app *pocketbase.PocketBase) (*SitemapIndex, error) {
|
||||
index := &SitemapIndex{
|
||||
Xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9",
|
||||
}
|
||||
|
||||
bseUrl, err := getBaseUrl(app)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
langs, err := app.FindRecordsByFilter("lang", "active=true", "", 200, 0)
|
||||
if err != nil {
|
||||
return index, err
|
||||
}
|
||||
|
||||
lastMod := time.Now().Add(time.Hour * 24 * 7 * -1).Format("2006-01-02")
|
||||
|
||||
for _, l := range langs {
|
||||
index.Sitemaps = append(index.Sitemaps, Sitemap{
|
||||
Loc: bseUrl + path.Join("feeds/", l.Id, "sitemap.xml"),
|
||||
LastMod: lastMod,
|
||||
})
|
||||
}
|
||||
|
||||
return index, nil
|
||||
}
|
50
backend/custom/seo/robots.go
Normal file
50
backend/custom/seo/robots.go
Normal file
@ -0,0 +1,50 @@
|
||||
package seo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/pocketbase/pocketbase"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/router"
|
||||
)
|
||||
|
||||
type Robots struct {
|
||||
Robots []string
|
||||
}
|
||||
|
||||
func ServeRobotsTxt(app *pocketbase.PocketBase, se *core.ServeEvent) *router.Route[*core.RequestEvent] {
|
||||
return se.Router.GET("/robots.txt", func(e *core.RequestEvent) error {
|
||||
|
||||
text, err := getRobots(app)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return e.String(http.StatusOK, text)
|
||||
})
|
||||
}
|
||||
|
||||
func getRobots(app *pocketbase.PocketBase) (string, error) {
|
||||
record, err := app.FindFirstRecordByFilter("settings", "key='robots_txt'", nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
settings := Robots{}
|
||||
json.Unmarshal([]byte(record.GetString("value")), &settings)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
baseUrl, err := getBaseUrl(app)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
settings.Robots = append(settings.Robots, fmt.Sprintf("\n\nSitemap: %s%s", baseUrl, "feeds/index.xml"))
|
||||
|
||||
return strings.Join(settings.Robots, "\n"), nil
|
||||
}
|
Reference in New Issue
Block a user