aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/data.go4
-rw-r--r--backend/logs.go66
-rw-r--r--backend/router.go20
-rw-r--r--backend/templates/base.html11
-rw-r--r--main.go2
5 files changed, 67 insertions, 36 deletions
diff --git a/backend/data.go b/backend/data.go
index cd1ea9e..f3e8b42 100644
--- a/backend/data.go
+++ b/backend/data.go
@@ -89,3 +89,7 @@ func (d *data) Title() string {
}
return title
}
+
+func (d *data) PubDate() string {
+ return ""
+}
diff --git a/backend/logs.go b/backend/logs.go
index e25c638..d15be41 100644
--- a/backend/logs.go
+++ b/backend/logs.go
@@ -9,6 +9,7 @@ import (
"os"
"path/filepath"
"strings"
+ "sync"
"git.anhgelus.world/anhgelus/small-world/markdown"
"github.com/go-chi/chi/v5"
@@ -16,22 +17,26 @@ import (
)
var (
- logs = map[string]string{}
- loadedLogs = map[string]*logData{}
+ logs = map[string]*logData{}
)
type logData struct {
*data
- LogTitle string `toml:"title"`
- Description string `toml:"description"`
- Img image `toml:"image"`
- Content template.HTML `toml:"-"`
+ LogTitle string `toml:"title"`
+ Description string `toml:"description"`
+ Img image `toml:"image"`
+ pubDate toml.LocalDate `toml:"publication_date"`
+ Content template.HTML `toml:"-"`
}
func (d *logData) SetData(dt *data) {
d.data = dt
}
+func (d *logData) PubDate() string {
+ return d.pubDate.String()
+}
+
type image struct {
Src string `toml:"src"`
Alt string `toml:"alt"`
@@ -62,6 +67,7 @@ func LoadLogs(cfg *Config) bool {
}
func readLogDir(path string, dir []os.DirEntry) error {
+ var wg sync.WaitGroup
for _, d := range dir {
p := filepath.Join(path, d.Name())
if d.IsDir() {
@@ -76,18 +82,31 @@ func readLogDir(path string, dir []os.DirEntry) error {
if !strings.HasSuffix(d.Name(), ".md") {
return fmt.Errorf("file %s is not a markdown file", d.Name())
}
- _, ok := logs[d.Name()]
+ slug := strings.TrimSuffix(p, ".md")
+ _, ok := logs[slug]
if ok {
return fmt.Errorf("log already exists: %s", d.Name())
}
- logs[strings.TrimSuffix(d.Name(), ".md")] = p
+ dd := new(logData)
+ dd.data = new(data)
+ go func() {
+ wg.Add(1)
+ defer wg.Done()
+ ok = parseLog(dd, slug, strings.TrimSuffix(d.Name(), ".md"))
+ if ok {
+ slog.Debug("log parsed", "path", p)
+ } else {
+ slog.Debug("log skipped", "path", p)
+ }
+ }()
}
}
+ wg.Wait()
return nil
}
func HandleLogs(r *chi.Mux) {
- r.Route("/logs", func(r chi.Router) {
+ r.Route("/log", func(r chi.Router) {
r.Get("/", handleLogList)
r.Get("/{slug:[a-zA-Z0-9-]+}", handleLog)
})
@@ -98,32 +117,30 @@ func handleLogList(w http.ResponseWriter, r *http.Request) {
}
func handleLog(w http.ResponseWriter, r *http.Request) {
+ cfg := r.Context().Value("config").(*Config)
slug := chi.URLParam(r, "slug")
- path, ok := logs[slug]
- if !ok {
- http.NotFoundHandler().ServeHTTP(w, r)
- return
- }
- var d *logData
- d, ok = loadedLogs[slug]
+ path := filepath.Join(cfg.LogFolder, slug)
+ d, ok := logs[path]
if !ok {
d = new(logData)
d.data = new(data)
- d.Article = true
- d.LogTitle = slug
- d.title = slug
- if ok = parseLog(d, path); !ok {
- w.WriteHeader(http.StatusInternalServerError)
+ if ok = parseLog(d, path, slug); !ok {
+ http.NotFoundHandler().ServeHTTP(w, r)
return
}
- loadedLogs[slug] = d
}
d.handleGeneric(w, r, "log", d)
}
-func parseLog(d *logData, path string) bool {
- b, err := os.ReadFile(path)
+func parseLog(d *logData, path, slug string) bool {
+ d.Article = true
+ d.LogTitle = slug
+ d.title = slug
+ b, err := os.ReadFile(path + ".md")
if err != nil {
+ if os.IsNotExist(err) {
+ return false
+ }
panic(err)
}
var dd string
@@ -147,5 +164,6 @@ func parseLog(d *logData, path string) bool {
fmt.Println(errMd.Pretty())
return false
}
+ logs[path] = d
return true
}
diff --git a/backend/router.go b/backend/router.go
index 374e28b..33c685d 100644
--- a/backend/router.go
+++ b/backend/router.go
@@ -20,28 +20,38 @@ const Version = "0.1.0"
//go:embed templates
var templates embed.FS
-func NewRouter(debug bool, cfg *Config) *chi.Mux {
+func SetupLogger(debug bool) {
logFormat := httplog.SchemaECS.Concise(!debug)
+ logLevel := slog.LevelWarn
+ if debug {
+ logLevel = slog.LevelDebug
+ }
+
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
ReplaceAttr: logFormat.ReplaceAttr,
+ Level: logLevel,
})).With(
slog.String("app", "anhgelus/small-web"),
slog.String("version", Version),
)
+ slog.SetDefault(logger)
+}
+
+func NewRouter(debug bool, cfg *Config) *chi.Mux {
+ r := chi.NewRouter()
+
logLevel := slog.LevelWarn
if debug {
logLevel = slog.LevelDebug
}
- r := chi.NewRouter()
-
r.Use(middleware.Timeout(30 * time.Second))
- r.Use(httplog.RequestLogger(logger, &httplog.Options{
+ r.Use(httplog.RequestLogger(slog.Default(), &httplog.Options{
Level: logLevel,
// Set log output to Elastic Common Schema (ECS) format.
- Schema: logFormat,
+ Schema: httplog.SchemaECS.Concise(!debug),
RecoverPanics: true,
Skip: func(req *http.Request, respStatus int) bool {
return respStatus == http.StatusNotFound || respStatus == http.StatusMethodNotAllowed
diff --git a/backend/templates/base.html b/backend/templates/base.html
index 34a7c7f..bef493f 100644
--- a/backend/templates/base.html
+++ b/backend/templates/base.html
@@ -1,5 +1,5 @@
<!doctype html>
-<html lang="fr">
+<html lang="fr" prefix="og: https://ogp.me/ns/article#">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
@@ -15,6 +15,7 @@
<meta property="og:description" content="{{ .Description }}" />
<meta property="og:local" content="fr_FR" />
<meta property="og:site_name" content="{{ .Name }}" />
+ {{ if ne .PubDate "" }}<meta property="article:published_time" content="{{ .PubDate }}">{{ end }}
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image" />
<meta property="twitter:domain" content="{{ .Domain }}" />
@@ -31,13 +32,9 @@
</nav>
</header>
{{ if .Article }}
-<main>
- {{ template "body" . }}
-</main>
+<main>{{ template "body" . }}</main>
{{ else }}
-<article>
- {{ template "body" . }}
-</article>
+<article>{{ template "body" . }}</article>
{{ end }}
<footer>
<p>&copy; 2025 - Anhgelus Morthuuzh</p>
diff --git a/main.go b/main.go
index 78fa44b..fc64d5c 100644
--- a/main.go
+++ b/main.go
@@ -56,6 +56,8 @@ func init() {
func main() {
flag.Parse()
+ backend.SetupLogger(dev)
+
cfg, ok := backend.LoadConfig(configFile)
if !ok {
slog.Info("exiting")