summaryrefslogtreecommitdiff
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
-rw-r--r--config/config.go1
-rw-r--r--config/config.local.yaml1
-rw-r--r--config/config.prod.yaml1
-rw-r--r--config/config.stage.yaml1
-rw-r--r--internal/b2/client.go17
-rw-r--r--internal/router/basic-handler.go18
-rw-r--r--internal/router/handlers/lang-blog-title.go49
-rw-r--r--internal/router/handlers/lang-blog.go17
-rw-r--r--internal/router/handlers/lang-map.go8
-rw-r--r--internal/router/handlers/lang-user.go11
-rw-r--r--internal/router/handlers/lang.go20
-rw-r--r--internal/router/handlers/robots.txt.go48
-rw-r--r--internal/router/handlers/root.go15
-rw-r--r--internal/router/handlers/sitemap.xml.go79
-rw-r--r--internal/router/router.go95
-rw-r--r--internal/templatemanager/templatemanager.go50
-rw-r--r--locale/localization.en.yaml1
-rw-r--r--locale/localization.go1
-rw-r--r--locale/localization.ru.yaml1
-rw-r--r--views/layouts/general-page.html31
-rw-r--r--views/pages/blog-page.html10
-rw-r--r--views/pages/global-map.html8
-rw-r--r--views/pages/robots.txt5
-rw-r--r--views/pages/sitemap.xml10
24 files changed, 76 insertions, 422 deletions
diff --git a/config/config.go b/config/config.go
index fd8c480..1393dd8 100644
--- a/config/config.go
+++ b/config/config.go
@@ -16,7 +16,6 @@ type Config struct {
AvailableLanguages []AvailableLanguageConfig `json:"AvailableLanguages" yaml:"availableLanguages" validate:"required"`
Auth AuthConfig `json:"Auth" yaml:"auth" validate:"required"`
Mail MailConfig `json:"Mail" yaml:"mail" validate:"required"`
- CanonicalEndpoint string `json:"CanonicalEndpoint" yaml:"canonicalEndpoint" validate:"required"`
}
type BlogPagesConfig struct {
diff --git a/config/config.local.yaml b/config/config.local.yaml
index c02dc2d..e23c808 100644
--- a/config/config.local.yaml
+++ b/config/config.local.yaml
@@ -45,4 +45,3 @@ mail:
salt: '${MAIL_SALT}'
trigger:
onNewPost: "* * * * *"
-canonicalEndpoint: 'http://127.0.0.1:3000'
diff --git a/config/config.prod.yaml b/config/config.prod.yaml
index 4de853c..0bee79d 100644
--- a/config/config.prod.yaml
+++ b/config/config.prod.yaml
@@ -44,4 +44,3 @@ mail:
salt: '${MAIL_SALT}'
trigger:
onNewPost: "0/5 * * * *"
-canonicalEndpoint: 'https://${FQDN}'
diff --git a/config/config.stage.yaml b/config/config.stage.yaml
index efa94ae..1c15dae 100644
--- a/config/config.stage.yaml
+++ b/config/config.stage.yaml
@@ -44,4 +44,3 @@ mail:
salt: '${MAIL_SALT}'
trigger:
onNewPost: "0/3 * * * *"
-canonicalEndpoint: 'https://${FQDN}'
diff --git a/internal/b2/client.go b/internal/b2/client.go
index fda79e0..d712736 100644
--- a/internal/b2/client.go
+++ b/internal/b2/client.go
@@ -33,11 +33,10 @@ func NewB2Client(cfg *config.B2Config) (*B2Client, error) {
}
type BlogPage struct {
- Link string
- FileName string
- Lang string
- ModifiedTime time.Time
- Metadata *frontmatter.Metadata
+ Link string
+ FileName string
+ Lang string
+ Metadata *frontmatter.Metadata
}
func (c *B2Client) Scan(prefix string) ([]*BlogPage, error) {
@@ -80,13 +79,9 @@ func (c *B2Client) Scan(prefix string) ([]*BlogPage, error) {
tags := strings.Split(attrs.Info["tags"], ",")
slices.Sort(tags)
- lang, _ := strings.CutPrefix(linkParts[0], c.prefix)
-
filePaths = append(filePaths, &BlogPage{
- Link: obj.Name(),
- FileName: fileName,
- Lang: lang,
- ModifiedTime: attrs.LastModified,
+ Link: obj.Name(),
+ FileName: fileName,
Metadata: &frontmatter.Metadata{
Title: attrs.Info["title"],
ShortDescription: attrs.Info["short-description"],
diff --git a/internal/router/basic-handler.go b/internal/router/basic-handler.go
index b973d01..4a94a48 100644
--- a/internal/router/basic-handler.go
+++ b/internal/router/basic-handler.go
@@ -34,14 +34,6 @@ func (r *BasicHandler) TemplatesToInject() []string {
return []string{}
}
-func (r *BasicHandler) SitemapInfo(supplements *Supplements) []SitemapInfo {
- return nil
-}
-
-func (r *BasicHandler) ContentType() string {
- return fiber.MIMETextHTMLCharsetUTF8
-}
-
func (r *BasicHandler) Render(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
if !r.IsTemplated() {
panic("handler did not implement Render method (while being non-templated)")
@@ -49,12 +41,10 @@ func (r *BasicHandler) Render(c *fiber.Ctx, supplements *Supplements, lang strin
return fiber.StatusNoContent, nil
}
-func (r *BasicHandler) AddMeta(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (meta []MetaField, err error) {
- return []MetaField{{Name: "robots", Content: "noindex,nofollow"}}, nil
-}
-
-func (r *BasicHandler) AddLinkedData(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (ld map[string]any, err error) {
- return nil, nil
+func (r *BasicHandler) AddMeta(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (meta map[string]string, err error) {
+ return map[string]string{
+ "robots": "noindex,nofollow",
+ }, nil
}
func (r *BasicHandler) RenderHeader(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
diff --git a/internal/router/handlers/lang-blog-title.go b/internal/router/handlers/lang-blog-title.go
index 5bfc6e7..97de089 100644
--- a/internal/router/handlers/lang-blog-title.go
+++ b/internal/router/handlers/lang-blog-title.go
@@ -46,54 +46,17 @@ func (r *BlogPageHandler) ToValidateLang() router.LangSetting {
return router.InPath
}
-func (r *BlogPageHandler) SitemapInfo(supplements *router.Supplements) []router.SitemapInfo {
- sitemapInfo := []router.SitemapInfo{}
-
- pages, err := supplements.B2Client.Scan("")
- if err != nil {
- return sitemapInfo
- }
-
- for _, page := range pages {
- sitemapInfo = append(sitemapInfo, router.SitemapInfo{
- Loc: "/" + page.Lang + "/blog/" + page.FileName,
- LastModified: page.ModifiedTime,
- Priority: 1.0,
- })
- }
-
- return sitemapInfo
-}
-
-func (r *BlogPageHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta []router.MetaField, err error) {
- metadata, _, err := supplements.B2Client.ReadFrontmatter(lang + "/" + c.Params("title") + ".md")
- if err != nil {
- return nil, fmt.Errorf("failed to read frontmatter of the desired blog post: %w", err)
- }
-
- return []router.MetaField{
- {Property: "og:title", Content: metadata.Title},
- {Property: "og:description", Content: fmt.Sprintf("%s [%s]", metadata.ShortDescription, metadata.ActionDate)},
- {Property: "og:image", Content: fmt.Sprintf("https://f003.backblazeb2.com/file/sayana-photos/webp-320p/%s.webp", metadata.Thumbnail)},
- {Property: "og:url", Content: fmt.Sprintf("%s/%s/blog/%s", templateMap["CanonicalEndpoint"], lang, c.Params("title"))},
- {Property: "og:type", Content: "website"},
- {Name: "twitter:card", Content: "summary_large_image"},
- }, nil
-}
-
-func (r *BlogPageHandler) AddLinkedData(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (ld map[string]any, err error) {
+func (r *BlogPageHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta map[string]string, err error) {
metadata, _, err := supplements.B2Client.ReadFrontmatter(lang + "/" + c.Params("title") + ".md")
if err != nil {
return nil, fmt.Errorf("failed to read frontmatter of the desired blog post: %w", err)
}
- return map[string]any{
- "@context": "https://schema.org",
- "@type": "Article",
- "headline": metadata.Title,
- "description": fmt.Sprintf("%s [%s]", metadata.ShortDescription, metadata.ActionDate),
- "author": map[string]string{"@type": "Person", "name": "Saya Andy"},
- "datePublished": metadata.PublishedTime.UTC().Format(time.RFC3339),
+ return map[string]string{
+ "og:title": metadata.Title,
+ "og:description": fmt.Sprintf("%s [%s]", metadata.ShortDescription, metadata.ActionDate),
+ "og:image": fmt.Sprintf("https://f003.backblazeb2.com/file/sayana-photos/webp-320p/%s.webp", metadata.Thumbnail),
+ "twitter:card": "summary_large_image",
}, nil
}
diff --git a/internal/router/handlers/lang-blog.go b/internal/router/handlers/lang-blog.go
index 709d3dc..e4c20c6 100644
--- a/internal/router/handlers/lang-blog.go
+++ b/internal/router/handlers/lang-blog.go
@@ -47,23 +47,6 @@ func (r *CatalogueHandler) ToValidateLang() router.LangSetting {
return router.InPath
}
-func (r *CatalogueHandler) SitemapInfo(supplements *router.Supplements) []router.SitemapInfo {
- sitemapInfo := []router.SitemapInfo{}
- for _, lang := range supplements.AvailableLanguages {
- sitemapInfo = append(sitemapInfo, router.SitemapInfo{Loc: "/" + lang.Name + "/blog", Priority: 0.3})
- }
- return sitemapInfo
-}
-
-func (r *CatalogueHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta []router.MetaField, err error) {
- return []router.MetaField{
- {Property: "og:title", Content: supplements.Localization[lang].BlogSearch.Header},
- {Property: "og:description", Content: supplements.Localization[lang].BlogSearch.Description},
- {Property: "og:url", Content: fmt.Sprintf("%s/%s/blog", templateMap["CanonicalEndpoint"], lang)},
- {Property: "og:type", Content: "website"},
- }, nil
-}
-
func (r *CatalogueHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
querySort := c.Query("sort")
if querySort == "" {
diff --git a/internal/router/handlers/lang-map.go b/internal/router/handlers/lang-map.go
index 551b485..7df6104 100644
--- a/internal/router/handlers/lang-map.go
+++ b/internal/router/handlers/lang-map.go
@@ -40,14 +40,6 @@ func (r *MapHandler) ToValidateLang() router.LangSetting {
return router.InPath
}
-func (r *MapHandler) SitemapInfo(supplements *router.Supplements) []router.SitemapInfo {
- sitemapInfo := []router.SitemapInfo{}
- for _, lang := range supplements.AvailableLanguages {
- sitemapInfo = append(sitemapInfo, router.SitemapInfo{Loc: "/" + lang.Name + "/map", Priority: 0.3})
- }
- return sitemapInfo
-}
-
func (r *MapHandler) Render(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
pages, err := supplements.B2Client.Scan(lang + "/")
slices.SortFunc(pages, func(a *b2.BlogPage, b *b2.BlogPage) int {
diff --git a/internal/router/handlers/lang-user.go b/internal/router/handlers/lang-user.go
index eae1685..c22bcac 100644
--- a/internal/router/handlers/lang-user.go
+++ b/internal/router/handlers/lang-user.go
@@ -37,13 +37,10 @@ func (r *UserHandler) ToValidateLang() router.LangSetting {
return router.InPath
}
-func (r *UserHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta []router.MetaField, err error) {
- return []router.MetaField{
- {Name: "robots", Content: "noindex,nofollow"},
- {Property: "og:title", Content: supplements.Localization[lang].UserProfile.Header},
- {Property: "og:description", Content: supplements.Localization[lang].UserProfile.Description},
- {Property: "og:url", Content: fmt.Sprintf("%s/%s/user", templateMap["CanonicalEndpoint"], lang)},
- {Property: "og:type", Content: "website"},
+func (r *UserHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta map[string]string, err error) {
+ return map[string]string{
+ "og:title": supplements.Localization[lang].BlogSearch.Header,
+ "og:description": supplements.Localization[lang].BlogSearch.Description,
}, nil
}
diff --git a/internal/router/handlers/lang.go b/internal/router/handlers/lang.go
index c618353..74166ae 100644
--- a/internal/router/handlers/lang.go
+++ b/internal/router/handlers/lang.go
@@ -41,21 +41,11 @@ func (r *HomeHandler) ToValidateLang() router.LangSetting {
return router.InPath
}
-func (r *HomeHandler) SitemapInfo(supplements *router.Supplements) []router.SitemapInfo {
- sitemapInfo := []router.SitemapInfo{}
- for _, lang := range supplements.AvailableLanguages {
- sitemapInfo = append(sitemapInfo, router.SitemapInfo{Loc: "/" + lang.Name, Priority: 0.7})
- }
- return sitemapInfo
-}
-
-func (r *HomeHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta []router.MetaField, err error) {
- return []router.MetaField{
- {Property: "og:title", Content: supplements.Localization[lang].HomePage.Header},
- {Property: "og:description", Content: supplements.Localization[lang].HomePage.HomePageDescription},
- {Property: "og:image", Content: fmt.Sprintf("https://f003.backblazeb2.com/file/sayana-static/home-page-gifs/otter-%d.gif", rand.Int()%3+1)},
- {Property: "og:url", Content: fmt.Sprintf("%s/%s", templateMap["CanonicalEndpoint"], lang)},
- {Property: "og:type", Content: "website"},
+func (r *HomeHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta map[string]string, err error) {
+ return map[string]string{
+ "og:title": supplements.Localization[lang].HomePage.Header,
+ "og:description": supplements.Localization[lang].HomePage.HomePageDescription,
+ "og:image": "https://f003.backblazeb2.com/file/sayana-static/home-page-gifs/" + fmt.Sprintf("otter-%d.gif", rand.Int()%3+1),
}, nil
}
diff --git a/internal/router/handlers/robots.txt.go b/internal/router/handlers/robots.txt.go
deleted file mode 100644
index fc60af4..0000000
--- a/internal/router/handlers/robots.txt.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package handlers
-
-import (
- "time"
-
- "github.com/SayaAndy/saya-today-web/internal/router"
- "github.com/gofiber/fiber/v2"
-)
-
-type RobotsTxtHandler struct {
- router.BasicHandler
-}
-
-func init() {
- router.Routes = append(router.Routes, &RobotsTxtHandler{})
-}
-
-func (r *RobotsTxtHandler) Filter() (method string, path string) {
- return "GET", "/robots.txt"
-}
-
-func (r *RobotsTxtHandler) IsTemplated() bool {
- return false
-}
-
-func (r *RobotsTxtHandler) TemplatesToInject() []string {
- return []string{"views/pages/robots.txt"}
-}
-
-func (r *RobotsTxtHandler) ToCache() router.CacheSetting {
- return router.ByUrlOnly
-}
-
-func (r *RobotsTxtHandler) CacheDuration() time.Duration {
- return time.Hour
-}
-
-func (r *RobotsTxtHandler) ToValidateLang() router.LangSetting {
- return router.NotRequired
-}
-
-func (r *RobotsTxtHandler) ContentType() string {
- return fiber.MIMETextPlainCharsetUTF8
-}
-
-func (r *RobotsTxtHandler) Render(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
- return fiber.StatusOK, nil
-}
diff --git a/internal/router/handlers/root.go b/internal/router/handlers/root.go
index cd01fcd..9f15782 100644
--- a/internal/router/handlers/root.go
+++ b/internal/router/handlers/root.go
@@ -1,7 +1,6 @@
package handlers
import (
- "fmt"
"time"
"github.com/SayaAndy/saya-today-web/internal/router"
@@ -36,16 +35,10 @@ func (r *RootHandler) CacheDuration() time.Duration {
return 24 * time.Hour
}
-func (r *RootHandler) SitemapInfo(_ *router.Supplements) []router.SitemapInfo {
- return []router.SitemapInfo{{Loc: "/", Priority: 0.7}}
-}
-
-func (r *RootHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta []router.MetaField, err error) {
- return []router.MetaField{
- {Property: "og:title", Content: "Saya Blog"},
- {Property: "og:description", Content: "The blog of a 25 years old, travelling God knows where, proud to be not mainstream // Личный блог 25-летки, странствующего по ебеням, зато не мейнстрим"},
- {Property: "og:url", Content: fmt.Sprint(templateMap["CanonicalEndpoint"]) + "/"},
- {Property: "og:type", Content: "website"},
+func (r *RootHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta map[string]string, err error) {
+ return map[string]string{
+ "og:title": "Saya Blog",
+ "og:description": "The blog of a 25 years old, travelling God knows where, proud to be not mainstream // Личный блог 25-летки, странствующего по ебеням, зато не мейнстрим",
}, nil
}
diff --git a/internal/router/handlers/sitemap.xml.go b/internal/router/handlers/sitemap.xml.go
deleted file mode 100644
index bb1df93..0000000
--- a/internal/router/handlers/sitemap.xml.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package handlers
-
-import (
- "log/slog"
- "time"
-
- "github.com/SayaAndy/saya-today-web/internal/router"
- "github.com/gofiber/fiber/v2"
-)
-
-type SitemapXmlHandler struct {
- router.BasicHandler
-}
-
-func init() {
- router.Routes = append(router.Routes, &SitemapXmlHandler{})
-}
-
-func (r *SitemapXmlHandler) Filter() (method string, path string) {
- return "GET", "/sitemap.xml"
-}
-
-func (r *SitemapXmlHandler) IsTemplated() bool {
- return false
-}
-
-func (r *SitemapXmlHandler) TemplatesToInject() []string {
- return []string{"views/pages/sitemap.xml"}
-}
-
-func (r *SitemapXmlHandler) ToCache() router.CacheSetting {
- return router.ByUrlOnly
-}
-
-func (r *SitemapXmlHandler) CacheDuration() time.Duration {
- return time.Hour
-}
-
-func (r *SitemapXmlHandler) ToValidateLang() router.LangSetting {
- return router.NotRequired
-}
-
-func (r *SitemapXmlHandler) ContentType() string {
- return fiber.MIMEApplicationXMLCharsetUTF8
-}
-
-func (r *SitemapXmlHandler) Render(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
- urls := []router.SitemapInfo{}
- for _, route := range router.Routes {
- sitemapInfo := route.SitemapInfo(supplements)
- if sitemapInfo == nil {
- continue
- }
-
- method, match := route.Filter()
- lastMod, err := supplements.TemplateManager.GetLastModified(method + " " + match)
- if err != nil {
- slog.Warn("failed to get last modified for a route",
- slog.String("error", err.Error()),
- slog.String("method", method),
- slog.String("match", match))
- lastMod = time.Now()
- }
-
- for i := range sitemapInfo {
- if sitemapInfo[i].LastModified.Before(lastMod) {
- sitemapInfo[i].LastModified = lastMod
- }
- if sitemapInfo[i].ChangeFreq == "" {
- sitemapInfo[i].ChangeFreq = "monthly"
- }
- urls = append(urls, sitemapInfo[i])
- }
- }
-
- templateMap["URLs"] = urls
-
- return fiber.StatusOK, nil
-}
diff --git a/internal/router/router.go b/internal/router/router.go
index 0d0ce8c..f28add2 100644
--- a/internal/router/router.go
+++ b/internal/router/router.go
@@ -2,10 +2,8 @@ package router
import (
"database/sql"
- "encoding/json"
"errors"
"fmt"
- "html/template"
"log/slog"
"net/url"
"slices"
@@ -23,9 +21,7 @@ import (
"github.com/SayaAndy/saya-today-web/locale"
"github.com/dgraph-io/ristretto/v2"
"github.com/gofiber/fiber/v2"
- "github.com/gofiber/fiber/v2/middleware/compress"
"github.com/gofiber/fiber/v2/middleware/cors"
- "github.com/gofiber/fiber/v2/middleware/etag"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database/sqlite3"
"github.com/yuin/goldmark"
@@ -56,19 +52,6 @@ var (
Routes = make([]Route, 0)
)
-type SitemapInfo struct {
- Loc string
- LastModified time.Time
- ChangeFreq string
- Priority float32
-}
-
-type MetaField struct {
- Name string
- Property string
- Content string
-}
-
type Route interface {
Filter() (method string, path string)
IsTemplated() bool
@@ -76,11 +59,8 @@ type Route interface {
CacheDuration() time.Duration
ToValidateLang() LangSetting
TemplatesToInject() []string
- SitemapInfo(supplements *Supplements) []SitemapInfo
- ContentType() string
Render(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (statusCode int, err error)
- AddMeta(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (meta []MetaField, err error)
- AddLinkedData(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (ld map[string]any, err error)
+ AddMeta(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (meta map[string]string, err error)
RenderHeader(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (statusCode int, err error)
RenderBody(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (statusCode int, err error)
RenderFooter(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (statusCode int, err error)
@@ -107,7 +87,6 @@ type Router struct {
app *fiber.App
templatedRoutes map[string]map[string]Route
templatedPathMatcher *PathMatcher
- canonicalEndpoint string
}
func NewRouter(cfg *config.Config) (*Router, error) {
@@ -231,24 +210,10 @@ func NewRouter(cfg *config.Config) (*Router, error) {
AllowHeaders: "Origin, Content-Type, Accept",
}))
- app.Use(compress.New(compress.Config{
- Level: compress.LevelBestSpeed,
- }))
-
- app.Use(etag.New())
-
- app.Use(func(c *fiber.Ctx) error {
- path := c.Path()
- if len(path) > 1 && path[len(path)-1] == '/' {
- return c.Redirect(strings.TrimRight(path, "/"), fiber.StatusMovedPermanently)
- }
- return c.Next()
- })
-
templatedRoutes := make(map[string]map[string]Route)
templatedPathMatcher := NewPathMatcher()
- return &Router{supplements, app, templatedRoutes, templatedPathMatcher, cfg.CanonicalEndpoint}, nil
+ return &Router{supplements, app, templatedRoutes, templatedPathMatcher}, nil
}
func (r *Router) InitRoutes() (err error) {
@@ -296,11 +261,10 @@ func (r *Router) InitRoutes() (err error) {
}
defaultMap := fiber.Map{
- "L": r.supplements.Localization[lang],
- "Lang": lang,
- "Path": trimmedPath,
- "QueryString": queryString,
- "CanonicalEndpoint": r.canonicalEndpoint,
+ "L": r.supplements.Localization[lang],
+ "Lang": lang,
+ "Path": trimmedPath,
+ "QueryString": queryString,
}
statusCode, err := currentRoute.Render(c, r.supplements, lang, defaultMap)
@@ -339,8 +303,8 @@ func (r *Router) InitRoutes() (err error) {
go r.supplements.PageCache.SetWithTTL(cacheKey, content, int64(len(content)), route.CacheDuration())
}
- c.Set(fiber.HeaderContentType, route.ContentType())
- return c.Status(statusCode).Send(content)
+ c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
+ return c.Status(statusCode).Type("html").Send(content)
})
}
}
@@ -363,7 +327,7 @@ func (r *Router) InitRoutes() (err error) {
r.app.Static("/", "./static")
- // Routes = make([]Route, 0)
+ Routes = make([]Route, 0)
return nil
}
@@ -415,15 +379,14 @@ func (r *Router) generalPage(c *fiber.Ctx, route Route, lang string) error {
}
if val, ok := r.supplements.PageCache.Get(cacheKey); val != nil && ok {
- c.Set(fiber.HeaderContentType, route.ContentType())
- return c.Status(fiber.StatusOK).Send(val)
+ c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
+ return c.Status(fiber.StatusOK).Type("html").Send(val)
}
valueMap := fiber.Map{
- "L": r.supplements.Localization[lang],
- "Lang": lang,
- "QueryString": queryString,
- "CanonicalEndpoint": r.canonicalEndpoint,
+ "L": r.supplements.Localization[lang],
+ "Lang": lang,
+ "QueryString": queryString,
}
var err error
@@ -431,15 +394,6 @@ func (r *Router) generalPage(c *fiber.Ctx, route Route, lang string) error {
slog.Warn("failed to receive meta", slog.String("path", path), slog.String("error", err.Error()))
}
- var ld map[string]any
- if ld, err = route.AddLinkedData(c, r.supplements, lang, valueMap); err != nil {
- slog.Warn("failed to receive linked data", slog.String("path", path), slog.String("error", err.Error()))
- }
- if ld != nil {
- ldBytes, _ := json.Marshal(ld)
- valueMap["LinkedData"] = template.JS(ldBytes)
- }
-
content, err := r.supplements.TemplateManager.Render("general-page", valueMap)
if err != nil {
slog.Warn("failed to generate div", slog.String("path", path), slog.String("error", err.Error()))
@@ -447,8 +401,8 @@ func (r *Router) generalPage(c *fiber.Ctx, route Route, lang string) error {
}
go r.supplements.PageCache.SetWithTTL(cacheKey, content, int64(len(content)), route.CacheDuration())
- c.Set(fiber.HeaderContentType, route.ContentType())
- return c.Status(fiber.StatusOK).Send(content)
+ c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
+ return c.Status(fiber.StatusOK).Type("html").Send(content)
}
func (r *Router) generalPageSegment(c *fiber.Ctx, part string) error {
@@ -493,18 +447,17 @@ func (r *Router) generalPageSegment(c *fiber.Ctx, part string) error {
if route.ToCache() != Disabled {
if val, ok := r.supplements.PageCache.Get(cacheKey); val != nil && ok {
- c.Set(fiber.HeaderContentType, route.ContentType())
- return c.Status(fiber.StatusOK).Send(val)
+ c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
+ return c.Status(fiber.StatusOK).Type("html").Send(val)
}
}
var statusCode int
defaultMap := fiber.Map{
- "L": r.supplements.Localization[lang],
- "Lang": lang,
- "Path": strings.Trim(path, "/"),
- "QueryString": queryString,
- "CanonicalEndpoint": r.canonicalEndpoint,
+ "L": r.supplements.Localization[lang],
+ "Lang": lang,
+ "Path": strings.Trim(path, "/"),
+ "QueryString": queryString,
}
switch part {
@@ -552,8 +505,8 @@ func (r *Router) generalPageSegment(c *fiber.Ctx, part string) error {
go r.supplements.PageCache.SetWithTTL(cacheKey, content, int64(len(content)), route.CacheDuration())
}
- c.Set(fiber.HeaderContentType, route.ContentType())
- return c.Status(statusCode).Send(content)
+ c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
+ return c.Status(statusCode).Type("html").Send(content)
}
func (r *Router) getAndValidateLang(c *fiber.Ctx, langSetting LangSetting, defaultLang ...string) (string, error) {
diff --git a/internal/templatemanager/templatemanager.go b/internal/templatemanager/templatemanager.go
index 9d14e15..b23e2e8 100644
--- a/internal/templatemanager/templatemanager.go
+++ b/internal/templatemanager/templatemanager.go
@@ -4,10 +4,8 @@ import (
"bytes"
"fmt"
"html/template"
- "os"
"path/filepath"
"strings"
- "time"
)
type TemplateManager struct {
@@ -15,9 +13,8 @@ type TemplateManager struct {
}
type templateManagerRender struct {
- Main string
- Tmpl *template.Template
- LastModified time.Time
+ Main string
+ Tmpl *template.Template
}
type TemplateManagerTemplates struct {
@@ -56,15 +53,10 @@ func NewTemplateManager(templates ...TemplateManagerTemplates) (*TemplateManager
if err != nil {
return nil, err
}
- modTime, err := setLastModified(tmplStruct.Files...)
- if err != nil {
- return nil, err
- }
templateMap[tmplStruct.Name] = templateManagerRender{
- Main: filepath.Base(tmplStruct.Files[0]),
- Tmpl: tmpl,
- LastModified: modTime,
+ Main: filepath.Base(tmplStruct.Files[0]),
+ Tmpl: tmpl,
}
}
@@ -122,40 +114,10 @@ func (tm *TemplateManager) Add(name string, files ...string) error {
return fmt.Errorf("failed to add template into manager: %w", err)
}
- modTime, err := setLastModified(files...)
- if err != nil {
- return fmt.Errorf("failed to add template into manager: %w", err)
- }
-
tm.templates[name] = templateManagerRender{
- Main: filepath.Base(files[0]),
- Tmpl: tmpl,
- LastModified: modTime,
+ Main: filepath.Base(files[0]),
+ Tmpl: tmpl,
}
return nil
}
-
-func (tm *TemplateManager) GetLastModified(name string) (time.Time, error) {
- tmpl, exists := tm.templates[name]
- if !exists {
- return time.Time{}, fmt.Errorf("template %s not found", name)
- }
-
- return tmpl.LastModified, nil
-}
-
-func setLastModified(filenames ...string) (time.Time, error) {
- lastModified := time.Time{}
- for _, filename := range filenames {
- stat, err := os.Stat(filename)
- if err != nil {
- return lastModified, fmt.Errorf("failed to stat file: path '%s': %w", filename, err)
- }
- modTime := stat.ModTime()
- if lastModified.Before(modTime) {
- lastModified = modTime
- }
- }
- return lastModified, nil
-}
diff --git a/locale/localization.en.yaml b/locale/localization.en.yaml
index 9923881..e165866 100644
--- a/locale/localization.en.yaml
+++ b/locale/localization.en.yaml
@@ -48,7 +48,6 @@ Mail:
CapturedOn: 'Captured on'
UserProfile:
Header: 'Personal Settings'
- Description: 'Set and verify your e-mail here, as well as subscribe to favorite blog tags'
EmailHeader: 'E-Mail'
VerificationCodeHeader: 'Verification Code'
TypeEmail: 'Please type your email'
diff --git a/locale/localization.go b/locale/localization.go
index 7080355..a4f36f1 100644
--- a/locale/localization.go
+++ b/locale/localization.go
@@ -85,7 +85,6 @@ type NewPostConfig struct {
type UserProfileConfig struct {
Header string `yaml:"Header" json:"Header"`
- Description string `yaml:"Description" json:"Description"`
EmailHeader string `yaml:"EmailHeader" json:"EmailHeader"`
VerificationCodeHeader string `yaml:"VerificationCodeHeader" json:"VerificationCodeHeader"`
TypeEmail string `yaml:"TypeEmail" json:"TypeEmail"`
diff --git a/locale/localization.ru.yaml b/locale/localization.ru.yaml
index 34e5387..e65848a 100644
--- a/locale/localization.ru.yaml
+++ b/locale/localization.ru.yaml
@@ -48,7 +48,6 @@ Mail:
CapturedOn: 'Снималось'
UserProfile:
Header: 'Личные настройки'
- Description: 'Здесь можно настроить и верифицировать свою электронную почту, а также подписаться на избранные темы блога'
EmailHeader: 'E-Mail'
VerificationCodeHeader: 'Код верификации'
TypeEmail: 'Пожалуйста, введите свою почту'
diff --git a/views/layouts/general-page.html b/views/layouts/general-page.html
index 7167d12..3f5bcfd 100644
--- a/views/layouts/general-page.html
+++ b/views/layouts/general-page.html
@@ -3,24 +3,13 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
- {{- range .Meta }}
- <meta {{with .Name}}name="{{.}}" {{end}}{{with .Property}}property="{{.}}" {{end}}{{with .Content}}content="{{.}}"{{end}}>
- {{- if eq .Property "og:description" }}
- <meta name="description" href="{{.Content}}">
- {{- end }}
- {{- if eq .Property "og:url" }}
- <link rel="canonical" href="{{.Content}}">
- {{- end }}
+ {{- range $k, $v := .Meta }}
+ <meta name="{{ $k }}" content="{{ $v }}">
{{- end }}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
<link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/leaflet/1.9.4/leaflet.css">
<link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/glightbox/3.3.0/css/glightbox.min.css">
<link href="/output.css" rel="stylesheet">
- {{- with .LinkedData }}
- <script type="application/ld+json">
- {{ . }}
- </script>
- {{- end }}
</head>
<body data-theme="ram" class="font-andika text-main-hard overflow-hidden bg-interlocked-hexagons h-dvh flex flex-row">
@@ -191,7 +180,7 @@
flex-row sticky w-dvw h-fit xs:w-[90dvw]
sm:left-0 sm:flex-col sm:fixed sm:w-fit
z-20 shadow-[0_0_1rem_black]">
- <nav aria-label="Main navigation" class="text-[3rem] flex flex-row sm:flex-col gap-0 relative z-20">
+ <div class="text-[3rem] flex flex-row sm:flex-col gap-0 relative z-20">
<a onclick="return changeUrl('/../', true);" href="./" id="sidebar-back-button" class="themed-button themed-button-sidebar w-fit h-fit hidden" draggable="false">
<i class="fas fa-circle-left flex w-18 h-18 content-center text-center text-sidebar"></i>
</a>
@@ -210,7 +199,7 @@
<a onclick="return changeUrl('/{{ .Lang }}/user');" href="/{{ .Lang }}/user" id="sidebar-user-button" class="themed-button themed-button-sidebar w-fit h-fit hidden" draggable="false">
<i class="fas fa-user flex w-18 h-18 content-center text-center text-sidebar"></i>
</a>
- </nav>
+ </div>
<div class="theme-wheel" id="theme-wheel">
<div class="theme-icon" data-theme="olive"></div>
<div class="theme-icon" data-theme="lettuce"></div>
@@ -258,21 +247,21 @@
<div class="bg-background-dark border-r-2 border-dashed border-main-hard"></div>
<div class="max-h-full max-w-full flex flex-col grow bg-background-dark relative pt-4 ml-8 pr-4">
- <header id="general-page-header" class="max-xs:hidden [@media(max-height:32rem)]:hidden flex flex-col basis-8"
+ <div id="general-page-header" class="max-xs:hidden [@media(max-height:32rem)]:hidden flex flex-col basis-8"
hx-get="/api/v1/general-page/header{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML">
- </header>
+ </div>
<div id="general-page-header-trigger" hx-get="/api/v1/general-page/header{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-header" hx-swap="innerHTML"></div>
<hr class="max-xs:hidden [@media(max-height:32rem)]:hidden border-t-4 border-dotted border-main-hard mb-2">
- <main id="general-page-body" class="relative flex flex-col grow overflow-y-auto"
+ <div id="general-page-body" class="relative flex flex-col grow overflow-y-auto"
hx-get="/api/v1/general-page/body{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML">
- </main>
+ </div>
<div id="general-page-body-trigger" hx-get="/api/v1/general-page/body{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-body" hx-swap="innerHTML"></div>
- <footer id="general-page-footer" class="flex flex-row basis-4 my-1"
+ <div id="general-page-footer" class="flex flex-row basis-4 my-1"
hx-get="/api/v1/general-page/footer{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML">
- </footer>
+ </div>
<div id="general-page-footer-trigger" hx-get="/api/v1/general-page/footer{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-footer" hx-swap="innerHTML"></div>
<hr class="border-t-4 border-dotted border-main-hard mb-2">
diff --git a/views/pages/blog-page.html b/views/pages/blog-page.html
index 3fc4526..c81406f 100644
--- a/views/pages/blog-page.html
+++ b/views/pages/blog-page.html
@@ -1,12 +1,12 @@
{{ define "body" }}
<div class="absolute w-full h-full inset-0 inset-shadow-[0_0_0.4rem_black] pointer-events-none z-20"></div>
-<article class="relative bg-background-light flex flex-col px-8 py-4 overflow-y-auto">
- <h1 class="max-xs:block [@media(max-height:32rem)]:block hidden font-andika text-2xl font-bold italic text-main-hard tracking-[.0125rem] mb-1">{{ .Title }}</h1>
+<div class="relative bg-background-light flex flex-col px-8 py-4 overflow-y-auto">
+ <p class="max-xs:block [@media(max-height:32rem)]:block hidden font-andika text-2xl font-bold italic text-main-hard tracking-[.0125rem] mb-1">{{ .Title }}</p>
<p class="block grow text-lg font-andika text-secondary">
<b>{{ .L.Metadata.Published }}</b>:
- <time datetime="{{ .PublishedDate }}" hx-get="/api/v1/tz" hx-vals='js:{timestamp: "{{ .PublishedDate }}", tz: clientTimeZone}' hx-target="this" hx-swap="innerHTML" hx-trigger="load">
+ <span hx-get="/api/v1/tz" hx-vals='js:{timestamp: "{{ .PublishedDate }}", tz: clientTimeZone}' hx-target="this" hx-swap="innerHTML" hx-trigger="load">
{{ .PublishedDate }}
- </time>
+ </span>
</p>
<p class="block grow text-lg font-andika text-secondary"><b>{{ .L.Metadata.Action }}</b>: {{ .ActionDate }}</p>
<p class="block grow text-md font-andika italic text-main-hard">{{ .ShortDescription }}</p>
@@ -60,7 +60,7 @@
});
</script>
{{- end }}
-</article>
+</div>
{{ end }}
{{ define "header" }}
diff --git a/views/pages/global-map.html b/views/pages/global-map.html
index 604b52e..4b07bd2 100644
--- a/views/pages/global-map.html
+++ b/views/pages/global-map.html
@@ -3,13 +3,9 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="description" content="{{ .L.GlobalMap.Description }}">
- <meta property="og:title" content="{{ .L.GlobalMap.Header }}">
- <meta property="og:description" content="{{ .L.GlobalMap.Description }}">
- <meta property="og:url" content="{{ .CanonicalEndpoint }}/{{ .Lang }}/map">
- <meta property="og:type" content="site">
+ <meta name="og:title" content="{{ .L.GlobalMap.Header }}">
+ <meta name="og:description" content="{{ .L.GlobalMap.Description }}">
<title>{{ .L.GlobalMap.Header }} // SAYA TODAY</title>
- <link rel="canonical" href="{{ .CanonicalEndpoint }}/{{ .Lang }}/map">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
{{ block "header" . }}{{ end }}
<link href="/output.css" rel="stylesheet">
diff --git a/views/pages/robots.txt b/views/pages/robots.txt
deleted file mode 100644
index 1e5bebb..0000000
--- a/views/pages/robots.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-User-agent: *
-Allow: /
-Disallow: /api/
-
-Sitemap: {{ .CanonicalEndpoint }}/sitemap.xml \ No newline at end of file
diff --git a/views/pages/sitemap.xml b/views/pages/sitemap.xml
deleted file mode 100644
index 1474a56..0000000
--- a/views/pages/sitemap.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
- {{- range .URLs }}
- <url>
- <loc>{{ $.CanonicalEndpoint }}{{ .Loc }}</loc>
- <lastmod>{{ .LastModified.UTC.Format "2006-01-02T15:04:05Z" }}</lastmod>
- <changefreq>{{ .ChangeFreq }}</changefreq>
- <priority>{{ printf "%.1f" .Priority }}</priority>
- </url>
- {{- end }}
-</urlset>