diff --git a/activityStreams.go b/activityStreams.go index 311ee7a..899a466 100644 --- a/activityStreams.go +++ b/activityStreams.go @@ -106,7 +106,7 @@ func (a *goBlog) toASNote(p *post) *asNote { AttributedTo: a.apIri(a.cfg.Blogs[p.Blog]), } // Name and Type - if title := a.renderMdTitle(p.Title()); title != "" { + if title := p.RenderedTitle; title != "" { as.Name = title as.Type = "Article" } else { diff --git a/check.go b/check.go index f0096c4..942b291 100644 --- a/check.go +++ b/check.go @@ -17,7 +17,7 @@ import ( func (a *goBlog) checkAllExternalLinks() { // Get all published posts without parameters - posts, err := a.db.getPosts(&postsRequestConfig{status: statusPublished, withoutParameters: true}) + posts, err := a.getPosts(&postsRequestConfig{status: statusPublished, withoutParameters: true}) if err != nil { log.Println(err.Error()) return diff --git a/editor.go b/editor.go index 24c3302..e6fb794 100644 --- a/editor.go +++ b/editor.go @@ -41,7 +41,7 @@ func (a *goBlog) serveEditorPost(w http.ResponseWriter, r *http.Request) { a.serveError(w, r, err.Error(), http.StatusBadRequest) return } - post, err := a.db.getPost(parsedURL.Path) + post, err := a.getPost(parsedURL.Path) if err != nil { a.serveError(w, r, err.Error(), http.StatusBadRequest) return diff --git a/feeds.go b/feeds.go index 297445a..dcc7785 100644 --- a/feeds.go +++ b/feeds.go @@ -42,7 +42,7 @@ func (a *goBlog) generateFeed(blog string, f feedType, w http.ResponseWriter, r } for _, p := range posts { feed.Add(&feeds.Item{ - Title: a.renderMdTitle(p.Title()), + Title: p.RenderedTitle, Link: &feeds.Link{Href: a.fullPostURL(p)}, Description: a.postSummary(p), Id: p.Path, diff --git a/geoMap.go b/geoMap.go index fd584d5..a7ed2da 100644 --- a/geoMap.go +++ b/geoMap.go @@ -20,7 +20,7 @@ func (a *goBlog) serveGeoMap(w http.ResponseWriter, r *http.Request) { blog := r.Context().Value(blogKey).(string) bc := a.cfg.Blogs[blog] - allPostsWithLocation, err := a.db.getPosts(&postsRequestConfig{ + allPostsWithLocation, err := a.getPosts(&postsRequestConfig{ blog: blog, status: statusPublished, parameter: a.cfg.Micropub.LocationParam, diff --git a/markdown.go b/markdown.go index a7c4c90..ffcc927 100644 --- a/markdown.go +++ b/markdown.go @@ -33,30 +33,28 @@ func (a *goBlog) initMarkdown() { emoji.Emoji, ), } + publicAddress := "" + if srv := a.cfg.Server; srv != nil { + publicAddress = srv.PublicAddress + } a.md = goldmark.New(append(defaultGoldmarkOptions, goldmark.WithExtensions(&customExtension{ absoluteLinks: false, - publicAddress: a.cfg.Server.PublicAddress, + publicAddress: publicAddress, }))...) a.absoluteMd = goldmark.New(append(defaultGoldmarkOptions, goldmark.WithExtensions(&customExtension{ absoluteLinks: true, - publicAddress: a.cfg.Server.PublicAddress, + publicAddress: publicAddress, }))...) a.titleMd = goldmark.New( goldmark.WithParser( // Override, no need for special Markdown parsers parser.NewParser( parser.WithBlockParsers( - util.Prioritized(parser.NewHTMLBlockParser(), 900), util.Prioritized(parser.NewParagraphParser(), 1000)), - parser.WithInlineParsers( - util.Prioritized(parser.NewRawHTMLParser(), 400), - ), + parser.WithInlineParsers(), parser.WithParagraphTransformers(), ), ), - goldmark.WithRendererOptions( - html.WithUnsafe(), - ), goldmark.WithExtensions( extension.Typographer, emoji.Emoji, diff --git a/markdown_test.go b/markdown_test.go index 9b737df..a5588b1 100644 --- a/markdown_test.go +++ b/markdown_test.go @@ -73,6 +73,7 @@ func Test_markdown(t *testing.T) { assert.Equal(t, "3. **Test**", app.renderMdTitle("3. **Test**")) assert.Equal(t, "Test’s", app.renderMdTitle("Test's")) assert.Equal(t, "πŸ˜‚", app.renderMdTitle(":joy:")) + assert.Equal(t, "", app.renderMdTitle("")) // Template func diff --git a/micropub.go b/micropub.go index c3c17f0..ac46e38 100644 --- a/micropub.go +++ b/micropub.go @@ -40,7 +40,7 @@ func (a *goBlog) serveMicropubQuery(w http.ResponseWriter, r *http.Request) { a.serveError(w, r, err.Error(), http.StatusBadRequest) return } - p, err := a.db.getPost(u.Path) + p, err := a.getPost(u.Path) if err != nil { a.serveError(w, r, err.Error(), http.StatusBadRequest) return @@ -49,7 +49,7 @@ func (a *goBlog) serveMicropubQuery(w http.ResponseWriter, r *http.Request) { } else { limit, _ := strconv.Atoi(r.URL.Query().Get("limit")) offset, _ := strconv.Atoi(r.URL.Query().Get("offset")) - posts, err := a.db.getPosts(&postsRequestConfig{ + posts, err := a.getPosts(&postsRequestConfig{ limit: limit, offset: offset, }) @@ -473,7 +473,7 @@ func (a *goBlog) micropubUpdate(w http.ResponseWriter, r *http.Request, u string a.serveError(w, r, err.Error(), http.StatusBadRequest) return } - p, err := a.db.getPost(uu.Path) + p, err := a.getPost(uu.Path) if err != nil { a.serveError(w, r, err.Error(), http.StatusBadRequest) return diff --git a/posts.go b/posts.go index 7a0736f..0a8b7e1 100644 --- a/posts.go +++ b/posts.go @@ -29,9 +29,10 @@ type post struct { Status postStatus Priority int // Not persisted - Slug string - renderCache map[bool]template.HTML - renderMutex sync.RWMutex + Slug string + RenderedTitle string + renderCache map[bool]template.HTML + renderMutex sync.RWMutex } type postStatus string @@ -45,7 +46,7 @@ const ( ) func (a *goBlog) servePost(w http.ResponseWriter, r *http.Request) { - p, err := a.db.getPost(r.URL.Path) + p, err := a.getPost(r.URL.Path) if err == errPostNotFound { a.serve404(w, r) return @@ -89,12 +90,12 @@ func (a *goBlog) redirectToRandomPost(rw http.ResponseWriter, r *http.Request) { type postPaginationAdapter struct { config *postsRequestConfig nums int64 - db *database + a *goBlog } func (p *postPaginationAdapter) Nums() (int64, error) { if p.nums == 0 { - nums, _ := p.db.countPosts(p.config) + nums, _ := p.a.db.countPosts(p.config) p.nums = int64(nums) } return p.nums, nil @@ -105,7 +106,7 @@ func (p *postPaginationAdapter) Slice(offset, length int, data interface{}) erro modifiedConfig.offset = offset modifiedConfig.limit = length - posts, err := p.db.getPosts(&modifiedConfig) + posts, err := p.a.getPosts(&modifiedConfig) reflect.ValueOf(data).Elem().Set(reflect.ValueOf(&posts).Elem()) return err } @@ -247,7 +248,7 @@ func (a *goBlog) serveIndex(w http.ResponseWriter, r *http.Request) { publishedDay: ic.day, status: status, priorityOrder: true, - }, db: a.db}, a.cfg.Blogs[blog].Pagination) + }, a: a}, a.cfg.Blogs[blog].Pagination) p.SetPage(pageNo) var posts []*post err := p.Results(&posts) diff --git a/postsDb.go b/postsDb.go index 2263e2f..2be9d9d 100644 --- a/postsDb.go +++ b/postsDb.go @@ -190,7 +190,7 @@ func (db *database) savePost(p *post, o *postCreationOptions) error { } func (a *goBlog) deletePost(path string) error { - p, err := a.db.deletePost(path) + p, err := a.deletePostFromDb(path) if err != nil || p == nil { return err } @@ -201,17 +201,17 @@ func (a *goBlog) deletePost(path string) error { return nil } -func (db *database) deletePost(path string) (*post, error) { +func (a *goBlog) deletePostFromDb(path string) (*post, error) { if path == "" { return nil, nil } - db.pcm.Lock() - defer db.pcm.Unlock() - p, err := db.getPost(path) + a.db.pcm.Lock() + defer a.db.pcm.Unlock() + p, err := a.getPost(path) if err != nil { return nil, err } - _, err = db.exec( + _, err = a.db.exec( `begin; delete from posts where path = ?; delete from post_parameters where path = ?; @@ -222,7 +222,7 @@ func (db *database) deletePost(path string) (*post, error) { if err != nil { return nil, err } - db.rebuildFTSIndex() + a.db.rebuildFTSIndex() return p, nil } @@ -389,10 +389,10 @@ func (d *database) loadPostParameters(posts []*post, parameters ...string) (err return nil } -func (d *database) getPosts(config *postsRequestConfig) (posts []*post, err error) { +func (a *goBlog) getPosts(config *postsRequestConfig) (posts []*post, err error) { // Query posts query, queryParams := buildPostsQuery(config, "path, coalesce(content, ''), coalesce(published, ''), coalesce(updated, ''), blog, coalesce(section, ''), status, priority") - rows, err := d.query(query, queryParams...) + rows, err := a.db.query(query, queryParams...) if err != nil { return nil, err } @@ -417,16 +417,22 @@ func (d *database) getPosts(config *postsRequestConfig) (posts []*post, err erro posts = append(posts, p) } if !config.withoutParameters { - err = d.loadPostParameters(posts, config.withOnlyParameters...) + err = a.db.loadPostParameters(posts, config.withOnlyParameters...) if err != nil { return nil, err } } + // Render post title + for _, p := range posts { + if t := p.Title(); t != "" { + p.RenderedTitle = a.renderMdTitle(t) + } + } return posts, nil } -func (d *database) getPost(path string) (*post, error) { - posts, err := d.getPosts(&postsRequestConfig{path: path, limit: 1}) +func (a *goBlog) getPost(path string) (*post, error) { + posts, err := a.getPosts(&postsRequestConfig{path: path, limit: 1}) if err != nil { return nil, err } else if len(posts) == 0 { diff --git a/postsDb_test.go b/postsDb_test.go index 25d15b2..faf7757 100644 --- a/postsDb_test.go +++ b/postsDb_test.go @@ -29,6 +29,7 @@ func Test_postsDb(t *testing.T) { }, } _ = app.initDatabase(false) + app.initMarkdown() now := toLocalSafe(time.Now().String()) nowPlus1Hour := toLocalSafe(time.Now().Add(1 * time.Hour).String()) @@ -51,7 +52,7 @@ func Test_postsDb(t *testing.T) { must.NoError(err) // Check post - p, err := app.db.getPost("/test/abc") + p, err := app.getPost("/test/abc") must.NoError(err) is.Equal("/test/abc", p.Path) is.Equal("ABC", p.Content) @@ -75,7 +76,7 @@ func Test_postsDb(t *testing.T) { is.Len(pp, 0) // Check drafts - drafts, _ := app.db.getPosts(&postsRequestConfig{ + drafts, _ := app.getPosts(&postsRequestConfig{ blog: "en", status: statusDraft, }) @@ -90,7 +91,7 @@ func Test_postsDb(t *testing.T) { is.Equal(0, count) // Delete post - _, err = app.db.deletePost("/test/abc") + _, err = app.deletePostFromDb("/test/abc") must.NoError(err) // Check that there is no post @@ -220,6 +221,7 @@ func Test_ftsWithoutTitle(t *testing.T) { }, } _ = app.initDatabase(false) + app.initMarkdown() err := app.db.savePost(&post{ Path: "/test/abc", @@ -232,7 +234,7 @@ func Test_ftsWithoutTitle(t *testing.T) { }, &postCreationOptions{new: true}) require.NoError(t, err) - ps, err := app.db.getPosts(&postsRequestConfig{ + ps, err := app.getPosts(&postsRequestConfig{ search: "ABC", }) assert.NoError(t, err) @@ -250,6 +252,7 @@ func Test_postsPriority(t *testing.T) { }, } _ = app.initDatabase(false) + app.initMarkdown() err := app.db.savePost(&post{ Path: "/test/abc", @@ -272,7 +275,7 @@ func Test_postsPriority(t *testing.T) { }, &postCreationOptions{new: true}) require.NoError(t, err) - ps, err := app.db.getPosts(&postsRequestConfig{ + ps, err := app.getPosts(&postsRequestConfig{ priorityOrder: true, }) require.NoError(t, err) diff --git a/postsFuncs.go b/postsFuncs.go index 75c69e1..32d41db 100644 --- a/postsFuncs.go +++ b/postsFuncs.go @@ -109,7 +109,7 @@ func (a *goBlog) postTranslations(p *post) []*post { if translationkey == "" { return nil } - posts, err := a.db.getPosts(&postsRequestConfig{ + posts, err := a.getPosts(&postsRequestConfig{ parameter: "translationkey", parameterValue: translationkey, }) diff --git a/sitemap.go b/sitemap.go index f77cd32..f9473fa 100644 --- a/sitemap.go +++ b/sitemap.go @@ -153,7 +153,7 @@ func (a *goBlog) serveSitemapBlogPosts(w http.ResponseWriter, r *http.Request) { // Create sitemap sm := sitemap.New() // Request posts - posts, _ := a.db.getPosts(&postsRequestConfig{ + posts, _ := a.getPosts(&postsRequestConfig{ status: statusPublished, blog: r.Context().Value(blogKey).(string), withoutParameters: true, diff --git a/telegram.go b/telegram.go index 8c6b5d7..bbd106b 100644 --- a/telegram.go +++ b/telegram.go @@ -16,7 +16,7 @@ const telegramBaseURL = "https://api.telegram.org/bot" func (a *goBlog) initTelegram() { a.pPostHooks = append(a.pPostHooks, func(p *post) { if tg := a.cfg.Blogs[p.Blog].Telegram; tg.enabled() && p.isPublishedSectionPost() { - if html := tg.generateHTML(a.renderMdTitle(p.Title()), a.fullPostURL(p), a.shortPostURL(p)); html != "" { + if html := tg.generateHTML(p.RenderedTitle, a.fullPostURL(p), a.shortPostURL(p)); html != "" { if err := a.send(tg, html, "HTML"); err != nil { log.Printf("Failed to send post to Telegram: %v", err) } diff --git a/telegram_test.go b/telegram_test.go index de263e4..c9e11da 100644 --- a/telegram_test.go +++ b/telegram_test.go @@ -139,14 +139,12 @@ func Test_telegram(t *testing.T) { app.initTelegram() p := &post{ - Path: "/test", - Parameters: map[string][]string{ - "title": {"Title"}, - }, - Published: time.Now().String(), - Section: "test", - Blog: "en", - Status: statusPublished, + Path: "/test", + RenderedTitle: "Title", + Published: time.Now().String(), + Section: "test", + Blog: "en", + Status: statusPublished, } app.pPostHooks[0](p) diff --git a/templates/photosummary.gohtml b/templates/photosummary.gohtml index 75c9e66..21d9efb 100644 --- a/templates/photosummary.gohtml +++ b/templates/photosummary.gohtml @@ -1,10 +1,10 @@ {{ define "photosummary" }}
{{ if gt .Data.Priority 0 }}

