From f300c3d498c99d8b618a8948ce286a8b3e0ae958 Mon Sep 17 00:00:00 2001 From: Jan-Lukas Else Date: Sun, 1 Nov 2020 18:37:21 +0100 Subject: [PATCH] Improve templates and stuff --- activityStreams.go | 1 - config.go | 2 + customPages.go | 5 ++- example-config.yaml | 70 ---------------------------------- feeds.go | 24 ++++++++++++ go.mod | 5 ++- go.sum | 10 +++-- http.go | 44 +++++++++------------ posts.go | 7 ++++ postsDb.go | 24 ++++-------- render.go | 63 ++++++++++++++++++++++++++---- templates/assets/js/speak.js | 45 ++++++++++++++++++++++ templates/author.gohtml | 10 +++++ templates/base.gohtml | 7 +++- templates/footer.gohtml | 12 ++++++ templates/header.gohtml | 10 ++++- templates/menu.gohtml | 11 ------ templates/photosummary.gohtml | 17 ++++----- templates/post.gohtml | 39 +++++++++---------- templates/postactions.gohtml | 8 ++++ templates/postheadmeta.gohtml | 13 +++++++ templates/postmeta.gohtml | 17 +++++++++ templates/posttax.gohtml | 14 +++++++ templates/strings/de.yaml | 11 ++++++ templates/strings/de_DE.yaml | 5 --- templates/strings/default.yaml | 8 +++- templates/summary.gohtml | 6 +-- templates/summarymeta.gohtml | 11 ------ utils.go | 12 ++++++ 29 files changed, 318 insertions(+), 193 deletions(-) delete mode 100644 example-config.yaml create mode 100644 templates/assets/js/speak.js create mode 100644 templates/author.gohtml create mode 100644 templates/footer.gohtml delete mode 100644 templates/menu.gohtml create mode 100644 templates/postactions.gohtml create mode 100644 templates/postheadmeta.gohtml create mode 100644 templates/postmeta.gohtml create mode 100644 templates/posttax.gohtml create mode 100644 templates/strings/de.yaml delete mode 100644 templates/strings/de_DE.yaml delete mode 100644 templates/summarymeta.gohtml diff --git a/activityStreams.go b/activityStreams.go index 43b58f5..96e2479 100644 --- a/activityStreams.go +++ b/activityStreams.go @@ -150,5 +150,4 @@ func (b *configBlog) serveActivityStreams(blog string, w http.ResponseWriter) { } } _ = json.NewEncoder(w).Encode(asBlog) - } diff --git a/config.go b/config.go index 49bca57..cb9b3c2 100644 --- a/config.go +++ b/config.go @@ -44,6 +44,7 @@ type configCache struct { type configBlog struct { Path string `mapstructure:"path"` Lang string `mapstructure:"lang"` + TimeLang string `mapstructure:"timelang"` Title string `mapstructure:"title"` Description string `mapstructure:"description"` Pagination int `mapstructure:"pagination"` @@ -104,6 +105,7 @@ type configUser struct { Name string `mapstructure:"name"` Password string `mapstructure:"password"` Picture string `mapstructure:"picture"` + Link string `mapstructure:"link"` } type configHooks struct { diff --git a/customPages.go b/customPages.go index 4e45207..df35f4a 100644 --- a/customPages.go +++ b/customPages.go @@ -5,8 +5,9 @@ import "net/http" func serveCustomPage(blog *configBlog, page *customPage) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { render(w, page.Template, &renderData{ - Blog: blog, - Data: page.Data, + Blog: blog, + Canonical: appConfig.Server.PublicAddress + page.Path, + Data: page.Data, }) } } diff --git a/example-config.yaml b/example-config.yaml deleted file mode 100644 index 159ff06..0000000 --- a/example-config.yaml +++ /dev/null @@ -1,70 +0,0 @@ -server: - logging: false - debug: false - port: 8080 - domain: example.com - publicAddress: http://localhost:8080 - publicHttps: false - letsEncryptMail: mail@example.com - localHttps: false -database: - file: data/db.sqlite -cache: - enable: true - expiration: 600 -blogs: - main: - path: / - lang: en_US - title: My blog - description: This is my blog - sections: - - name: posts - title: Posts - description: "**Posts** on this blog" - taxonomies: - - name: tags - title: Tags - description: "**Tags** on this blog" - menus: - main: - items: - - title: Home - link: / - - title: Posts - link: /posts - photos: - enable: true - parameter: images - path: /photos - title: Photos - description: "Photos on this blog" - activitystreams: - enable: true - replyParameter: replylink - imagesParameter: images -user: - nick: admin - name: Admin - password: secret -hugo: - frontmatter: - - meta: title - parameter: title - - meta: tags - parameter: tags -micropub: - categoryParam: tags - replyParam: replylink - likeParam: likelink - bookmarkParam: link - audioParam: audio - photoParam: images - photoDescriptionParam: imagealts -pathRedirects: - - from: "\\/index\\.xml" - to: ".rss" - - from: "\\/feed\\.json" - to: ".json" - - from: "\\/(feed|rss)\\/?$" - to: ".rss" \ No newline at end of file diff --git a/feeds.go b/feeds.go index b51deeb..d84f2f9 100644 --- a/feeds.go +++ b/feeds.go @@ -5,6 +5,7 @@ import ( "strings" "time" + "github.com/araddon/dateparse" "github.com/gorilla/feeds" ) @@ -15,6 +16,10 @@ const ( rssFeed feedType = "rss" atomFeed feedType = "atom" jsonFeed feedType = "json" + + feedAudioURL = "audio" + feedAudioType = "audiomime" + feedAudioLength = "audiolength" ) func generateFeed(blog string, f feedType, w http.ResponseWriter, r *http.Request, posts []*post, title string, description string) { @@ -30,14 +35,33 @@ func generateFeed(blog string, f feedType, w http.ResponseWriter, r *http.Reques Description: description, Link: &feeds.Link{Href: appConfig.Server.PublicAddress + strings.TrimSuffix(r.URL.Path, "."+string(f))}, Created: now, + Author: &feeds.Author{ + Name: appConfig.User.Name, + }, + Image: &feeds.Image{ + Url: appConfig.User.Picture, + }, } for _, p := range posts { + created, _ := dateparse.ParseIn(p.Published, time.Local) + updated, _ := dateparse.ParseIn(p.Updated, time.Local) + var enc *feeds.Enclosure + if p.firstParameter(feedAudioURL) != "" { + enc = &feeds.Enclosure{ + Url: p.firstParameter(feedAudioURL), + Type: p.firstParameter(feedAudioType), + Length: p.firstParameter(feedAudioLength), + } + } feed.Add(&feeds.Item{ Title: p.title(), Link: &feeds.Link{Href: appConfig.Server.PublicAddress + p.Path}, Description: p.summary(), Id: p.Path, Content: string(p.html()), + Created: created, + Updated: updated, + Enclosure: enc, }) } var feedStr string diff --git a/go.mod b/go.mod index a25d9bc..abd2c79 100644 --- a/go.mod +++ b/go.mod @@ -36,9 +36,10 @@ require ( github.com/yuin/goldmark v1.2.1 github.com/yuin/goldmark-emoji v1.0.1 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 - golang.org/x/net v0.0.0-20201026091529-146b70c837a4 // indirect + golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 // indirect golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 - golang.org/x/sys v0.0.0-20201026133411-418715ba6fdd // indirect + golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 // indirect + golang.org/x/text v0.3.4 // indirect gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect gopkg.in/ini.v1 v1.62.0 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect diff --git a/go.sum b/go.sum index 2a22108..3797872 100644 --- a/go.sum +++ b/go.sum @@ -342,8 +342,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201026091529-146b70c837a4 h1:awiuzyrRjJDb+OXi9ceHO3SDxVoN3JER57mhtqkdQBs= -golang.org/x/net v0.0.0-20201026091529-146b70c837a4/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -374,14 +374,16 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c h1:UIcGWL6/wpCfyGuJnRFJRurA+yj8RrW7Q6x2YMCXt6c= golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201026133411-418715ba6fdd h1:+7OQgGrJBd80e8ASl94G3xIpokulXXzB/dikfre4ho0= -golang.org/x/sys v0.0.0-20201026133411-418715ba6fdd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 h1:a/mKvvZr9Jcc8oKfcmgzyp7OwF73JPWsQLvH1z2Kxck= +golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/http.go b/http.go index fb468ef..f8cf1b3 100644 --- a/http.go +++ b/http.go @@ -6,7 +6,6 @@ import ( "net/http" "os" "strconv" - "strings" "sync/atomic" "github.com/go-chi/chi" @@ -185,9 +184,10 @@ func buildHandler() (http.Handler, error) { for _, section := range blogConfig.Sections { if section.Name != "" { path := blogPath + "/" + section.Name - r.With(cacheMiddleware, minifier.Middleware).Get(path, serveSection(blog, path, section)) - r.With(cacheMiddleware, minifier.Middleware).Get(path+feedPath, serveSection(blog, path, section)) - r.With(cacheMiddleware, minifier.Middleware).Get(path+paginationPath, serveSection(blog, path, section)) + handler := serveSection(blog, path, section) + r.With(cacheMiddleware, minifier.Middleware).Get(path, handler) + r.With(cacheMiddleware, minifier.Middleware).Get(path+feedPath, handler) + r.With(cacheMiddleware, minifier.Middleware).Get(path+paginationPath, handler) } } @@ -201,17 +201,19 @@ func buildHandler() (http.Handler, error) { } for _, tv := range values { vPath := path + "/" + urlize(tv) - r.With(cacheMiddleware, minifier.Middleware).Get(vPath, serveTaxonomyValue(blog, vPath, taxonomy, tv)) - r.With(cacheMiddleware, minifier.Middleware).Get(vPath+feedPath, serveTaxonomyValue(blog, vPath, taxonomy, tv)) - r.With(cacheMiddleware, minifier.Middleware).Get(vPath+paginationPath, serveTaxonomyValue(blog, vPath, taxonomy, tv)) + handler := serveTaxonomyValue(blog, vPath, taxonomy, tv) + r.With(cacheMiddleware, minifier.Middleware).Get(vPath, handler) + r.With(cacheMiddleware, minifier.Middleware).Get(vPath+feedPath, handler) + r.With(cacheMiddleware, minifier.Middleware).Get(vPath+paginationPath, handler) } } } // Photos if blogConfig.Photos.Enabled { - r.With(cacheMiddleware, minifier.Middleware).Get(blogPath+blogConfig.Photos.Path, servePhotos(blog)) - r.With(cacheMiddleware, minifier.Middleware).Get(blogPath+blogConfig.Photos.Path+paginationPath, servePhotos(blog)) + handler := servePhotos(blog) + r.With(cacheMiddleware, minifier.Middleware).Get(blogPath+blogConfig.Photos.Path, handler) + r.With(cacheMiddleware, minifier.Middleware).Get(blogPath+blogConfig.Photos.Path+paginationPath, handler) } // Blog @@ -221,17 +223,18 @@ func buildHandler() (http.Handler, error) { } else { mw = []func(http.Handler) http.Handler{cacheMiddleware, minifier.Middleware} } - r.With(mw...).Get(fullBlogPath, serveHome(blog, blogPath)) - r.With(cacheMiddleware, minifier.Middleware).Get(fullBlogPath+feedPath, serveHome(blog, blogPath)) - r.With(cacheMiddleware, minifier.Middleware).Get(blogPath+paginationPath, serveHome(blog, blogPath)) + handler := serveHome(blog, blogPath) + r.With(mw...).Get(fullBlogPath, handler) + r.With(cacheMiddleware, minifier.Middleware).Get(fullBlogPath+feedPath, handler) + r.With(cacheMiddleware, minifier.Middleware).Get(blogPath+paginationPath, handler) // Custom pages for _, cp := range blogConfig.CustomPages { - serveFunc := serveCustomPage(blogConfig, cp) + handler := serveCustomPage(blogConfig, cp) if cp.Cache { - r.With(cacheMiddleware, minifier.Middleware).Get(cp.Path, serveFunc) + r.With(cacheMiddleware, minifier.Middleware).Get(cp.Path, handler) } else { - r.With(minifier.Middleware).Get(cp.Path, serveFunc) + r.With(minifier.Middleware).Get(cp.Path, handler) } } } @@ -268,14 +271,3 @@ func (d *dynamicHandler) swapHandler(h http.Handler) { func (d *dynamicHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { d.realHandler.Load().(http.Handler).ServeHTTP(w, r) } - -func slashTrimmedPath(r *http.Request) string { - return trimSlash(r.URL.Path) -} - -func trimSlash(s string) string { - if len(s) > 1 { - s = strings.TrimSuffix(s, "/") - } - return s -} diff --git a/posts.go b/posts.go index 8cd0cf1..e4f3604 100644 --- a/posts.go +++ b/posts.go @@ -46,8 +46,13 @@ func servePost(w http.ResponseWriter, r *http.Request) { p.serveActivityStreams(w) return } + canonical := p.firstParameter("original") + if canonical == "" { + canonical = appConfig.Server.PublicAddress + p.Path + } render(w, templatePost, &renderData{ blogString: p.Blog, + Canonical: canonical, Data: p, }) } @@ -121,6 +126,7 @@ func serveTaxonomy(blog string, tax *taxonomy) func(w http.ResponseWriter, r *ht } render(w, templateTaxonomy, &renderData{ blogString: blog, + Canonical: appConfig.Server.PublicAddress + slashTrimmedPath(r), Data: struct { Taxonomy *taxonomy TaxonomyValues []string @@ -214,6 +220,7 @@ func serveIndex(ic *indexConfig) func(w http.ResponseWriter, r *http.Request) { } render(w, template, &renderData{ blogString: ic.blog, + Canonical: appConfig.Server.PublicAddress + slashTrimmedPath(r), Data: &indexTemplateData{ Title: title, Description: description, diff --git a/postsDb.go b/postsDb.go index 375a663..f8f0978 100644 --- a/postsDb.go +++ b/postsDb.go @@ -66,21 +66,6 @@ func (p *post) checkPost() error { p.Slug = fmt.Sprintf("%v-%02d-%02d-%v", now.Year(), int(now.Month()), now.Day(), random) } published, _ := dateparse.ParseIn(p.Published, time.Local) - pathVars := struct { - BlogPath string - Year int - Month int - Day int - Slug string - Section string - }{ - BlogPath: appConfig.Blogs[p.Blog].Path, - Year: published.Year(), - Month: int(published.Month()), - Day: published.Day(), - Slug: p.Slug, - Section: p.Section, - } pathTmplString := appConfig.Blogs[p.Blog].Sections[p.Section].PathTemplate if pathTmplString == "" { return errors.New("path template empty") @@ -90,7 +75,14 @@ func (p *post) checkPost() error { return errors.New("failed to parse location template") } var pathBuffer bytes.Buffer - err = pathTmpl.Execute(&pathBuffer, pathVars) + err = pathTmpl.Execute(&pathBuffer, map[string]interface{}{ + "BlogPath": appConfig.Blogs[p.Blog].Path, + "Year": published.Year(), + "Month": int(published.Month()), + "Day": published.Day(), + "Slug": p.Slug, + "Section": p.Section, + }) if err != nil { return errors.New("failed to execute location template") } diff --git a/render.go b/render.go index 7069a7a..852a695 100644 --- a/render.go +++ b/render.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "errors" "fmt" "html/template" "io/ioutil" @@ -10,6 +11,7 @@ import ( "os" "path" "path/filepath" + "reflect" "strings" "time" @@ -39,6 +41,9 @@ func initRendering() error { "menu": func(blog *configBlog, id string) *menu { return blog.Menus[id] }, + "user": func() *configUser { + return appConfig.User + }, "md": func(content string) template.HTML { htmlContent, err := renderMarkdown(content) if err != nil { @@ -85,18 +90,61 @@ func initRendering() error { ml := monday.Locale(localeString) return monday.Format(d, monday.LongFormatsByLocale[ml], ml) }, + "now": func() string { + return time.Now().String() + }, "asset": assetFile, "string": getTemplateStringVariant, - "include": func(templateName string, blog *configBlog, data interface{}) (template.HTML, error) { - buf := new(bytes.Buffer) - err := templates[templateName].ExecuteTemplate(buf, templateName, &renderData{ - Blog: blog, - Data: data, - }) - return template.HTML(buf.String()), err + "include": func(templateName string, data ...interface{}) (template.HTML, error) { + if len(data) == 1 { + if rd, ok := data[0].(*renderData); ok { + buf := new(bytes.Buffer) + err := templates[templateName].ExecuteTemplate(buf, templateName, rd) + return template.HTML(buf.String()), err + } + return "", errors.New("wrong argument") + } else if len(data) == 2 { + if blog, ok := data[0].(*configBlog); ok { + buf := new(bytes.Buffer) + err := templates[templateName].ExecuteTemplate(buf, templateName, &renderData{ + Blog: blog, + Data: data[1], + }) + return template.HTML(buf.String()), err + } + return "", errors.New("wrong arguments") + } + return "", errors.New("wrong argument count") + }, + "default": func(dflt interface{}, given ...interface{}) interface{} { + if len(given) == 0 { + return dflt + } + g := reflect.ValueOf(given[0]) + if !g.IsValid() { + return dflt + } + set := false + switch g.Kind() { + case reflect.Bool: + set = true + case reflect.String, reflect.Array, reflect.Slice, reflect.Map: + set = g.Len() != 0 + case reflect.Int: + set = g.Int() != 0 + default: + set = !g.IsNil() + } + if set { + return given[0] + } + return dflt }, "urlize": urlize, "sort": sortedStrings, + "absolute": func(path string) string { + return appConfig.Server.PublicAddress + path + }, "blogRelative": func(blog *configBlog, path string) string { return blog.getRelativePath(path) }, @@ -138,6 +186,7 @@ func initRendering() error { type renderData struct { blogString string + Canonical string Blog *configBlog Data interface{} } diff --git a/templates/assets/js/speak.js b/templates/assets/js/speak.js new file mode 100644 index 0000000..18f0911 --- /dev/null +++ b/templates/assets/js/speak.js @@ -0,0 +1,45 @@ +"use strict"; + +function getVoice() { + if (window.speechSynthesis) { + return window.speechSynthesis.getVoices().filter(voice => voice.lang.startsWith(document.querySelector('html').lang))[0]; + } + return false; +} + +function initSpeak() { + if (window.speechSynthesis) { + let speakBtn = document.querySelector('#speakBtn'); + speakBtn.style.display = ''; + speakBtn.onclick = function() { speak() }; + speakBtn.textContent = speakText; + } +} + +function speak() { + console.log("Start speaking") + let speakBtn = document.querySelector('#speakBtn'); + speakBtn.onclick = function() { stopSpeak() }; + speakBtn.textContent = stopSpeakText; + let textContent = + ((document.querySelector('article .p-name')) ? document.querySelector('article .p-name').innerText + "\n\n" : "") + + document.querySelector('article .e-content').innerText; + let utterThis = new SpeechSynthesisUtterance(textContent); + utterThis.voice = getVoice(); + utterThis.onerror = stopSpeak; + utterThis.onend = stopSpeak; + window.speechSynthesis.speak(utterThis); +} + +function stopSpeak() { + console.log("Stop speaking") + window.speechSynthesis.cancel(); + let speakBtn = document.querySelector('#speakBtn'); + speakBtn.onclick = function() { speak() }; + speakBtn.textContent = speakText; +} + +window.onbeforeunload = function () { + stopSpeak(); +} +initSpeak(); \ No newline at end of file diff --git a/templates/author.gohtml b/templates/author.gohtml new file mode 100644 index 0000000..e5cfa06 --- /dev/null +++ b/templates/author.gohtml @@ -0,0 +1,10 @@ +{{ define "author" }} + {{ with user }} +
+ {{ with .Picture }}{{ end }} + {{ if .Name }} + {{ .Name }} + {{ end }} +
+ {{ end }} +{{ end }} \ No newline at end of file diff --git a/templates/base.gohtml b/templates/base.gohtml index d8ee40b..e7ae1f0 100644 --- a/templates/base.gohtml +++ b/templates/base.gohtml @@ -5,8 +5,11 @@ + {{ with user.Picture }}{{ end }} + {{ with .Canonical }}{{ end }} {{ template "title" . }} - {{ include "micropub" .Blog .Data }} - {{ include "header" .Blog .Data }} + {{ include "micropub" . }} + {{ include "header" . }} {{ template "main" . }} + {{ include "footer" . }} {{ end }} \ No newline at end of file diff --git a/templates/footer.gohtml b/templates/footer.gohtml new file mode 100644 index 0000000..24b4f85 --- /dev/null +++ b/templates/footer.gohtml @@ -0,0 +1,12 @@ +{{ define "footer" }} + +{{ end }} \ No newline at end of file diff --git a/templates/header.gohtml b/templates/header.gohtml index c100edb..2a1e1b4 100644 --- a/templates/header.gohtml +++ b/templates/header.gohtml @@ -2,6 +2,14 @@

{{ .Blog.Title }}

{{ with .Blog.Description }}

{{ . }}

{{ end }} - {{ include "menu" .Blog .Data }} +
{{ end }} \ No newline at end of file diff --git a/templates/menu.gohtml b/templates/menu.gohtml deleted file mode 100644 index bd599f3..0000000 --- a/templates/menu.gohtml +++ /dev/null @@ -1,11 +0,0 @@ -{{ define "menu" }} - -{{ end }} \ No newline at end of file diff --git a/templates/photosummary.gohtml b/templates/photosummary.gohtml index 7c2f81a..6efa673 100644 --- a/templates/photosummary.gohtml +++ b/templates/photosummary.gohtml @@ -1,12 +1,11 @@ {{ define "photosummary" }} -
- {{ with p .Data "title" }}

{{ . }}

{{ end }} - {{ if .Data.Published }}

{{ longDate .Data.Published .Blog.Lang }}

{{ end }} - {{ range $i, $photo := ( ps .Data .Blog.Photos.Parameter ) }} - {{ md ( printf "![](%s)" $photo ) }} - {{ end }} -

{{ summary .Data }}

- {{ string .Blog.Lang "view" }} +
+ {{ with p .Data "title" }}

{{ . }}

{{ end }} + {{ include "postmeta" . }} + {{ range $i, $photo := ( ps .Data .Blog.Photos.Parameter ) }} + {{ md ( printf "![](%s)" $photo ) }} + {{ end }} +

{{ summary .Data }}

+

{{ if (hasp .Data "images") }}🖼️ {{ end }}{{ string .Blog.Lang "view" }}

-
{{ end }} \ No newline at end of file diff --git a/templates/post.gohtml b/templates/post.gohtml index 38b2658..e3cf916 100644 --- a/templates/post.gohtml +++ b/templates/post.gohtml @@ -1,34 +1,29 @@ {{ define "title" }} {{ with p .Data "title" }}{{ . }} - {{end}}{{ .Blog.Title }} + {{ include "postheadmeta" . }} {{ end }} {{ define "main" }}
- {{ with title .Data }}

{{ . }}

{{ end }} - {{ if .Data.Published }} -

{{ string .Blog.Lang "publishedon" }} {{ longDate .Data.Published .Blog.Lang }}

{{ end }} - {{ if .Data.Updated }} -

{{ string .Blog.Lang "updatedon" }} {{ longDate .Data.Updated .Blog.Lang }}

{{ end }} - {{ if .Data.Content }} -
{{ content .Data }}
- {{ end }} -
- {{ $post := .Data }} - {{ $blog := .Blog }} - {{ range $i, $tax := $blog.Taxonomies }} - {{ $tvs := ps $post $tax.Name }} - {{ if gt (len $tvs) 0 }} -

In {{ $tax.Title }}: - {{ range $j, $tv := $tvs }} - {{ $tv }} - {{ end }} -

+ + {{ with title .Data }}

{{ . }}

{{ end }} + {{ include "postmeta" . }} + {{ include "postactions" . }} + {{ if .Data.Content }} +
+ {{ with p .Data "audio" }} + {{ end }} + {{ content .Data }} + {{ with p .Data "link" }} +

{{ . }}

+ {{ end }} +
{{ end }} - {{ range $i, $t := (translations .Data) }} -

{{ (blog $t.Blog).Title }}

- {{ end }} + {{ include "posttax" . }} +
+ {{ include "author" . }} {{ end }} diff --git a/templates/postactions.gohtml b/templates/postactions.gohtml new file mode 100644 index 0000000..a9511d5 --- /dev/null +++ b/templates/postactions.gohtml @@ -0,0 +1,8 @@ +{{ define "postactions" }} +
+ {{ string .Blog.Lang "share" }}  + + + +
+{{ end }} \ No newline at end of file diff --git a/templates/postheadmeta.gohtml b/templates/postheadmeta.gohtml new file mode 100644 index 0000000..376fe08 --- /dev/null +++ b/templates/postheadmeta.gohtml @@ -0,0 +1,13 @@ +{{ define "postheadmeta" }} + + {{ $ISO8601 := "2006-01-02T15:04:05-07:00" }} + {{ if .Data.Published }} + + {{ end }} + {{ if .Data.Updated }} + + {{ end }} + {{ range $key, $image := ps .Data "images" }} + + {{ end }} +{{ end }} \ No newline at end of file diff --git a/templates/postmeta.gohtml b/templates/postmeta.gohtml new file mode 100644 index 0000000..9770349 --- /dev/null +++ b/templates/postmeta.gohtml @@ -0,0 +1,17 @@ +{{ define "postmeta" }} +
+ {{ $section := (index .Blog.Sections .Data.Section) }} + {{ if .Data.Published }}
{{ string .Blog.Lang "publishedon" }} {{ if $section }} in {{ $section.Title }}{{ end }}
{{ end }} + {{ if .Data.Updated }}
{{ string .Blog.Lang "updatedon" }}
{{ end }} + {{ if p .Data "replylink" }} +
{{ string .Blog.Lang "replyto" }}: {{ p .Data "replytitle" | default (p .Data "replylink") }}
+ {{ end }} + {{ if p .Data "likelink" }} +
{{ string .Blog.Lang "likeof" }}: {{ p .Data "liketitle" | default (p .Data "likelink") }}
+ {{ end }} + {{ $translations := (translations .Data) }} + {{ if gt (len $translations) 0 }} +
{{ string .Blog.Lang "translations" }}: {{ $delimiter := "" }}{{ range $i, $t := $translations }}{{ $delimiter }}{{ title $t }}{{ $delimiter = ", " }}{{ end }}
+ {{ end }} +
+{{ end }} \ No newline at end of file diff --git a/templates/posttax.gohtml b/templates/posttax.gohtml new file mode 100644 index 0000000..ed1917c --- /dev/null +++ b/templates/posttax.gohtml @@ -0,0 +1,14 @@ +{{ define "posttax" }} + {{ $post := .Data }} + {{ $blog := .Blog }} + {{ range $i, $tax := $blog.Taxonomies }} + {{ $tvs := ps $post $tax.Name }} + {{ if gt (len $tvs) 0 }} +

{{ $tax.Title }}: + {{ range $j, $tv := $tvs }} + + {{ end }} +

+ {{ end }} + {{ end }} +{{ end }} \ No newline at end of file diff --git a/templates/strings/de.yaml b/templates/strings/de.yaml new file mode 100644 index 0000000..fcbd9e1 --- /dev/null +++ b/templates/strings/de.yaml @@ -0,0 +1,11 @@ +publishedon: "Veröffentlicht am" +updatedon: "Aktualisiert am" +next: "Weiter" +prev: "Zurück" +view: "Anschauen" +replyto: "Antwort an" +likeof: "Gefällt mir von" +translations: "Übersetzungen" +share: "Teilen" +speak: "Lies mir bitte vor." +stopspeak: "Hör auf zu sprechen!" \ No newline at end of file diff --git a/templates/strings/de_DE.yaml b/templates/strings/de_DE.yaml deleted file mode 100644 index 097df98..0000000 --- a/templates/strings/de_DE.yaml +++ /dev/null @@ -1,5 +0,0 @@ -publishedon: "Veröffentlicht am" -updatedon: "Aktualisiert am" -next: "Weiter" -prev: "Zurück" -view: "Anschauen" \ No newline at end of file diff --git a/templates/strings/default.yaml b/templates/strings/default.yaml index bb50490..532c577 100644 --- a/templates/strings/default.yaml +++ b/templates/strings/default.yaml @@ -5,4 +5,10 @@ prev: "Previous" view: "View" authenticate: "Authenticate" scopes: "Scopes" -indieauth: "IndieAuth" \ No newline at end of file +indieauth: "IndieAuth" +replyto: "Reply to" +likeof: "Like of" +translations: "Translations" +share: "Share" +speak: "Read to me, please." +stopspeak: "Stop speaking!" \ No newline at end of file diff --git a/templates/summary.gohtml b/templates/summary.gohtml index ffa19b0..ca8087e 100644 --- a/templates/summary.gohtml +++ b/templates/summary.gohtml @@ -1,13 +1,13 @@ {{ define "summary" }}
- {{ if p .Data "title" }} + {{ if p .Data "title" }}

{{ p .Data "title" }}

- {{ end }} - {{ include "summarymeta" .Blog .Data }} + {{ end }} + {{ include "postmeta" . }}

{{ summary .Data }}

{{ if (hasp .Data "images") }}🖼️ {{ end }}{{ string .Blog.Lang "view" }}

diff --git a/templates/summarymeta.gohtml b/templates/summarymeta.gohtml deleted file mode 100644 index af560b8..0000000 --- a/templates/summarymeta.gohtml +++ /dev/null @@ -1,11 +0,0 @@ -{{ define "summarymeta" }} -
- {{ $section := (index .Blog.Sections .Data.Section) }} - {{ if .Data.Published }} -
{{ if $section }} in {{ $section.Title }}{{ end }}
- {{ end }} - {{ if .Data.Updated }} -
{{ string .Blog.Lang "updatedon" }}
- {{ end }} -
-{{ end }} \ No newline at end of file diff --git a/utils.go b/utils.go index 5f64218..850279b 100644 --- a/utils.go +++ b/utils.go @@ -2,6 +2,7 @@ package main import ( "math/rand" + "net/http" "sort" "strings" "time" @@ -35,3 +36,14 @@ func generateRandomString(chars int) string { } return string(b) } + +func slashTrimmedPath(r *http.Request) string { + return trimSlash(r.URL.Path) +} + +func trimSlash(s string) string { + if len(s) > 1 { + s = strings.TrimSuffix(s, "/") + } + return s +}