summaryrefslogtreecommitdiff
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
-rw-r--r--internal/router/basic-handler.go4
-rw-r--r--internal/router/handlers/lang-blog-title.go16
-rw-r--r--internal/router/router.go12
-rw-r--r--views/layouts/general-page.html21
-rw-r--r--views/pages/blog-page.html10
5 files changed, 50 insertions, 13 deletions
diff --git a/internal/router/basic-handler.go b/internal/router/basic-handler.go
index 96d0f77..b973d01 100644
--- a/internal/router/basic-handler.go
+++ b/internal/router/basic-handler.go
@@ -53,6 +53,10 @@ func (r *BasicHandler) AddMeta(c *fiber.Ctx, supplements *Supplements, lang stri
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) RenderHeader(c *fiber.Ctx, supplements *Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
return fiber.StatusNoContent, nil
}
diff --git a/internal/router/handlers/lang-blog-title.go b/internal/router/handlers/lang-blog-title.go
index a9acdbb..5bfc6e7 100644
--- a/internal/router/handlers/lang-blog-title.go
+++ b/internal/router/handlers/lang-blog-title.go
@@ -81,6 +81,22 @@ func (r *BlogPageHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements,
}, nil
}
+func (r *BlogPageHandler) AddLinkedData(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (ld map[string]any, 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),
+ }, nil
+}
+
func (r *BlogPageHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
_, pathParts, _, err := router.GetPathFromReferer(c)
if err != nil {
diff --git a/internal/router/router.go b/internal/router/router.go
index 3ce7e3b..0d0ce8c 100644
--- a/internal/router/router.go
+++ b/internal/router/router.go
@@ -2,8 +2,10 @@ package router
import (
"database/sql"
+ "encoding/json"
"errors"
"fmt"
+ "html/template"
"log/slog"
"net/url"
"slices"
@@ -78,6 +80,7 @@ type Route interface {
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)
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)
@@ -428,6 +431,15 @@ 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()))
diff --git a/views/layouts/general-page.html b/views/layouts/general-page.html
index 2114b1c..7167d12 100644
--- a/views/layouts/general-page.html
+++ b/views/layouts/general-page.html
@@ -16,6 +16,11 @@
<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">
@@ -186,7 +191,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]">
- <div class="text-[3rem] flex flex-row sm:flex-col gap-0 relative z-20">
+ <nav aria-label="Main navigation" 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>
@@ -205,7 +210,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>
- </div>
+ </nav>
<div class="theme-wheel" id="theme-wheel">
<div class="theme-icon" data-theme="olive"></div>
<div class="theme-icon" data-theme="lettuce"></div>
@@ -253,21 +258,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">
- <div id="general-page-header" class="max-xs:hidden [@media(max-height:32rem)]:hidden flex flex-col basis-8"
+ <header 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">
- </div>
+ </header>
<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">
- <div id="general-page-body" class="relative flex flex-col grow overflow-y-auto"
+ <main 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">
- </div>
+ </main>
<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>
- <div id="general-page-footer" class="flex flex-row basis-4 my-1"
+ <footer 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">
- </div>
+ </footer>
<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 c81406f..3fc4526 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>
-<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>
+<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>
<p class="block grow text-lg font-andika text-secondary">
<b>{{ .L.Metadata.Published }}</b>:
- <span hx-get="/api/v1/tz" hx-vals='js:{timestamp: "{{ .PublishedDate }}", tz: clientTimeZone}' hx-target="this" hx-swap="innerHTML" hx-trigger="load">
+ <time datetime="{{ .PublishedDate }}" hx-get="/api/v1/tz" hx-vals='js:{timestamp: "{{ .PublishedDate }}", tz: clientTimeZone}' hx-target="this" hx-swap="innerHTML" hx-trigger="load">
{{ .PublishedDate }}
- </span>
+ </time>
</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 }}
-</div>
+</article>
{{ end }}
{{ define "header" }}