πŸ“Œ {{ string .Blog.Lang "pinned" }}

{{ end }} - {{ if .Data.Title }} + {{ if .Data.RenderedTitle }}

- {{ mdtitle .Data.Title }} + {{ .Data.RenderedTitle }}

{{ end }} diff --git a/templates/post.gohtml b/templates/post.gohtml index f85cc88..c581dab 100644 --- a/templates/post.gohtml +++ b/templates/post.gohtml @@ -1,5 +1,5 @@ {{ define "title" }} - {{ with .Data.Title }}{{ mdtitle . }} - {{end}}{{ mdtitle .Blog.Title }} + {{ with .Data.RenderedTitle }}{{ . }} - {{end}}{{ mdtitle .Blog.Title }} {{ include "postheadmeta" . }} {{ with shorturl .Data }}{{ end }} {{ end }} @@ -8,7 +8,7 @@
- {{ with .Data.Title }}

{{ mdtitle . }}

{{ end }} + {{ with .Data.RenderedTitle }}

{{ . }}

{{ end }} {{ include "postmeta" . }} {{ include "postactions" . }} {{ if .Data.Content }} diff --git a/templates/postactions.gohtml b/templates/postactions.gohtml index 12ec425..dd3531d 100644 --- a/templates/postactions.gohtml +++ b/templates/postactions.gohtml @@ -1,6 +1,6 @@ {{ define "postactions" }}
- {{ string .Blog.Lang "share" }}  + {{ string .Blog.Lang "share" }}  {{ string .Blog.Lang "translate" }}  diff --git a/templates/postheadmeta.gohtml b/templates/postheadmeta.gohtml index 80bd6e9..233a88a 100644 --- a/templates/postheadmeta.gohtml +++ b/templates/postheadmeta.gohtml @@ -3,9 +3,9 @@ {{ end }} - {{ with .Data.Title }} - - + {{ with .Data.RenderedTitle }} + + {{ end }} {{ with summary .Data }} diff --git a/templates/postmeta.gohtml b/templates/postmeta.gohtml index 6ba76a3..ecb9318 100644 --- a/templates/postmeta.gohtml +++ b/templates/postmeta.gohtml @@ -3,7 +3,7 @@ {{ include "summaryandpostmeta" . }} {{ $translations := (translations .Data) }} {{ if gt (len $translations) 0 }} -
{{ string .Blog.Lang "translations" }}: {{ $delimiter := "" }}{{ range $i, $t := $translations }}{{ $delimiter }}{{ mdtitle $t.Title }}{{ $delimiter = ", " }}{{ end }}
+
{{ string .Blog.Lang "translations" }}: {{ $delimiter := "" }}{{ range $i, $t := $translations }}{{ $delimiter }}{{ $t.RenderedTitle }}{{ $delimiter = ", " }}{{ end }}
{{ end }} {{ $short := shorturl .Data }} {{ if $short }}
{{ string .Blog.Lang "shorturl" }} {{ $short }}
{{ end }} diff --git a/templates/summary.gohtml b/templates/summary.gohtml index 3b35da1..ddb3fe9 100644 --- a/templates/summary.gohtml +++ b/templates/summary.gohtml @@ -1,10 +1,10 @@ {{ define "summary" }}