mirror of https://github.com/jlelse/GoBlog
Add reply and like context and fetching it (Completes #45)
This commit is contained in:
parent
6d25ba0029
commit
d5e3d9e216
36
config.go
36
config.go
|
@ -101,7 +101,9 @@ type configBlog struct {
|
||||||
hideShareButton bool
|
hideShareButton bool
|
||||||
hideTranslateButton bool
|
hideTranslateButton bool
|
||||||
addReplyTitle bool
|
addReplyTitle bool
|
||||||
|
addReplyContext bool
|
||||||
addLikeTitle bool
|
addLikeTitle bool
|
||||||
|
addLikeContext bool
|
||||||
// Editor state WebSockets
|
// Editor state WebSockets
|
||||||
esws sync.Map
|
esws sync.Map
|
||||||
esm sync.Mutex
|
esm sync.Mutex
|
||||||
|
@ -232,8 +234,10 @@ type configMicropub struct {
|
||||||
CategoryParam string `mapstructure:"categoryParam"`
|
CategoryParam string `mapstructure:"categoryParam"`
|
||||||
ReplyParam string `mapstructure:"replyParam"`
|
ReplyParam string `mapstructure:"replyParam"`
|
||||||
ReplyTitleParam string `mapstructure:"replyTitleParam"`
|
ReplyTitleParam string `mapstructure:"replyTitleParam"`
|
||||||
|
ReplyContextParam string `mapstructure:"replyContextParam"`
|
||||||
LikeParam string `mapstructure:"likeParam"`
|
LikeParam string `mapstructure:"likeParam"`
|
||||||
LikeTitleParam string `mapstructure:"likeTitleParam"`
|
LikeTitleParam string `mapstructure:"likeTitleParam"`
|
||||||
|
LikeContextParam string `mapstructure:"likeContextParam"`
|
||||||
BookmarkParam string `mapstructure:"bookmarkParam"`
|
BookmarkParam string `mapstructure:"bookmarkParam"`
|
||||||
AudioParam string `mapstructure:"audioParam"`
|
AudioParam string `mapstructure:"audioParam"`
|
||||||
PhotoParam string `mapstructure:"photoParam"`
|
PhotoParam string `mapstructure:"photoParam"`
|
||||||
|
@ -520,25 +524,23 @@ func (a *goBlog) initConfig(logging bool) error {
|
||||||
br.Enabled = false
|
br.Enabled = false
|
||||||
}
|
}
|
||||||
// Load other settings from database
|
// Load other settings from database
|
||||||
bc.hideOldContentWarning, err = a.getBooleanSettingValue(settingNameWithBlog(blog, hideOldContentWarningSetting), false)
|
configs := []*bool{
|
||||||
|
&bc.hideOldContentWarning, &bc.hideShareButton, &bc.hideTranslateButton,
|
||||||
|
&bc.addReplyTitle, &bc.addReplyContext, &bc.addLikeTitle, &bc.addLikeContext,
|
||||||
|
}
|
||||||
|
settings := []string{
|
||||||
|
hideOldContentWarningSetting, hideShareButtonSetting, hideTranslateButtonSetting,
|
||||||
|
addReplyTitleSetting, addReplyContextSetting, addLikeTitleSetting, addLikeContextSetting,
|
||||||
|
}
|
||||||
|
defaults := []bool{
|
||||||
|
false, false, false,
|
||||||
|
false, false, false, false,
|
||||||
|
}
|
||||||
|
for i := range configs {
|
||||||
|
*configs[i], err = a.getBooleanSettingValue(settingNameWithBlog(blog, settings[i]), defaults[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
bc.hideShareButton, err = a.getBooleanSettingValue(settingNameWithBlog(blog, hideShareButtonSetting), false)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
bc.hideTranslateButton, err = a.getBooleanSettingValue(settingNameWithBlog(blog, hideTranslateButtonSetting), false)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
bc.addReplyTitle, err = a.getBooleanSettingValue(settingNameWithBlog(blog, addReplyTitleSetting), false)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
bc.addLikeTitle, err = a.getBooleanSettingValue(settingNameWithBlog(blog, addLikeTitleSetting), false)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Log success
|
// Log success
|
||||||
|
@ -571,8 +573,10 @@ func createDefaultConfig() *config {
|
||||||
CategoryParam: "tags",
|
CategoryParam: "tags",
|
||||||
ReplyParam: "replylink",
|
ReplyParam: "replylink",
|
||||||
ReplyTitleParam: "replytitle",
|
ReplyTitleParam: "replytitle",
|
||||||
|
ReplyContextParam: "replycontext",
|
||||||
LikeParam: "likelink",
|
LikeParam: "likelink",
|
||||||
LikeTitleParam: "liketitle",
|
LikeTitleParam: "liketitle",
|
||||||
|
LikeContextParam: "likecontext",
|
||||||
BookmarkParam: "link",
|
BookmarkParam: "link",
|
||||||
AudioParam: "audio",
|
AudioParam: "audio",
|
||||||
PhotoParam: "images",
|
PhotoParam: "images",
|
||||||
|
|
|
@ -229,11 +229,13 @@ func (a *goBlog) editorPostDesc(bc *configBlog) string {
|
||||||
a.cfg.Micropub.BookmarkParam,
|
a.cfg.Micropub.BookmarkParam,
|
||||||
a.cfg.Micropub.LikeParam,
|
a.cfg.Micropub.LikeParam,
|
||||||
a.cfg.Micropub.LikeTitleParam,
|
a.cfg.Micropub.LikeTitleParam,
|
||||||
|
a.cfg.Micropub.LikeContextParam,
|
||||||
a.cfg.Micropub.LocationParam,
|
a.cfg.Micropub.LocationParam,
|
||||||
a.cfg.Micropub.PhotoParam,
|
a.cfg.Micropub.PhotoParam,
|
||||||
a.cfg.Micropub.PhotoDescriptionParam,
|
a.cfg.Micropub.PhotoDescriptionParam,
|
||||||
a.cfg.Micropub.ReplyParam,
|
a.cfg.Micropub.ReplyParam,
|
||||||
a.cfg.Micropub.ReplyTitleParam,
|
a.cfg.Micropub.ReplyTitleParam,
|
||||||
|
a.cfg.Micropub.ReplyContextParam,
|
||||||
gpxParameter,
|
gpxParameter,
|
||||||
} {
|
} {
|
||||||
if param == "" {
|
if param == "" {
|
||||||
|
|
|
@ -119,8 +119,10 @@ micropub:
|
||||||
categoryParam: tags
|
categoryParam: tags
|
||||||
replyParam: replylink
|
replyParam: replylink
|
||||||
replyTitleParam: replytitle
|
replyTitleParam: replytitle
|
||||||
|
replyContextParam: replycontext
|
||||||
likeParam: likelink
|
likeParam: likelink
|
||||||
likeTitleParam: liketitle
|
likeTitleParam: liketitle
|
||||||
|
likeContextParam: likecontext
|
||||||
bookmarkParam: link
|
bookmarkParam: link
|
||||||
audioParam: audio
|
audioParam: audio
|
||||||
photoParam: images
|
photoParam: images
|
||||||
|
|
|
@ -18,6 +18,7 @@ func Test_feeds(t *testing.T) {
|
||||||
|
|
||||||
_ = app.initConfig(false)
|
_ = app.initConfig(false)
|
||||||
app.initMarkdown()
|
app.initMarkdown()
|
||||||
|
_ = app.initTemplateStrings()
|
||||||
_ = app.initCache()
|
_ = app.initCache()
|
||||||
app.initSessions()
|
app.initSessions()
|
||||||
|
|
||||||
|
|
|
@ -471,7 +471,9 @@ func (a *goBlog) blogSettingsRouter(_ *configBlog) func(r chi.Router) {
|
||||||
r.Post(settingsHideShareButtonPath, a.settingsHideShareButton())
|
r.Post(settingsHideShareButtonPath, a.settingsHideShareButton())
|
||||||
r.Post(settingsHideTranslateButtonPath, a.settingsHideTranslateButton())
|
r.Post(settingsHideTranslateButtonPath, a.settingsHideTranslateButton())
|
||||||
r.Post(settingsAddReplyTitlePath, a.settingsAddReplyTitle())
|
r.Post(settingsAddReplyTitlePath, a.settingsAddReplyTitle())
|
||||||
|
r.Post(settingsAddReplyContextPath, a.settingsAddReplyContext())
|
||||||
r.Post(settingsAddLikeTitlePath, a.settingsAddLikeTitle())
|
r.Post(settingsAddLikeTitlePath, a.settingsAddLikeTitle())
|
||||||
|
r.Post(settingsAddLikeContextPath, a.settingsAddLikeContext())
|
||||||
r.Post(settingsUpdateUserPath, a.settingsUpdateUser)
|
r.Post(settingsUpdateUserPath, a.settingsUpdateUser)
|
||||||
r.Post(settingsUpdateProfileImagePath, a.serveUpdateProfileImage)
|
r.Post(settingsUpdateProfileImagePath, a.serveUpdateProfileImage)
|
||||||
r.Post(settingsDeleteProfileImagePath, a.serveDeleteProfileImage)
|
r.Post(settingsDeleteProfileImagePath, a.serveDeleteProfileImage)
|
||||||
|
|
|
@ -85,6 +85,13 @@ func parseMicroformatsFromReader(u string, r io.Reader) (*microformatsResult, er
|
||||||
if m.Title != "" && strings.HasPrefix(m.Content, m.Title) {
|
if m.Title != "" && strings.HasPrefix(m.Content, m.Title) {
|
||||||
m.Title = ""
|
m.Title = ""
|
||||||
}
|
}
|
||||||
|
// Shorten content and title if too long
|
||||||
|
if cr := []rune(m.Content); len(cr) > 500 {
|
||||||
|
m.Content = string(cr[0:497]) + "…"
|
||||||
|
}
|
||||||
|
if tr := []rune(m.Title); len(tr) > 60 {
|
||||||
|
m.Title = string(tr[0:57]) + "…"
|
||||||
|
}
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ func Test_parseMicroformats(t *testing.T) {
|
||||||
m, err := app.parseMicroformats("https://example.net/articles/micropub-crossposting-to-twitter-and-enabling-tweetstorms", false)
|
m, err := app.parseMicroformats("https://example.net/articles/micropub-crossposting-to-twitter-and-enabling-tweetstorms", false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, "Micropub, Crossposting to Twitter, and Enabling “Tweetstorms”", m.Title)
|
assert.Equal(t, "Micropub, Crossposting to Twitter, and Enabling “Tweetsto…", m.Title)
|
||||||
assert.NotEmpty(t, m.Content)
|
assert.NotEmpty(t, m.Content)
|
||||||
assert.Equal(t, "Test Blogger", m.Author)
|
assert.Equal(t, "Test Blogger", m.Author)
|
||||||
assert.Equal(t, "https://example.net/articles/micropub-crossposting-to-twitter-and-enabling-tweetstorms", m.Url)
|
assert.Equal(t, "https://example.net/articles/micropub-crossposting-to-twitter-and-enabling-tweetstorms", m.Url)
|
||||||
|
|
|
@ -632,9 +632,11 @@ func (a *goBlog) micropubUpdateDelete(p *post, del any) {
|
||||||
case "in-reply-to":
|
case "in-reply-to":
|
||||||
delete(p.Parameters, a.cfg.Micropub.ReplyParam)
|
delete(p.Parameters, a.cfg.Micropub.ReplyParam)
|
||||||
delete(p.Parameters, a.cfg.Micropub.ReplyTitleParam)
|
delete(p.Parameters, a.cfg.Micropub.ReplyTitleParam)
|
||||||
|
delete(p.Parameters, a.cfg.Micropub.ReplyContextParam)
|
||||||
case "like-of":
|
case "like-of":
|
||||||
delete(p.Parameters, a.cfg.Micropub.LikeParam)
|
delete(p.Parameters, a.cfg.Micropub.LikeParam)
|
||||||
delete(p.Parameters, a.cfg.Micropub.LikeTitleParam)
|
delete(p.Parameters, a.cfg.Micropub.LikeTitleParam)
|
||||||
|
delete(p.Parameters, a.cfg.Micropub.LikeContextParam)
|
||||||
case "bookmark-of":
|
case "bookmark-of":
|
||||||
delete(p.Parameters, a.cfg.Micropub.BookmarkParam)
|
delete(p.Parameters, a.cfg.Micropub.BookmarkParam)
|
||||||
case "audio":
|
case "audio":
|
||||||
|
|
19
postsDb.go
19
postsDb.go
|
@ -98,21 +98,10 @@ func (a *goBlog) checkPost(p *post, new bool) (err error) {
|
||||||
}
|
}
|
||||||
p.Parameters[pk] = pvs
|
p.Parameters[pk] = pvs
|
||||||
}
|
}
|
||||||
// Automatically add reply title
|
// Add context for replies and likes
|
||||||
if replyLink := p.firstParameter(a.cfg.Micropub.ReplyParam); replyLink != "" && p.firstParameter(a.cfg.Micropub.ReplyTitleParam) == "" &&
|
if new {
|
||||||
a.getBlogFromPost(p).addReplyTitle {
|
a.addReplyTitleAndContext(p)
|
||||||
// Is reply, but has no reply title
|
a.addLikeTitleAndContext(p)
|
||||||
if mf, err := a.parseMicroformats(replyLink, true); err == nil && mf.Title != "" {
|
|
||||||
p.addParameter(a.cfg.Micropub.ReplyTitleParam, mf.Title)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Automatically add like title
|
|
||||||
if likeLink := p.firstParameter(a.cfg.Micropub.LikeParam); likeLink != "" && p.firstParameter(a.cfg.Micropub.LikeTitleParam) == "" &&
|
|
||||||
a.getBlogFromPost(p).addLikeTitle {
|
|
||||||
// Is like, but has no like title
|
|
||||||
if mf, err := a.parseMicroformats(likeLink, true); err == nil && mf.Title != "" {
|
|
||||||
p.addParameter(a.cfg.Micropub.LikeTitleParam, mf.Title)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Check path
|
// Check path
|
||||||
if p.Path != "/" {
|
if p.Path != "/" {
|
||||||
|
|
|
@ -57,8 +57,13 @@ func (a *goBlog) postHtmlToWriter(w io.Writer, p *post, absolute bool) {
|
||||||
hb.WriteElementClose("source")
|
hb.WriteElementClose("source")
|
||||||
hb.WriteElementClose("audio")
|
hb.WriteElementClose("audio")
|
||||||
}
|
}
|
||||||
|
// Add IndieWeb context
|
||||||
|
a.renderPostReplyContext(hb, p)
|
||||||
|
a.renderPostLikeContext(hb, p)
|
||||||
// Render markdown
|
// Render markdown
|
||||||
|
hb.WriteElementOpen("div", "class", "e-content")
|
||||||
_ = a.renderMarkdownToWriter(w, p.Content, absolute)
|
_ = a.renderMarkdownToWriter(w, p.Content, absolute)
|
||||||
|
hb.WriteElementClose("div")
|
||||||
// Add bookmark links to the bottom
|
// Add bookmark links to the bottom
|
||||||
for _, l := range p.Parameters[a.cfg.Micropub.BookmarkParam] {
|
for _, l := range p.Parameters[a.cfg.Micropub.BookmarkParam] {
|
||||||
hb.WriteElementOpen("p")
|
hb.WriteElementOpen("p")
|
||||||
|
@ -78,9 +83,6 @@ func (a *goBlog) feedHtml(w io.Writer, p *post) {
|
||||||
hb.WriteElementClose("source")
|
hb.WriteElementClose("source")
|
||||||
hb.WriteElementClose("audio")
|
hb.WriteElementClose("audio")
|
||||||
}
|
}
|
||||||
// Add IndieWeb context
|
|
||||||
a.renderPostReplyContext(hb, p, "p")
|
|
||||||
a.renderPostLikeContext(hb, p, "p")
|
|
||||||
// Add post HTML
|
// Add post HTML
|
||||||
a.postHtmlToWriter(hb, p, true)
|
a.postHtmlToWriter(hb, p, true)
|
||||||
// Add link to interactions and comments
|
// Add link to interactions and comments
|
||||||
|
@ -96,9 +98,6 @@ func (a *goBlog) feedHtml(w io.Writer, p *post) {
|
||||||
|
|
||||||
func (a *goBlog) minFeedHtml(w io.Writer, p *post) {
|
func (a *goBlog) minFeedHtml(w io.Writer, p *post) {
|
||||||
hb := htmlbuilder.NewHtmlBuilder(w)
|
hb := htmlbuilder.NewHtmlBuilder(w)
|
||||||
// Add IndieWeb context
|
|
||||||
a.renderPostReplyContext(hb, p, "p")
|
|
||||||
a.renderPostLikeContext(hb, p, "p")
|
|
||||||
// Add post HTML
|
// Add post HTML
|
||||||
a.postHtmlToWriter(hb, p, true)
|
a.postHtmlToWriter(hb, p, true)
|
||||||
}
|
}
|
||||||
|
@ -219,6 +218,10 @@ func (a *goBlog) replyTitle(p *post) string {
|
||||||
return p.firstParameter(a.cfg.Micropub.ReplyTitleParam)
|
return p.firstParameter(a.cfg.Micropub.ReplyTitleParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *goBlog) replyContext(p *post) string {
|
||||||
|
return p.firstParameter(a.cfg.Micropub.ReplyContextParam)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *goBlog) likeLink(p *post) string {
|
func (a *goBlog) likeLink(p *post) string {
|
||||||
return p.firstParameter(a.cfg.Micropub.LikeParam)
|
return p.firstParameter(a.cfg.Micropub.LikeParam)
|
||||||
}
|
}
|
||||||
|
@ -227,6 +230,10 @@ func (a *goBlog) likeTitle(p *post) string {
|
||||||
return p.firstParameter(a.cfg.Micropub.LikeTitleParam)
|
return p.firstParameter(a.cfg.Micropub.LikeTitleParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *goBlog) likeContext(p *post) string {
|
||||||
|
return p.firstParameter(a.cfg.Micropub.LikeContextParam)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *goBlog) photoLinks(p *post) []string {
|
func (a *goBlog) photoLinks(p *post) []string {
|
||||||
return p.Parameters[a.cfg.Micropub.PhotoParam]
|
return p.Parameters[a.cfg.Micropub.PhotoParam]
|
||||||
}
|
}
|
||||||
|
@ -270,6 +277,42 @@ func (p *post) getChannel() string {
|
||||||
return p.Blog + "/" + p.Section
|
return p.Blog + "/" + p.Section
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *goBlog) addReplyTitleAndContext(p *post) {
|
||||||
|
if replyLink := p.firstParameter(a.cfg.Micropub.ReplyParam); replyLink != "" {
|
||||||
|
addTitle := p.firstParameter(a.cfg.Micropub.ReplyTitleParam) == "" && a.getBlogFromPost(p).addReplyTitle
|
||||||
|
addContext := p.firstParameter(a.cfg.Micropub.ReplyContextParam) == "" && a.getBlogFromPost(p).addReplyContext
|
||||||
|
if !addTitle && !addContext {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if mf, err := a.parseMicroformats(replyLink, true); err == nil {
|
||||||
|
if addTitle && mf.Title != "" {
|
||||||
|
p.addParameter(a.cfg.Micropub.ReplyTitleParam, mf.Title)
|
||||||
|
}
|
||||||
|
if addContext && mf.Content != "" {
|
||||||
|
p.addParameter(a.cfg.Micropub.ReplyContextParam, mf.Content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *goBlog) addLikeTitleAndContext(p *post) {
|
||||||
|
if likeLink := p.firstParameter(a.cfg.Micropub.LikeParam); likeLink != "" {
|
||||||
|
addTitle := p.firstParameter(a.cfg.Micropub.LikeTitleParam) == "" && a.getBlogFromPost(p).addLikeTitle
|
||||||
|
addContext := p.firstParameter(a.cfg.Micropub.LikeContextParam) == "" && a.getBlogFromPost(p).addLikeContext
|
||||||
|
if !addTitle && !addContext {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if mf, err := a.parseMicroformats(likeLink, true); err == nil {
|
||||||
|
if addTitle && mf.Title != "" {
|
||||||
|
p.addParameter(a.cfg.Micropub.LikeTitleParam, mf.Title)
|
||||||
|
}
|
||||||
|
if addContext && mf.Content != "" {
|
||||||
|
p.addParameter(a.cfg.Micropub.LikeContextParam, mf.Content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Public because of rendering
|
// Public because of rendering
|
||||||
|
|
||||||
func (p *post) Title() string {
|
func (p *post) Title() string {
|
||||||
|
|
18
settings.go
18
settings.go
|
@ -24,7 +24,9 @@ func (a *goBlog) serveSettings(w http.ResponseWriter, r *http.Request) {
|
||||||
hideShareButton: bc.hideShareButton,
|
hideShareButton: bc.hideShareButton,
|
||||||
hideTranslateButton: bc.hideTranslateButton,
|
hideTranslateButton: bc.hideTranslateButton,
|
||||||
addReplyTitle: bc.addReplyTitle,
|
addReplyTitle: bc.addReplyTitle,
|
||||||
|
addReplyContext: bc.addReplyContext,
|
||||||
addLikeTitle: bc.addLikeTitle,
|
addLikeTitle: bc.addLikeTitle,
|
||||||
|
addLikeContext: bc.addLikeContext,
|
||||||
userNick: a.cfg.User.Nick,
|
userNick: a.cfg.User.Nick,
|
||||||
userName: a.cfg.User.Name,
|
userName: a.cfg.User.Name,
|
||||||
},
|
},
|
||||||
|
@ -209,6 +211,14 @@ func (a *goBlog) settingsAddReplyTitle() http.HandlerFunc {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const settingsAddReplyContextPath = "/replycontext"
|
||||||
|
|
||||||
|
func (a *goBlog) settingsAddReplyContext() http.HandlerFunc {
|
||||||
|
return a.booleanBlogSettingHandler(addReplyContextSetting, func(cb *configBlog, b bool) {
|
||||||
|
cb.addReplyContext = b
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const settingsAddLikeTitlePath = "/liketitle"
|
const settingsAddLikeTitlePath = "/liketitle"
|
||||||
|
|
||||||
func (a *goBlog) settingsAddLikeTitle() http.HandlerFunc {
|
func (a *goBlog) settingsAddLikeTitle() http.HandlerFunc {
|
||||||
|
@ -217,6 +227,14 @@ func (a *goBlog) settingsAddLikeTitle() http.HandlerFunc {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const settingsAddLikeContextPath = "/likecontext"
|
||||||
|
|
||||||
|
func (a *goBlog) settingsAddLikeContext() http.HandlerFunc {
|
||||||
|
return a.booleanBlogSettingHandler(addLikeContextSetting, func(cb *configBlog, b bool) {
|
||||||
|
cb.addLikeContext = b
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const settingsUpdateUserPath = "/user"
|
const settingsUpdateUserPath = "/user"
|
||||||
|
|
||||||
func (a *goBlog) settingsUpdateUser(w http.ResponseWriter, r *http.Request) {
|
func (a *goBlog) settingsUpdateUser(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
|
@ -20,7 +20,9 @@ const (
|
||||||
userNickSetting = "usernick"
|
userNickSetting = "usernick"
|
||||||
userNameSetting = "username"
|
userNameSetting = "username"
|
||||||
addReplyTitleSetting = "addreplytitle"
|
addReplyTitleSetting = "addreplytitle"
|
||||||
|
addReplyContextSetting = "addreplycontext"
|
||||||
addLikeTitleSetting = "addliketitle"
|
addLikeTitleSetting = "addliketitle"
|
||||||
|
addLikeContextSetting = "addlikecontext"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *goBlog) getSettingValue(name string) (string, error) {
|
func (a *goBlog) getSettingValue(name string) (string, error) {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
acommentby: "Ein Kommentar von"
|
acommentby: "Ein Kommentar von"
|
||||||
addliketitledesc: "Automatisch einen Like-Titel zu neuen und aktualisierten Beiträgen mit einem Like-Link ohne manuell gesetzten Like-Titel hinzufügen."
|
addlikecontextdesc: "Automatisch einen Like-Context zu neuen Beiträgen mit einem Like-Link ohne manuell gesetzten Like-Titel hinzufügen."
|
||||||
addreplytitledesc: "Automatisch einen Reply-Titel zu neuen und aktualisierten Beiträgen mit einem Reply-Link ohne manuell gesetzten Reply-Titel hinzufügen."
|
addliketitledesc: "Automatisch einen Like-Titel zu neuen Beiträgen mit einem Like-Link ohne manuell gesetzten Like-Titel hinzufügen."
|
||||||
|
addreplycontextdesc: "Automatisch einen Reply-Context zu neuen Beiträgen mit einem Reply-Link ohne manuell gesetzten Reply-Titel hinzufügen."
|
||||||
|
addreplytitledesc: "Automatisch einen Reply-Titel zu neuen Beiträgen mit einem Reply-Link ohne manuell gesetzten Reply-Titel hinzufügen."
|
||||||
captchainstructions: "Bitte gib die Ziffern aus dem oberen Bild ein"
|
captchainstructions: "Bitte gib die Ziffern aus dem oberen Bild ein"
|
||||||
chars: "Buchstaben"
|
chars: "Buchstaben"
|
||||||
comment: "Kommentar"
|
comment: "Kommentar"
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
acommentby: "A comment by"
|
acommentby: "A comment by"
|
||||||
addliketitledesc: "Automatically add like title to new and updated posts with a like link and no manually set like title."
|
addlikecontextdesc: "Automatically add like context to new posts with a like link and no manually set like title."
|
||||||
addreplytitledesc: "Automatically add reply title to new and updated posts with a reply link and no manually set reply title."
|
addliketitledesc: "Automatically add like title to new posts with a like link and no manually set like title."
|
||||||
|
addreplycontextdesc: "Automatically add reply context to new posts with a reply link and no manually set reply title."
|
||||||
|
addreplytitledesc: "Automatically add reply title to new posts with a reply link and no manually set reply title."
|
||||||
apfollower: "Follower"
|
apfollower: "Follower"
|
||||||
apfollowers: "ActivityPub followers"
|
apfollowers: "ActivityPub followers"
|
||||||
apinbox: "Inbox"
|
apinbox: "Inbox"
|
||||||
|
|
31
ui.go
31
ui.go
|
@ -38,11 +38,7 @@ func (a *goBlog) wrapUiPlugins(t plugintypes.RenderType, d plugintypes.RenderDat
|
||||||
func (a *goBlog) renderEditorPreview(hb *htmlbuilder.HtmlBuilder, bc *configBlog, p *post) {
|
func (a *goBlog) renderEditorPreview(hb *htmlbuilder.HtmlBuilder, bc *configBlog, p *post) {
|
||||||
a.renderPostTitle(hb, p)
|
a.renderPostTitle(hb, p)
|
||||||
a.renderPostMeta(hb, p, bc, "preview")
|
a.renderPostMeta(hb, p, bc, "preview")
|
||||||
if p.Content != "" {
|
|
||||||
hb.WriteElementOpen("div")
|
|
||||||
a.postHtmlToWriter(hb, p, true)
|
a.postHtmlToWriter(hb, p, true)
|
||||||
hb.WriteElementClose("div")
|
|
||||||
}
|
|
||||||
// a.renderPostGPX(hb, p, bc)
|
// a.renderPostGPX(hb, p, bc)
|
||||||
a.renderPostTax(hb, p, bc)
|
a.renderPostTax(hb, p, bc)
|
||||||
}
|
}
|
||||||
|
@ -893,7 +889,7 @@ func (a *goBlog) renderPost(hb *htmlbuilder.HtmlBuilder, rd *renderData) {
|
||||||
func(hb *htmlbuilder.HtmlBuilder) {
|
func(hb *htmlbuilder.HtmlBuilder) {
|
||||||
a.renderTitleTag(hb, rd.Blog, p.RenderedTitle)
|
a.renderTitleTag(hb, rd.Blog, p.RenderedTitle)
|
||||||
hb.WriteElementOpen("link", "rel", "stylesheet", "href", a.assetFileName("css/chroma.css"))
|
hb.WriteElementOpen("link", "rel", "stylesheet", "href", a.assetFileName("css/chroma.css"))
|
||||||
a.renderPostHeadMeta(hb, p, rd.Canonical)
|
a.renderPostHeadMeta(hb, p)
|
||||||
if su := a.shortPostURL(p); su != "" {
|
if su := a.shortPostURL(p); su != "" {
|
||||||
hb.WriteElementOpen("link", "rel", "shortlink", "href", su)
|
hb.WriteElementOpen("link", "rel", "shortlink", "href", su)
|
||||||
}
|
}
|
||||||
|
@ -935,12 +931,7 @@ func (a *goBlog) renderPost(hb *htmlbuilder.HtmlBuilder, rd *renderData) {
|
||||||
// Old content warning
|
// Old content warning
|
||||||
a.renderOldContentWarning(hb, p, rd.Blog)
|
a.renderOldContentWarning(hb, p, rd.Blog)
|
||||||
// Content
|
// Content
|
||||||
if p.Content != "" {
|
|
||||||
// Content
|
|
||||||
hb.WriteElementOpen("div", "class", "e-content")
|
|
||||||
a.postHtmlToWriter(hb, p, false)
|
a.postHtmlToWriter(hb, p, false)
|
||||||
hb.WriteElementClose("div")
|
|
||||||
}
|
|
||||||
// External Videp
|
// External Videp
|
||||||
a.renderPostVideo(hb, p)
|
a.renderPostVideo(hb, p)
|
||||||
// GPS Track
|
// GPS Track
|
||||||
|
@ -1006,7 +997,7 @@ func (a *goBlog) renderStaticHome(hb *htmlbuilder.HtmlBuilder, rd *renderData) {
|
||||||
hb, rd,
|
hb, rd,
|
||||||
func(hb *htmlbuilder.HtmlBuilder) {
|
func(hb *htmlbuilder.HtmlBuilder) {
|
||||||
a.renderTitleTag(hb, rd.Blog, "")
|
a.renderTitleTag(hb, rd.Blog, "")
|
||||||
a.renderPostHeadMeta(hb, p, rd.Canonical)
|
a.renderPostHeadMeta(hb, p)
|
||||||
},
|
},
|
||||||
func(hb *htmlbuilder.HtmlBuilder) {
|
func(hb *htmlbuilder.HtmlBuilder) {
|
||||||
hb.WriteElementOpen("main", "class", "h-entry")
|
hb.WriteElementOpen("main", "class", "h-entry")
|
||||||
|
@ -1017,9 +1008,7 @@ func (a *goBlog) renderStaticHome(hb *htmlbuilder.HtmlBuilder, rd *renderData) {
|
||||||
// Content
|
// Content
|
||||||
if p.Content != "" {
|
if p.Content != "" {
|
||||||
// Content
|
// Content
|
||||||
hb.WriteElementOpen("div", "class", "e-content")
|
|
||||||
a.postHtmlToWriter(hb, p, false)
|
a.postHtmlToWriter(hb, p, false)
|
||||||
hb.WriteElementClose("div")
|
|
||||||
}
|
}
|
||||||
// Author
|
// Author
|
||||||
a.renderAuthor(hb)
|
a.renderAuthor(hb)
|
||||||
|
@ -1537,7 +1526,9 @@ type settingsRenderData struct {
|
||||||
hideShareButton bool
|
hideShareButton bool
|
||||||
hideTranslateButton bool
|
hideTranslateButton bool
|
||||||
addReplyTitle bool
|
addReplyTitle bool
|
||||||
|
addReplyContext bool
|
||||||
addLikeTitle bool
|
addLikeTitle bool
|
||||||
|
addLikeContext bool
|
||||||
userNick string
|
userNick string
|
||||||
userName string
|
userName string
|
||||||
}
|
}
|
||||||
|
@ -1593,6 +1584,13 @@ func (a *goBlog) renderSettings(hb *htmlbuilder.HtmlBuilder, rd *renderData) {
|
||||||
addReplyTitleSetting,
|
addReplyTitleSetting,
|
||||||
srd.addReplyTitle,
|
srd.addReplyTitle,
|
||||||
)
|
)
|
||||||
|
// Add reply context
|
||||||
|
a.renderBooleanSetting(hb, rd,
|
||||||
|
rd.Blog.getRelativePath(settingsPath+settingsAddReplyContextPath),
|
||||||
|
a.ts.GetTemplateStringVariant(rd.Blog.Lang, "addreplycontextdesc"),
|
||||||
|
addReplyContextSetting,
|
||||||
|
srd.addReplyContext,
|
||||||
|
)
|
||||||
// Add like title
|
// Add like title
|
||||||
a.renderBooleanSetting(hb, rd,
|
a.renderBooleanSetting(hb, rd,
|
||||||
rd.Blog.getRelativePath(settingsPath+settingsAddLikeTitlePath),
|
rd.Blog.getRelativePath(settingsPath+settingsAddLikeTitlePath),
|
||||||
|
@ -1600,6 +1598,13 @@ func (a *goBlog) renderSettings(hb *htmlbuilder.HtmlBuilder, rd *renderData) {
|
||||||
addLikeTitleSetting,
|
addLikeTitleSetting,
|
||||||
srd.addLikeTitle,
|
srd.addLikeTitle,
|
||||||
)
|
)
|
||||||
|
// Add like context
|
||||||
|
a.renderBooleanSetting(hb, rd,
|
||||||
|
rd.Blog.getRelativePath(settingsPath+settingsAddLikeContextPath),
|
||||||
|
a.ts.GetTemplateStringVariant(rd.Blog.Lang, "addlikecontextdesc"),
|
||||||
|
addLikeContextSetting,
|
||||||
|
srd.addLikeContext,
|
||||||
|
)
|
||||||
|
|
||||||
// User settings
|
// User settings
|
||||||
a.renderUserSettings(hb, rd, srd)
|
a.renderUserSettings(hb, rd, srd)
|
||||||
|
|
|
@ -53,10 +53,11 @@ func (a *goBlog) renderSummary(hb *htmlbuilder.HtmlBuilder, bc *configBlog, p *p
|
||||||
a.renderPostMeta(hb, p, bc, "summary")
|
a.renderPostMeta(hb, p, bc, "summary")
|
||||||
if typ != photoSummary && a.showFull(p) {
|
if typ != photoSummary && a.showFull(p) {
|
||||||
// Show full content
|
// Show full content
|
||||||
hb.WriteElementOpen("div", "class", "e-content")
|
|
||||||
a.postHtmlToWriter(hb, p, false)
|
a.postHtmlToWriter(hb, p, false)
|
||||||
hb.WriteElementClose("div")
|
|
||||||
} else {
|
} else {
|
||||||
|
// Show IndieWeb context
|
||||||
|
a.renderPostReplyContext(hb, p)
|
||||||
|
a.renderPostLikeContext(hb, p)
|
||||||
// Show summary
|
// Show summary
|
||||||
hb.WriteElementOpen("p", "class", "p-summary")
|
hb.WriteElementOpen("p", "class", "p-summary")
|
||||||
hb.WriteEscaped(a.postSummary(p))
|
hb.WriteEscaped(a.postSummary(p))
|
||||||
|
@ -160,9 +161,6 @@ func (a *goBlog) renderPostMeta(hb *htmlbuilder.HtmlBuilder, p *post, b *configB
|
||||||
hb.WriteElementClose("time")
|
hb.WriteElementClose("time")
|
||||||
hb.WriteElementClose("div")
|
hb.WriteElementClose("div")
|
||||||
}
|
}
|
||||||
// IndieWeb Meta
|
|
||||||
a.renderPostReplyContext(hb, p, "")
|
|
||||||
a.renderPostLikeContext(hb, p, "")
|
|
||||||
// Geo
|
// Geo
|
||||||
if geoURIs := a.geoURIs(p); len(geoURIs) != 0 {
|
if geoURIs := a.geoURIs(p); len(geoURIs) != 0 {
|
||||||
hb.WriteElementOpen("div")
|
hb.WriteElementOpen("div")
|
||||||
|
@ -233,43 +231,41 @@ func (a *goBlog) renderPostMeta(hb *htmlbuilder.HtmlBuilder, p *post, b *configB
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reply ("u-in-reply-to")
|
// Reply ("u-in-reply-to")
|
||||||
func (a *goBlog) renderPostReplyContext(hb *htmlbuilder.HtmlBuilder, p *post, htmlWrapperElement string) {
|
func (a *goBlog) renderPostReplyContext(hb *htmlbuilder.HtmlBuilder, p *post) {
|
||||||
if htmlWrapperElement == "" {
|
a.renderPostLikeReplyContext(hb, "u-in-reply-to", a.ts.GetTemplateStringVariant(a.getBlogFromPost(p).Lang, "replyto"), a.replyLink(p), a.replyTitle(p), a.replyContext(p))
|
||||||
htmlWrapperElement = "div"
|
|
||||||
}
|
|
||||||
if replyLink := a.replyLink(p); replyLink != "" {
|
|
||||||
hb.WriteElementOpen(htmlWrapperElement)
|
|
||||||
hb.WriteEscaped(a.ts.GetTemplateStringVariant(a.getBlogFromPost(p).Lang, "replyto"))
|
|
||||||
hb.WriteEscaped(": ")
|
|
||||||
hb.WriteElementOpen("a", "class", "u-in-reply-to", "rel", "noopener", "target", "_blank", "href", replyLink)
|
|
||||||
if replyTitle := a.replyTitle(p); replyTitle != "" {
|
|
||||||
hb.WriteEscaped(replyTitle)
|
|
||||||
} else {
|
|
||||||
hb.WriteEscaped(replyLink)
|
|
||||||
}
|
|
||||||
hb.WriteElementClose("a")
|
|
||||||
hb.WriteElementClose(htmlWrapperElement)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like ("u-like-of")
|
// Like ("u-like-of")
|
||||||
func (a *goBlog) renderPostLikeContext(hb *htmlbuilder.HtmlBuilder, p *post, htmlWrapperElement string) {
|
func (a *goBlog) renderPostLikeContext(hb *htmlbuilder.HtmlBuilder, p *post) {
|
||||||
if htmlWrapperElement == "" {
|
a.renderPostLikeReplyContext(hb, "u-like-of", a.ts.GetTemplateStringVariant(a.getBlogFromPost(p).Lang, "likeof"), a.likeLink(p), a.likeTitle(p), a.likeContext(p))
|
||||||
htmlWrapperElement = "div"
|
}
|
||||||
|
|
||||||
|
func (a *goBlog) renderPostLikeReplyContext(hb *htmlbuilder.HtmlBuilder, class, pretext, link, title, content string) {
|
||||||
|
if link == "" {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if likeLink := a.likeLink(p); likeLink != "" {
|
|
||||||
hb.WriteElementOpen(htmlWrapperElement)
|
hb.WriteElementOpen("div", "class", "h-cite "+class)
|
||||||
hb.WriteEscaped(a.ts.GetTemplateStringVariant(a.getBlogFromPost(p).Lang, "likeof"))
|
|
||||||
|
hb.WriteElementOpen("p")
|
||||||
|
hb.WriteElementOpen("strong")
|
||||||
|
hb.WriteEscaped(pretext)
|
||||||
hb.WriteEscaped(": ")
|
hb.WriteEscaped(": ")
|
||||||
hb.WriteElementOpen("a", "class", "u-like-of", "rel", "noopener", "target", "_blank", "href", likeLink)
|
hb.WriteElementOpen("a", "class", "u-url", "rel", "noopener", "target", "_blank", "href", link)
|
||||||
if likeTitle := a.likeTitle(p); likeTitle != "" {
|
hb.WriteEscaped(lo.If(title != "", title).Else(link))
|
||||||
hb.WriteEscaped(likeTitle)
|
|
||||||
} else {
|
|
||||||
hb.WriteEscaped(likeLink)
|
|
||||||
}
|
|
||||||
hb.WriteElementClose("a")
|
hb.WriteElementClose("a")
|
||||||
hb.WriteElementClose(htmlWrapperElement)
|
hb.WriteElementClose("strong")
|
||||||
|
hb.WriteElementClose("p")
|
||||||
|
|
||||||
|
if content != "" {
|
||||||
|
hb.WriteElementOpen("blockquote")
|
||||||
|
hb.WriteElementOpen("p", "class", "e-content")
|
||||||
|
hb.WriteEscaped(content)
|
||||||
|
hb.WriteElementClose("p")
|
||||||
|
hb.WriteElementClose("blockquote")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hb.WriteElementClose("div")
|
||||||
}
|
}
|
||||||
|
|
||||||
// warning for old posts
|
// warning for old posts
|
||||||
|
@ -391,22 +387,12 @@ func (a *goBlog) renderAuthor(hb *htmlbuilder.HtmlBuilder) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// head meta tags for a post
|
// head meta tags for a post
|
||||||
func (a *goBlog) renderPostHeadMeta(hb *htmlbuilder.HtmlBuilder, p *post, canonical string) {
|
func (a *goBlog) renderPostHeadMeta(hb *htmlbuilder.HtmlBuilder, p *post) {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if canonical != "" {
|
|
||||||
hb.WriteElementOpen("meta", "property", "og:url", "content", canonical)
|
|
||||||
hb.WriteElementOpen("meta", "property", "twitter:url", "content", canonical)
|
|
||||||
}
|
|
||||||
if p.RenderedTitle != "" {
|
|
||||||
hb.WriteElementOpen("meta", "property", "og:title", "content", p.RenderedTitle)
|
|
||||||
hb.WriteElementOpen("meta", "property", "twitter:title", "content", p.RenderedTitle)
|
|
||||||
}
|
|
||||||
if summary := a.postSummary(p); summary != "" {
|
if summary := a.postSummary(p); summary != "" {
|
||||||
hb.WriteElementOpen("meta", "name", "description", "content", summary)
|
hb.WriteElementOpen("meta", "name", "description", "content", summary)
|
||||||
hb.WriteElementOpen("meta", "property", "og:description", "content", summary)
|
|
||||||
hb.WriteElementOpen("meta", "property", "twitter:description", "content", summary)
|
|
||||||
}
|
}
|
||||||
if published := toLocalTime(p.Published); !published.IsZero() {
|
if published := toLocalTime(p.Published); !published.IsZero() {
|
||||||
hb.WriteElementOpen("meta", "itemprop", "datePublished", "content", published.Format(time.RFC3339))
|
hb.WriteElementOpen("meta", "itemprop", "datePublished", "content", published.Format(time.RFC3339))
|
||||||
|
@ -416,8 +402,6 @@ func (a *goBlog) renderPostHeadMeta(hb *htmlbuilder.HtmlBuilder, p *post, canoni
|
||||||
}
|
}
|
||||||
for _, img := range a.photoLinks(p) {
|
for _, img := range a.photoLinks(p) {
|
||||||
hb.WriteElementOpen("meta", "itemprop", "image", "content", img)
|
hb.WriteElementOpen("meta", "itemprop", "image", "content", img)
|
||||||
hb.WriteElementOpen("meta", "property", "og:image", "content", img)
|
|
||||||
hb.WriteElementOpen("meta", "property", "twitter:image", "content", img)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,12 +113,6 @@ func (a *goBlog) verifyMention(m *mention) error {
|
||||||
}
|
}
|
||||||
return a.db.deleteWebmention(m)
|
return a.db.deleteWebmention(m)
|
||||||
}
|
}
|
||||||
if cr := []rune(m.Content); len(cr) > 500 {
|
|
||||||
m.Content = string(cr[0:497]) + "…"
|
|
||||||
}
|
|
||||||
if tr := []rune(m.Title); len(tr) > 60 {
|
|
||||||
m.Title = string(tr[0:57]) + "…"
|
|
||||||
}
|
|
||||||
newStatus := webmentionStatusVerified
|
newStatus := webmentionStatusVerified
|
||||||
// Update or insert webmention
|
// Update or insert webmention
|
||||||
if a.db.webmentionExists(m) {
|
if a.db.webmentionExists(m) {
|
||||||
|
|
Loading…
Reference in New Issue