diff --git a/blogstats.go b/blogstats.go
new file mode 100644
index 0000000..c7ef28b
--- /dev/null
+++ b/blogstats.go
@@ -0,0 +1,43 @@
+package main
+
+import (
+ "database/sql"
+ "net/http"
+)
+
+func serveBlogStats(blog, statsPath string) func(w http.ResponseWriter, r *http.Request) {
+ return func(w http.ResponseWriter, r *http.Request) {
+ var totalCount int
+ row, err := appDbQueryRow("select count(path) as count from posts where blog = @blog", sql.Named("blog", blog))
+ if err != nil {
+ serveError(w, r, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ err = row.Scan(&totalCount)
+ if err != nil {
+ serveError(w, r, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ var years, counts []int
+ rows, err := appDbQuery("select substr(published, 1, 4) as year, count(path) as count from posts where blog = @blog and coalesce(published, '') != '' group by year order by year desc", sql.Named("blog", blog))
+ if err != nil {
+ serveError(w, r, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ for rows.Next() {
+ var year, count int
+ rows.Scan(&year, &count)
+ years = append(years, year)
+ counts = append(counts, count)
+ }
+ render(w, templateBlogStats, &renderData{
+ blogString: blog,
+ Canonical: statsPath,
+ Data: map[string]interface{}{
+ "total": totalCount,
+ "years": years,
+ "counts": counts,
+ },
+ })
+ }
+}
diff --git a/config.go b/config.go
index 90e9315..e91f5d5 100644
--- a/config.go
+++ b/config.go
@@ -59,6 +59,7 @@ type configBlog struct {
Menus map[string]*menu `mapstructure:"menus"`
Photos *photos `mapstructure:"photos"`
Search *search `mapstructure:"search"`
+ BlogStats *blogStats `mapstructure:"blogStats"`
CustomPages []*customPage `mapstructure:"custompages"`
Telegram *configTelegram `mapstructure:"telegram"`
PostAsHome bool `mapstructure:"postAsHome"`
@@ -102,6 +103,13 @@ type search struct {
Placeholder string `mapstructure:"placeholder"`
}
+type blogStats struct {
+ Enabled bool `mapstructure:"enabled"`
+ Path string `mapstructure:"path"`
+ Title string `mapstructure:"title"`
+ Description string `mapstructure:"description"`
+}
+
type customPage struct {
Path string `mapstructure:"path"`
Template string `mapstructure:"template"`
diff --git a/http.go b/http.go
index e5848c6..cc9dd01 100644
--- a/http.go
+++ b/http.go
@@ -226,7 +226,7 @@ func buildHandler() (http.Handler, error) {
}
// Photos
- if blogConfig.Photos.Enabled {
+ if blogConfig.Photos != nil && blogConfig.Photos.Enabled {
photoPath := blogPath + blogConfig.Photos.Path
handler := servePhotos(blog, photoPath)
r.With(cacheMiddleware, minifier.Middleware).Get(photoPath, handler)
@@ -234,7 +234,7 @@ func buildHandler() (http.Handler, error) {
}
// Search
- if blogConfig.Search.Enabled {
+ if blogConfig.Search != nil && blogConfig.Search.Enabled {
searchPath := blogPath + blogConfig.Search.Path
handler := serveSearch(blog, searchPath)
r.With(cacheMiddleware, minifier.Middleware).Get(searchPath, handler)
@@ -246,6 +246,12 @@ func buildHandler() (http.Handler, error) {
r.With(cacheMiddleware, minifier.Middleware).Get(searchResultPath+paginationPath, resultHandler)
}
+ // Stats
+ if blogConfig.BlogStats != nil && blogConfig.BlogStats.Enabled {
+ statsPath := blogPath + blogConfig.BlogStats.Path
+ r.With(cacheMiddleware, minifier.Middleware).Get(statsPath, serveBlogStats(blog, statsPath))
+ }
+
// Year / month archives
dates, err := allPublishedDates(blog)
if err != nil {
diff --git a/render.go b/render.go
index e0966c4..38ca5fc 100644
--- a/render.go
+++ b/render.go
@@ -33,6 +33,7 @@ const templatePhotosSummary = "photosummary"
const templateEditor = "editor"
const templateLogin = "login"
const templateStaticHome = "statichome"
+const templateBlogStats = "blogstats"
var templates map[string]*template.Template
var templateFunctions template.FuncMap
diff --git a/templates/blogstats.gohtml b/templates/blogstats.gohtml
new file mode 100644
index 0000000..c8e495d
--- /dev/null
+++ b/templates/blogstats.gohtml
@@ -0,0 +1,35 @@
+{{ define "title" }}
+
{{ with .Blog.BlogStats.Title }}{{ . }} - {{ end }}{{ .Blog.Title }}
+{{ end }}
+
+{{ define "main" }}
+
+ {{ with .Blog.BlogStats.Title }}{{ . }}
{{ end }}
+ {{ with .Blog.BlogStats.Description }}{{ md . }}{{ end }}
+
+
+
+ {{ string .Blog.Lang "year" }} |
+ {{ string .Blog.Lang "count" }} |
+
+
+
+ {{ $counts := .Data.counts }}
+ {{ range $i, $year := .Data.years }}
+
+ {{ $year }} |
+ {{ index $counts $i }} |
+
+ {{ end }}
+
+ {{ string .Blog.Lang "total" }} |
+ {{ .Data.total }} |
+
+
+
+
+{{ end }}
+
+{{ define "blogstats" }}
+ {{ template "base" . }}
+{{ end }}
\ No newline at end of file
diff --git a/templates/strings/de.yaml b/templates/strings/de.yaml
index 94841f7..5be2169 100644
--- a/templates/strings/de.yaml
+++ b/templates/strings/de.yaml
@@ -11,4 +11,7 @@ speak: "Lies mir bitte vor."
stopspeak: "Hör auf zu sprechen!"
oldcontent: "⚠️ Dieser Eintrag ist bereits über ein Jahr alt. Er ist möglicherweise nicht mehr aktuell. Meinungen können sich geändert haben."
search: "Suchen"
-shorturl: "Kurz-URL:"
\ No newline at end of file
+shorturl: "Kurz-URL:"
+year: "Jahr"
+count: "Anzahl"
+total: "Gesamt"
\ No newline at end of file
diff --git a/templates/strings/default.yaml b/templates/strings/default.yaml
index 9e1cec1..909979e 100644
--- a/templates/strings/default.yaml
+++ b/templates/strings/default.yaml
@@ -30,4 +30,7 @@ upload: "Upload"
login: "Login"
username: "Username"
password: "Password"
-shorturl: "Short URL:"
\ No newline at end of file
+shorturl: "Short URL:"
+year: "Year"
+count: "Count"
+total: "Total"
\ No newline at end of file