diff --git a/blogroll.go b/blogroll.go
index 430dcc7..bb9fde4 100644
--- a/blogroll.go
+++ b/blogroll.go
@@ -3,6 +3,7 @@ package main
import (
"fmt"
"io"
+ "log"
"net/http"
"sort"
"strings"
@@ -26,7 +27,8 @@ func serveBlogroll(w http.ResponseWriter, r *http.Request) {
return getBlogrollOutlines(c)
})
if err != nil {
- serveError(w, r, err.Error(), http.StatusInternalServerError)
+ log.Println("Failed to get outlines:", err.Error())
+ serveError(w, r, "", http.StatusInternalServerError)
return
}
if appConfig.Cache != nil && appConfig.Cache.Enable {
@@ -54,7 +56,8 @@ func serveBlogrollExport(w http.ResponseWriter, r *http.Request) {
return getBlogrollOutlines(c)
})
if err != nil {
- serveError(w, r, err.Error(), http.StatusInternalServerError)
+ log.Println("Failed to get outlines:", err.Error())
+ serveError(w, r, "", http.StatusInternalServerError)
return
}
if appConfig.Cache != nil && appConfig.Cache.Enable {
diff --git a/blogstats.go b/blogstats.go
index 6507f37..e610c22 100644
--- a/blogstats.go
+++ b/blogstats.go
@@ -8,6 +8,18 @@ import (
)
func serveBlogStats(w http.ResponseWriter, r *http.Request) {
+ blog := r.Context().Value(blogContextKey).(string)
+ canonical := blogPath(blog) + appConfig.Blogs[blog].BlogStats.Path
+ render(w, r, templateBlogStats, &renderData{
+ BlogString: blog,
+ Canonical: canonical,
+ Data: map[string]interface{}{
+ "TableUrl": canonical + ".table.html",
+ },
+ })
+}
+
+func serveBlogStatsTable(w http.ResponseWriter, r *http.Request) {
blog := r.Context().Value(blogContextKey).(string)
// Start timing
t := servertiming.FromContext(r.Context()).NewMetric("sq").Start()
@@ -17,6 +29,7 @@ func serveBlogStats(w http.ResponseWriter, r *http.Request) {
status: statusPublished,
}
query, params := buildPostsQuery(prq)
+ query = "select path, mdtext(content) as content, published, substr(published, 1, 4) as year, substr(published, 6, 2) as month from (" + query + ")"
postCount := "coalesce(count(distinct path), 0) as postcount"
charCount := "coalesce(sum(coalesce(length(distinct content), 0)), 0)"
wordCount := "coalesce(sum(wordcount(distinct content)), 0) as wordcount"
@@ -36,7 +49,7 @@ func serveBlogStats(w http.ResponseWriter, r *http.Request) {
return
}
// Count posts per year
- rows, err := appDbQuery("select *, "+wordsPerPost+" from (select substr(published, 1, 4) as year, "+postCount+", "+charCount+", "+wordCount+" from ("+query+") where published != '' group by year order by year desc)", params...)
+ rows, err := appDbQuery("select *, "+wordsPerPost+" from (select year, "+postCount+", "+charCount+", "+wordCount+" from ("+query+") where published != '' group by year order by year desc)", params...)
if err != nil {
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
@@ -66,7 +79,7 @@ func serveBlogStats(w http.ResponseWriter, r *http.Request) {
months := map[string][]statsTableType{}
month := statsTableType{}
for _, year := range years {
- rows, err = appDbQuery("select *, "+wordsPerPost+" from (select substr(published, 6, 2) as month, "+postCount+", "+charCount+", "+wordCount+" from ("+query+") where published != '' and substr(published, 1, 4) = @year group by month order by month desc)", append(params, sql.Named("year", year.Name))...)
+ rows, err = appDbQuery("select *, "+wordsPerPost+" from (select month, "+postCount+", "+charCount+", "+wordCount+" from ("+query+") where published != '' and year = @year group by month order by month desc)", append(params, sql.Named("year", year.Name))...)
if err != nil {
serveError(w, r, err.Error(), http.StatusInternalServerError)
return
@@ -83,9 +96,8 @@ func serveBlogStats(w http.ResponseWriter, r *http.Request) {
// Stop timing
t.Stop()
// Render
- render(w, r, templateBlogStats, &renderData{
+ render(w, r, templateBlogStatsTable, &renderData{
BlogString: blog,
- Canonical: blogPath(blog) + appConfig.Blogs[blog].BlogStats.Path,
Data: map[string]interface{}{
"total": total,
"years": years,
diff --git a/database.go b/database.go
index b485474..0a28b89 100644
--- a/database.go
+++ b/database.go
@@ -25,6 +25,9 @@ func initDatabase() (err error) {
if err := c.RegisterFunc("wordcount", wordCount, true); err != nil {
return err
}
+ if err := c.RegisterFunc("mdtext", renderText, true); err != nil {
+ return err
+ }
return nil
},
})
diff --git a/http.go b/http.go
index 5ebb74d..5071ff5 100644
--- a/http.go
+++ b/http.go
@@ -478,7 +478,12 @@ func buildDynamicRouter() (*chi.Mux, error) {
// Stats
if blogConfig.BlogStats != nil && blogConfig.BlogStats.Enabled {
statsPath := blogPath + blogConfig.BlogStats.Path
- r.With(privateModeHandler...).With(cacheMiddleware, sbm).Get(statsPath, serveBlogStats)
+ r.Group(func(r chi.Router) {
+ r.Use(privateModeHandler...)
+ r.Use(cacheMiddleware, sbm)
+ r.Get(statsPath, serveBlogStats)
+ r.Get(statsPath+".table.html", serveBlogStatsTable)
+ })
}
// Date archives
diff --git a/markdown.go b/markdown.go
index 1af3737..a45eb2c 100644
--- a/markdown.go
+++ b/markdown.go
@@ -4,6 +4,7 @@ import (
"bytes"
"strings"
+ "github.com/PuerkitoBio/goquery"
kemoji "github.com/kyokomi/emoji/v2"
"github.com/yuin/goldmark"
emoji "github.com/yuin/goldmark-emoji"
@@ -54,6 +55,18 @@ func renderMarkdown(source string, absoluteLinks bool) (rendered []byte, err err
return buffer.Bytes(), err
}
+func renderText(s string) string {
+ h, err := renderMarkdown(s, false)
+ if err != nil {
+ return ""
+ }
+ d, err := goquery.NewDocumentFromReader(bytes.NewReader(h))
+ if err != nil {
+ return ""
+ }
+ return d.Text()
+}
+
// Extensions etc...
// All emojis from emoji lib
diff --git a/render.go b/render.go
index 84409aa..b809dd1 100644
--- a/render.go
+++ b/render.go
@@ -35,6 +35,7 @@ const (
templateLogin = "login"
templateStaticHome = "statichome"
templateBlogStats = "blogstats"
+ templateBlogStatsTable = "blogstatstable"
templateComment = "comment"
templateCaptcha = "captcha"
templateCommentsAdmin = "commentsadmin"
diff --git a/templates/assets/js/blogstats.js b/templates/assets/js/blogstats.js
index 5f4e37e..40aea99 100644
--- a/templates/assets/js/blogstats.js
+++ b/templates/assets/js/blogstats.js
@@ -1,11 +1,22 @@
(function () {
- Array.from(document.getElementsByClassName('statsyear')).forEach(element => {
- element.addEventListener('click', function () {
- Array.from(document.getElementsByClassName('statsmonth')).forEach(c => {
- if (element.dataset.year == c.dataset.year) {
- c.classList.contains('hide') ? c.classList.remove('hide') : c.classList.add('hide')
- }
+ let loadingEl = document.getElementById('loading')
+ let tableUrl = loadingEl.dataset.table
+
+ let tableReq = new XMLHttpRequest()
+ tableReq.open('GET', tableUrl)
+ tableReq.onload = function() {
+ if (tableReq.status == 200) {
+ loadingEl.outerHTML = tableReq.responseText
+ Array.from(document.getElementsByClassName('statsyear')).forEach(element => {
+ element.addEventListener('click', function () {
+ Array.from(document.getElementsByClassName('statsmonth')).forEach(c => {
+ if (element.dataset.year == c.dataset.year) {
+ c.classList.contains('hide') ? c.classList.remove('hide') : c.classList.add('hide')
+ }
+ })
+ })
})
- })
- })
+ }
+ }
+ tableReq.send()
})()
\ No newline at end of file
diff --git a/templates/blogstats.gohtml b/templates/blogstats.gohtml
index c94f2da..febbe74 100644
--- a/templates/blogstats.gohtml
+++ b/templates/blogstats.gohtml
@@ -6,52 +6,7 @@
{{ with .Blog.BlogStats.Title }}{{ . }}
{{ end }}
{{ with .Blog.BlogStats.Description }}{{ md . }}{{ end }}
-
-
-
- {{ string .Blog.Lang "year" }} |
- {{ string .Blog.Lang "posts" }} |
- ~{{ string .Blog.Lang "chars" }} |
- ~{{ string .Blog.Lang "words" }} |
- ~{{ string .Blog.Lang "wordsperpost" }} |
-
-
-
- {{ $months := .Data.months }}
- {{ range $year := .Data.years }}
-
- {{ $year.Name }} |
- {{ $year.Posts }} |
- {{ $year.Chars }} |
- {{ $year.Words }} |
- {{ $year.WordsPerPost }} |
-
- {{ range $month := (index $months $year.Name) }}
-
- {{ $year.Name }}-{{ $month.Name }} |
- {{ $month.Posts }} |
- {{ $month.Chars }} |
- {{ $month.Words }} |
- {{ $month.WordsPerPost }} |
-
- {{ end }}
- {{ end }}
-
- {{ string .Blog.Lang "withoutdate" }} |
- {{ .Data.withoutdate.Posts }} |
- {{ .Data.withoutdate.Chars }} |
- {{ .Data.withoutdate.Words }} |
- {{ .Data.withoutdate.WordsPerPost }} |
-
-
- {{ string .Blog.Lang "total" }} |
- {{ .Data.total.Posts }} |
- {{ .Data.total.Chars }} |
- {{ .Data.total.Words }} |
- {{ .Data.total.WordsPerPost }} |
-
-
-
+ {{ string .Blog.Lang "loading" }}
{{ end }}
diff --git a/templates/blogstatstable.gohtml b/templates/blogstatstable.gohtml
new file mode 100644
index 0000000..d5755bd
--- /dev/null
+++ b/templates/blogstatstable.gohtml
@@ -0,0 +1,48 @@
+{{ define "blogstatstable" }}
+
+
+
+ {{ string .Blog.Lang "year" }} |
+ {{ string .Blog.Lang "posts" }} |
+ ~{{ string .Blog.Lang "chars" }} |
+ ~{{ string .Blog.Lang "words" }} |
+ ~{{ string .Blog.Lang "wordsperpost" }} |
+
+
+
+ {{ $months := .Data.months }}
+ {{ range $year := .Data.years }}
+
+ {{ $year.Name }} |
+ {{ $year.Posts }} |
+ {{ $year.Chars }} |
+ {{ $year.Words }} |
+ {{ $year.WordsPerPost }} |
+
+ {{ range $month := (index $months $year.Name) }}
+
+ {{ $year.Name }}-{{ $month.Name }} |
+ {{ $month.Posts }} |
+ {{ $month.Chars }} |
+ {{ $month.Words }} |
+ {{ $month.WordsPerPost }} |
+
+ {{ end }}
+ {{ end }}
+
+ {{ string .Blog.Lang "withoutdate" }} |
+ {{ .Data.withoutdate.Posts }} |
+ {{ .Data.withoutdate.Chars }} |
+ {{ .Data.withoutdate.Words }} |
+ {{ .Data.withoutdate.WordsPerPost }} |
+
+
+ {{ string .Blog.Lang "total" }} |
+ {{ .Data.total.Posts }} |
+ {{ .Data.total.Chars }} |
+ {{ .Data.total.Words }} |
+ {{ .Data.total.WordsPerPost }} |
+
+
+
+{{ end }}
\ No newline at end of file
diff --git a/templates/strings/de.yaml b/templates/strings/de.yaml
index bd2cd8e..bdb1be7 100644
--- a/templates/strings/de.yaml
+++ b/templates/strings/de.yaml
@@ -12,6 +12,7 @@ editor: "Editor"
interactions: "Interaktionen & Kommentare"
interactionslabel: "Hast du eine Antwort hierzu veröffentlicht? Füge hier die URL ein."
likeof: "Gefällt mir von"
+loading: "Laden..."
next: "Weiter"
noposts: "Hier sind keine Posts."
oldcontent: "⚠️ Dieser Eintrag ist bereits über ein Jahr alt. Er ist möglicherweise nicht mehr aktuell. Meinungen können sich geändert haben."
diff --git a/templates/strings/default.yaml b/templates/strings/default.yaml
index 8edc2be..ae8b73a 100644
--- a/templates/strings/default.yaml
+++ b/templates/strings/default.yaml
@@ -19,6 +19,7 @@ indieauth: "IndieAuth"
interactions: "Interactions & Comments"
interactionslabel: "Have you published a response to this? Paste the URL here."
likeof: "Like of"
+loading: "Loading..."
login: "Login"
logout: "Logout"
nameopt: "Name (optional)"