2022-01-20 17:22:10 +00:00
|
|
|
package main
|
|
|
|
|
2022-02-11 15:19:10 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
2022-04-16 19:42:09 +00:00
|
|
|
"strings"
|
2022-02-11 15:19:10 +00:00
|
|
|
"time"
|
2022-04-14 06:48:54 +00:00
|
|
|
|
2022-07-21 17:09:50 +00:00
|
|
|
"github.com/samber/lo"
|
2022-04-14 06:48:54 +00:00
|
|
|
"go.goblog.app/app/pkgs/bufferpool"
|
2022-08-12 10:48:16 +00:00
|
|
|
"go.goblog.app/app/pkgs/htmlbuilder"
|
2022-02-11 15:19:10 +00:00
|
|
|
)
|
2022-01-20 17:22:10 +00:00
|
|
|
|
|
|
|
type summaryTyp string
|
|
|
|
|
|
|
|
const (
|
|
|
|
defaultSummary summaryTyp = "summary"
|
|
|
|
photoSummary summaryTyp = "photosummary"
|
|
|
|
)
|
|
|
|
|
|
|
|
// post summary on index pages
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderSummary(hb *htmlbuilder.HtmlBuilder, bc *configBlog, p *post, typ summaryTyp) {
|
2022-01-20 17:22:10 +00:00
|
|
|
if bc == nil || p == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if typ == "" {
|
|
|
|
typ = defaultSummary
|
|
|
|
}
|
|
|
|
// Start article
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("article", "class", "h-entry border-bottom")
|
2022-01-20 17:22:10 +00:00
|
|
|
if p.Priority > 0 {
|
|
|
|
// Is pinned post
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("p")
|
|
|
|
hb.WriteEscaped("📌 ")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(bc.Lang, "pinned"))
|
|
|
|
hb.WriteElementClose("p")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
if p.RenderedTitle != "" {
|
|
|
|
// Has title
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("h2", "class", "p-name")
|
|
|
|
hb.WriteElementOpen("a", "class", "u-url", "href", p.Path)
|
|
|
|
hb.WriteEscaped(p.RenderedTitle)
|
|
|
|
hb.WriteElementClose("a")
|
|
|
|
hb.WriteElementClose("h2")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
// Show photos in photo summary
|
|
|
|
photos := a.photoLinks(p)
|
|
|
|
if typ == photoSummary && len(photos) > 0 {
|
|
|
|
for _, photo := range photos {
|
2022-01-26 11:02:12 +00:00
|
|
|
_ = a.renderMarkdownToWriter(hb, fmt.Sprintf("![](%s)", photo), false)
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// Post meta
|
|
|
|
a.renderPostMeta(hb, p, bc, "summary")
|
|
|
|
if typ != photoSummary && a.showFull(p) {
|
|
|
|
// Show full content
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div", "class", "e-content")
|
2022-02-11 15:19:10 +00:00
|
|
|
a.postHtmlToWriter(hb, p, false)
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("div")
|
2022-01-20 17:22:10 +00:00
|
|
|
} else {
|
|
|
|
// Show summary
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("p", "class", "p-summary")
|
|
|
|
hb.WriteEscaped(a.postSummary(p))
|
|
|
|
hb.WriteElementClose("p")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
// Show link to full post
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("p")
|
2022-04-14 06:48:54 +00:00
|
|
|
prefix := bufferpool.Get()
|
2022-01-20 17:22:10 +00:00
|
|
|
if len(photos) > 0 {
|
|
|
|
// Contains photos
|
2022-04-14 06:48:54 +00:00
|
|
|
prefix.WriteString("🖼️")
|
|
|
|
}
|
2022-07-13 14:02:08 +00:00
|
|
|
if p.hasTrack() {
|
2022-04-14 06:48:54 +00:00
|
|
|
// Has GPX track
|
|
|
|
prefix.WriteString("🗺️")
|
|
|
|
}
|
|
|
|
if prefix.Len() > 0 {
|
|
|
|
prefix.WriteRune(' ')
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteEscaped(prefix.String())
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
2022-04-14 06:48:54 +00:00
|
|
|
bufferpool.Put(prefix)
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("a", "class", "u-url", "href", p.Path)
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(bc.Lang, "view"))
|
|
|
|
hb.WriteElementClose("a")
|
|
|
|
hb.WriteElementClose("p")
|
2022-01-20 17:22:10 +00:00
|
|
|
// Finish article
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("article")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// list of post taxonomy values (tags, series, etc.)
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderPostTax(hb *htmlbuilder.HtmlBuilder, p *post, b *configBlog) {
|
2022-01-20 17:22:10 +00:00
|
|
|
if b == nil || p == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Iterate over all taxonomies
|
|
|
|
for _, tax := range b.Taxonomies {
|
|
|
|
// Get all sorted taxonomy values for this post
|
|
|
|
if taxValues := sortedStrings(p.Parameters[tax.Name]); len(taxValues) > 0 {
|
|
|
|
// Start new paragraph
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("p")
|
2022-01-20 17:22:10 +00:00
|
|
|
// Add taxonomy name
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("strong")
|
|
|
|
hb.WriteEscaped(a.renderMdTitle(tax.Title))
|
|
|
|
hb.WriteElementClose("strong")
|
|
|
|
hb.WriteUnescaped(": ")
|
2022-01-20 17:22:10 +00:00
|
|
|
// Add taxonomy values
|
|
|
|
for i, taxValue := range taxValues {
|
|
|
|
if i > 0 {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteUnescaped(", ")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen(
|
2022-01-20 17:22:10 +00:00
|
|
|
"a",
|
|
|
|
"class", "p-category",
|
|
|
|
"rel", "tag",
|
|
|
|
"href", b.getRelativePath(fmt.Sprintf("/%s/%s", tax.Name, urlize(taxValue))),
|
|
|
|
)
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteEscaped(a.renderMdTitle(taxValue))
|
|
|
|
hb.WriteElementClose("a")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
// End paragraph
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("p")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// post meta information.
|
|
|
|
// typ can be "summary", "post" or "preview".
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderPostMeta(hb *htmlbuilder.HtmlBuilder, p *post, b *configBlog, typ string) {
|
2022-01-20 17:22:10 +00:00
|
|
|
if b == nil || p == nil || typ != "summary" && typ != "post" && typ != "preview" {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if typ == "summary" || typ == "post" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div", "class", "p")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
// Published time
|
2022-02-11 15:19:10 +00:00
|
|
|
if published := toLocalTime(p.Published); !published.IsZero() {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(b.Lang, "publishedon"))
|
|
|
|
hb.WriteUnescaped(" ")
|
|
|
|
hb.WriteElementOpen("time", "class", "dt-published", "datetime", published.Format(time.RFC3339))
|
|
|
|
hb.WriteEscaped(published.Format(isoDateFormat))
|
|
|
|
hb.WriteElementClose("time")
|
2022-01-20 17:22:10 +00:00
|
|
|
// Section
|
|
|
|
if p.Section != "" {
|
|
|
|
if section := b.Sections[p.Section]; section != nil {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteUnescaped(" in ") // TODO: Replace with a proper translation
|
|
|
|
hb.WriteElementOpen("a", "href", b.getRelativePath(section.Name))
|
|
|
|
hb.WriteEscaped(a.renderMdTitle(section.Title))
|
|
|
|
hb.WriteElementClose("a")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("div")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
// Updated time
|
2022-02-11 15:19:10 +00:00
|
|
|
if updated := toLocalTime(p.Updated); !updated.IsZero() {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(b.Lang, "updatedon"))
|
|
|
|
hb.WriteUnescaped(" ")
|
|
|
|
hb.WriteElementOpen("time", "class", "dt-updated", "datetime", updated.Format(time.RFC3339))
|
|
|
|
hb.WriteEscaped(updated.Format(isoDateFormat))
|
|
|
|
hb.WriteElementClose("time")
|
|
|
|
hb.WriteElementClose("div")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
// IndieWeb Meta
|
2022-07-31 17:49:58 +00:00
|
|
|
a.renderPostReplyContext(hb, p, "")
|
|
|
|
a.renderPostLikeContext(hb, p, "")
|
2022-01-20 17:22:10 +00:00
|
|
|
// Geo
|
2022-05-26 18:03:53 +00:00
|
|
|
if geoURIs := a.geoURIs(p); len(geoURIs) != 0 {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div")
|
|
|
|
hb.WriteEscaped("📍 ")
|
2022-05-26 18:03:53 +00:00
|
|
|
for i, geoURI := range geoURIs {
|
|
|
|
if i > 0 {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteEscaped(", ")
|
2022-05-26 18:03:53 +00:00
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("a", "class", "p-location h-geo", "target", "_blank", "rel", "nofollow noopener noreferrer", "href", geoOSMLink(geoURI))
|
|
|
|
hb.WriteElementOpen("span", "class", "p-name")
|
|
|
|
hb.WriteEscaped(a.geoTitle(geoURI, b.Lang))
|
|
|
|
hb.WriteElementClose("span")
|
|
|
|
hb.WriteElementOpen("data", "class", "p-longitude", "value", fmt.Sprintf("%f", geoURI.Longitude))
|
|
|
|
hb.WriteElementClose("data")
|
|
|
|
hb.WriteElementOpen("data", "class", "p-latitude", "value", fmt.Sprintf("%f", geoURI.Latitude))
|
|
|
|
hb.WriteElementClose("data")
|
|
|
|
hb.WriteElementClose("a")
|
2022-05-26 18:03:53 +00:00
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("div")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
// Post specific elements
|
|
|
|
if typ == "post" {
|
|
|
|
// Translations
|
|
|
|
if translations := a.postTranslations(p); len(translations) > 0 {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(b.Lang, "translations"))
|
|
|
|
hb.WriteEscaped(": ")
|
2022-01-20 17:22:10 +00:00
|
|
|
for i, translation := range translations {
|
|
|
|
if i > 0 {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteEscaped(", ")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("a", "translate", "no", "href", translation.Path)
|
|
|
|
hb.WriteEscaped(translation.RenderedTitle)
|
|
|
|
hb.WriteElementClose("a")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("div")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
// Short link
|
|
|
|
if shortLink := a.shortPostURL(p); shortLink != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(b.Lang, "shorturl"))
|
|
|
|
hb.WriteEscaped(" ")
|
|
|
|
hb.WriteElementOpen("a", "rel", "shortlink", "href", shortLink)
|
|
|
|
hb.WriteEscaped(shortLink)
|
|
|
|
hb.WriteElementClose("a")
|
|
|
|
hb.WriteElementClose("div")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
// Status
|
|
|
|
if p.Status != statusPublished {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(b.Lang, "status"))
|
|
|
|
hb.WriteEscaped(": ")
|
|
|
|
hb.WriteEscaped(string(p.Status))
|
|
|
|
hb.WriteElementClose("div")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
2022-09-23 09:05:07 +00:00
|
|
|
// Visibility
|
|
|
|
if p.Visibility != visibilityPublic {
|
|
|
|
hb.WriteElementOpen("div")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(b.Lang, "visibility"))
|
|
|
|
hb.WriteEscaped(": ")
|
|
|
|
hb.WriteEscaped(string(p.Visibility))
|
|
|
|
hb.WriteElementClose("div")
|
|
|
|
}
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
if typ == "summary" || typ == "post" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("div")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-31 17:49:58 +00:00
|
|
|
// Reply ("u-in-reply-to")
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderPostReplyContext(hb *htmlbuilder.HtmlBuilder, p *post, htmlWrapperElement string) {
|
2022-07-31 17:49:58 +00:00
|
|
|
if htmlWrapperElement == "" {
|
|
|
|
htmlWrapperElement = "div"
|
|
|
|
}
|
|
|
|
if replyLink := a.replyLink(p); replyLink != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
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)
|
2022-07-31 17:49:58 +00:00
|
|
|
if replyTitle := a.replyTitle(p); replyTitle != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteEscaped(replyTitle)
|
2022-07-31 17:49:58 +00:00
|
|
|
} else {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteEscaped(replyLink)
|
2022-07-31 17:49:58 +00:00
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("a")
|
|
|
|
hb.WriteElementClose(htmlWrapperElement)
|
2022-07-31 17:49:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Like ("u-like-of")
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderPostLikeContext(hb *htmlbuilder.HtmlBuilder, p *post, htmlWrapperElement string) {
|
2022-07-31 17:49:58 +00:00
|
|
|
if htmlWrapperElement == "" {
|
|
|
|
htmlWrapperElement = "div"
|
|
|
|
}
|
|
|
|
if likeLink := a.likeLink(p); likeLink != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen(htmlWrapperElement)
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(a.getBlogFromPost(p).Lang, "likeof"))
|
|
|
|
hb.WriteEscaped(": ")
|
|
|
|
hb.WriteElementOpen("a", "class", "u-like-of", "rel", "noopener", "target", "_blank", "href", likeLink)
|
2022-07-31 17:49:58 +00:00
|
|
|
if likeTitle := a.likeTitle(p); likeTitle != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteEscaped(likeTitle)
|
2022-07-31 17:49:58 +00:00
|
|
|
} else {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteEscaped(likeLink)
|
2022-07-31 17:49:58 +00:00
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("a")
|
|
|
|
hb.WriteElementClose(htmlWrapperElement)
|
2022-07-31 17:49:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-20 17:22:10 +00:00
|
|
|
// warning for old posts
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderOldContentWarning(hb *htmlbuilder.HtmlBuilder, p *post, b *configBlog) {
|
2022-07-21 17:09:50 +00:00
|
|
|
if b == nil || b.hideOldContentWarning || p == nil || !p.Old() {
|
2022-01-20 17:22:10 +00:00
|
|
|
return
|
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("strong", "class", "p border-top border-bottom")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(b.Lang, "oldcontent"))
|
|
|
|
hb.WriteElementClose("strong")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
|
2022-10-07 15:08:37 +00:00
|
|
|
func (a *goBlog) renderShareButton(hb *htmlbuilder.HtmlBuilder, p *post, b *configBlog) {
|
|
|
|
if b == nil || b.hideShareButton {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
hb.WriteElementOpen("a", "class", "button", "href", fmt.Sprintf("https://www.addtoany.com/share#url=%s%s", a.shortPostURL(p), lo.If(p.RenderedTitle != "", "&title="+p.RenderedTitle).Else("")), "target", "_blank", "rel", "nofollow noopener noreferrer")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(b.Lang, "share"))
|
|
|
|
hb.WriteElementClose("a")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *goBlog) renderTranslateButton(hb *htmlbuilder.HtmlBuilder, p *post, b *configBlog) {
|
|
|
|
if b == nil || b.hideTranslateButton {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
hb.WriteElementOpen(
|
|
|
|
"a", "id", "translateBtn",
|
|
|
|
"class", "button",
|
|
|
|
"href", fmt.Sprintf("https://translate.google.com/translate?u=%s", a.getFullAddress(p.Path)),
|
|
|
|
"target", "_blank", "rel", "nofollow noopener noreferrer",
|
|
|
|
"title", a.ts.GetTemplateStringVariant(b.Lang, "translate"),
|
|
|
|
"translate", "no",
|
|
|
|
)
|
|
|
|
hb.WriteEscaped("A ⇄ 文")
|
|
|
|
hb.WriteElementClose("a")
|
|
|
|
hb.WriteElementOpen("script", "defer", "", "src", a.assetFileName("js/translate.js"))
|
|
|
|
hb.WriteElementClose("script")
|
|
|
|
}
|
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderInteractions(hb *htmlbuilder.HtmlBuilder, rd *renderData) {
|
2022-01-20 17:22:10 +00:00
|
|
|
// Start accordion
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("details", "class", "p", "id", "interactions")
|
|
|
|
hb.WriteElementOpen("summary")
|
|
|
|
hb.WriteElementOpen("strong")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "interactions"))
|
|
|
|
hb.WriteElementClose("strong")
|
|
|
|
hb.WriteElementClose("summary")
|
2022-01-20 17:22:10 +00:00
|
|
|
// Render mentions
|
|
|
|
var renderMentions func(m []*mention)
|
|
|
|
renderMentions = func(m []*mention) {
|
|
|
|
if len(m) == 0 {
|
|
|
|
return
|
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("ul")
|
2022-01-20 17:22:10 +00:00
|
|
|
for _, mention := range m {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("li")
|
|
|
|
hb.WriteElementOpen("a", "href", mention.Url, "target", "_blank", "rel", "nofollow noopener noreferrer ugc")
|
|
|
|
hb.WriteEscaped(defaultIfEmpty(mention.Author, mention.Url))
|
|
|
|
hb.WriteElementClose("a")
|
2022-01-20 17:22:10 +00:00
|
|
|
if mention.Title != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteUnescaped(" ")
|
|
|
|
hb.WriteElementOpen("strong")
|
|
|
|
hb.WriteEscaped(mention.Title)
|
|
|
|
hb.WriteElementClose("strong")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
if mention.Content != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteUnescaped(" ")
|
|
|
|
hb.WriteElementOpen("i")
|
|
|
|
hb.WriteEscaped(mention.Content)
|
|
|
|
hb.WriteElementClose("i")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
if len(mention.Submentions) > 0 {
|
|
|
|
renderMentions(mention.Submentions)
|
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("li")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("ul")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
2022-01-30 15:40:53 +00:00
|
|
|
renderMentions(a.db.getWebmentionsByAddress(rd.Canonical))
|
2022-01-20 17:22:10 +00:00
|
|
|
// Show form to send a webmention
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("form", "class", "fw p", "method", "post", "action", "/webmention")
|
|
|
|
hb.WriteElementOpen("label", "for", "wm-source", "class", "p")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "interactionslabel"))
|
|
|
|
hb.WriteElementClose("label")
|
|
|
|
hb.WriteElementOpen("input", "id", "wm-source", "type", "url", "name", "source", "placeholder", "URL", "required", "")
|
|
|
|
hb.WriteElementOpen("input", "type", "hidden", "name", "target", "value", rd.Canonical)
|
|
|
|
hb.WriteElementOpen("input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "send"))
|
|
|
|
hb.WriteElementClose("form")
|
2022-01-20 17:22:10 +00:00
|
|
|
// Show form to create a new comment
|
2022-12-06 19:02:03 +00:00
|
|
|
hb.WriteElementOpen("form", "class", "fw p", "method", "post", "action", rd.Blog.getRelativePath(commentPath))
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("input", "type", "hidden", "name", "target", "value", rd.Canonical)
|
|
|
|
hb.WriteElementOpen("input", "type", "text", "name", "name", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "nameopt"))
|
|
|
|
hb.WriteElementOpen("input", "type", "url", "name", "website", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "websiteopt"))
|
|
|
|
hb.WriteElementOpen("textarea", "name", "comment", "required", "", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "comment"))
|
|
|
|
hb.WriteElementClose("textarea")
|
|
|
|
hb.WriteElementOpen("input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "docomment"))
|
|
|
|
hb.WriteElementClose("form")
|
2022-01-20 17:22:10 +00:00
|
|
|
// Finish accordion
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("details")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// author h-card
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderAuthor(hb *htmlbuilder.HtmlBuilder) {
|
2022-01-20 17:22:10 +00:00
|
|
|
user := a.cfg.User
|
|
|
|
if user == nil {
|
|
|
|
return
|
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div", "class", "p-author h-card hide")
|
2022-11-27 14:06:43 +00:00
|
|
|
if a.hasProfileImage() {
|
|
|
|
hb.WriteElementOpen("data", "class", "u-photo", "value", a.profileImagePath(profileImageFormatJPEG, 0, 0))
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("data")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
if user.Name != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("a", "class", "p-name u-url", "rel", "me", "href", defaultIfEmpty(user.Link, "/"))
|
|
|
|
hb.WriteEscaped(user.Name)
|
|
|
|
hb.WriteElementClose("a")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("div")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// head meta tags for a post
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderPostHeadMeta(hb *htmlbuilder.HtmlBuilder, p *post, canonical string) {
|
2022-01-20 17:22:10 +00:00
|
|
|
if p == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if canonical != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("meta", "property", "og:url", "content", canonical)
|
|
|
|
hb.WriteElementOpen("meta", "property", "twitter:url", "content", canonical)
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
if p.RenderedTitle != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("meta", "property", "og:title", "content", p.RenderedTitle)
|
|
|
|
hb.WriteElementOpen("meta", "property", "twitter:title", "content", p.RenderedTitle)
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
if summary := a.postSummary(p); summary != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("meta", "name", "description", "content", summary)
|
|
|
|
hb.WriteElementOpen("meta", "property", "og:description", "content", summary)
|
|
|
|
hb.WriteElementOpen("meta", "property", "twitter:description", "content", summary)
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
2022-02-11 15:19:10 +00:00
|
|
|
if published := toLocalTime(p.Published); !published.IsZero() {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("meta", "itemprop", "datePublished", "content", published.Format(time.RFC3339))
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
2022-02-11 15:19:10 +00:00
|
|
|
if updated := toLocalTime(p.Updated); !updated.IsZero() {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("meta", "itemprop", "dateModified", "content", updated.Format(time.RFC3339))
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
for _, img := range a.photoLinks(p) {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("meta", "itemprop", "image", "content", img)
|
|
|
|
hb.WriteElementOpen("meta", "property", "og:image", "content", img)
|
|
|
|
hb.WriteElementOpen("meta", "property", "twitter:image", "content", img)
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TOR notice in the footer
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderTorNotice(hb *htmlbuilder.HtmlBuilder, rd *renderData) {
|
2022-01-20 17:22:10 +00:00
|
|
|
if !a.cfg.Server.Tor || (!rd.TorUsed && rd.TorAddress == "") {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if rd.TorUsed {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("p", "id", "tor")
|
|
|
|
hb.WriteEscaped("🔐 ")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "connectedviator"))
|
|
|
|
hb.WriteElementClose("p")
|
2022-01-20 17:22:10 +00:00
|
|
|
} else if rd.TorAddress != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("p", "id", "tor")
|
|
|
|
hb.WriteEscaped("🔓 ")
|
|
|
|
hb.WriteElementOpen("a", "href", rd.TorAddress)
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "connectviator"))
|
|
|
|
hb.WriteElementClose("a")
|
|
|
|
hb.WriteEscaped(" ")
|
|
|
|
hb.WriteElementOpen("a", "href", "https://www.torproject.org/", "target", "_blank", "rel", "nofollow noopener noreferrer")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "whatistor"))
|
|
|
|
hb.WriteElementClose("a")
|
|
|
|
hb.WriteElementClose("p")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderTitleTag(hb *htmlbuilder.HtmlBuilder, blog *configBlog, optionalTitle string) {
|
|
|
|
hb.WriteElementOpen("title")
|
2022-01-20 17:22:10 +00:00
|
|
|
if optionalTitle != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteEscaped(optionalTitle)
|
|
|
|
hb.WriteEscaped(" - ")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteEscaped(a.renderMdTitle(blog.Title))
|
|
|
|
hb.WriteElementClose("title")
|
2022-01-20 17:22:10 +00:00
|
|
|
}
|
2022-01-27 17:17:44 +00:00
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderPagination(hb *htmlbuilder.HtmlBuilder, blog *configBlog, hasPrev, hasNext bool, prev, next string) {
|
2022-01-27 17:17:44 +00:00
|
|
|
// Navigation
|
|
|
|
if hasPrev {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("p")
|
|
|
|
hb.WriteElementOpen("a", "href", prev) // TODO: rel=prev?
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(blog.Lang, "prev"))
|
|
|
|
hb.WriteElementClose("a")
|
|
|
|
hb.WriteElementClose("p")
|
2022-01-27 17:17:44 +00:00
|
|
|
}
|
|
|
|
if hasNext {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("p")
|
|
|
|
hb.WriteElementOpen("a", "href", next) // TODO: rel=next?
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(blog.Lang, "next"))
|
|
|
|
hb.WriteElementClose("a")
|
|
|
|
hb.WriteElementClose("p")
|
2022-01-27 17:17:44 +00:00
|
|
|
}
|
|
|
|
}
|
2022-04-15 18:53:19 +00:00
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
func (*goBlog) renderPostTitle(hb *htmlbuilder.HtmlBuilder, p *post) {
|
2022-04-15 18:53:19 +00:00
|
|
|
if p == nil || p.RenderedTitle == "" {
|
|
|
|
return
|
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("h1", "class", "p-name")
|
|
|
|
hb.WriteEscaped(p.RenderedTitle)
|
|
|
|
hb.WriteElementClose("h1")
|
2022-04-15 18:53:19 +00:00
|
|
|
}
|
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderPostGPX(hb *htmlbuilder.HtmlBuilder, p *post, b *configBlog) {
|
2022-07-13 14:02:08 +00:00
|
|
|
if p == nil || !p.hasTrack() {
|
2022-04-15 18:53:19 +00:00
|
|
|
return
|
|
|
|
}
|
2022-07-13 14:02:08 +00:00
|
|
|
track, err := a.getTrack(p, p.showTrackRoute())
|
|
|
|
if err != nil || track == nil {
|
2022-04-15 18:53:19 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
// Track stats
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("p")
|
2022-04-15 18:53:19 +00:00
|
|
|
if track.Name != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("strong")
|
|
|
|
hb.WriteEscaped(track.Name)
|
|
|
|
hb.WriteElementClose("strong")
|
|
|
|
hb.WriteUnescaped(" ")
|
2022-04-15 18:53:19 +00:00
|
|
|
}
|
|
|
|
if track.Kilometers != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteUnescaped("🏁 ")
|
|
|
|
hb.WriteEscaped(track.Kilometers)
|
|
|
|
hb.WriteUnescaped(" ")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(b.Lang, "kilometers"))
|
|
|
|
hb.WriteUnescaped(" ")
|
2022-04-15 18:53:19 +00:00
|
|
|
}
|
|
|
|
if track.Hours != "" {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteUnescaped("⏱ ")
|
|
|
|
hb.WriteEscaped(track.Hours)
|
2022-04-15 18:53:19 +00:00
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("p")
|
2022-07-13 14:02:08 +00:00
|
|
|
// Map (only show if it has features)
|
|
|
|
if track.hasMapFeatures() {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen(
|
2022-07-13 14:02:08 +00:00
|
|
|
"div", "id", "map", "class", "p",
|
|
|
|
"data-paths", track.PathsJSON,
|
|
|
|
"data-points", track.PointsJSON,
|
|
|
|
"data-minzoom", track.MinZoom, "data-maxzoom", track.MaxZoom,
|
|
|
|
"data-attribution", track.MapAttribution,
|
|
|
|
)
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("div")
|
|
|
|
hb.WriteElementOpen("script", "defer", "", "src", a.assetFileName("js/geomap.js"))
|
|
|
|
hb.WriteElementClose("script")
|
2022-07-13 14:02:08 +00:00
|
|
|
}
|
2022-04-15 18:53:19 +00:00
|
|
|
}
|
2022-04-16 19:42:09 +00:00
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderPostReactions(hb *htmlbuilder.HtmlBuilder, p *post) {
|
2022-04-16 19:42:09 +00:00
|
|
|
if !a.reactionsEnabledForPost(p) {
|
|
|
|
return
|
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div", "id", "reactions", "class", "actions", "data-path", p.Path, "data-allowed", strings.Join(allowedReactions, ","))
|
|
|
|
hb.WriteElementClose("div")
|
|
|
|
hb.WriteElementOpen("script", "defer", "", "src", a.assetFileName("js/reactions.js"))
|
|
|
|
hb.WriteElementClose("script")
|
2022-04-16 19:42:09 +00:00
|
|
|
}
|
2022-05-27 07:48:57 +00:00
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderPostVideo(hb *htmlbuilder.HtmlBuilder, p *post) {
|
2022-05-27 07:48:57 +00:00
|
|
|
if !p.hasVideoPlaylist() {
|
|
|
|
return
|
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div", "id", "video", "data-url", p.firstParameter(videoPlaylistParam))
|
|
|
|
hb.WriteElementClose("div")
|
|
|
|
hb.WriteElementOpen("script", "defer", "", "src", a.assetFileName("js/video.js"))
|
|
|
|
hb.WriteElementClose("script")
|
2022-05-27 07:48:57 +00:00
|
|
|
}
|
2022-07-21 17:09:50 +00:00
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
func (a *goBlog) renderPostSectionSettings(hb *htmlbuilder.HtmlBuilder, rd *renderData, srd *settingsRenderData) {
|
|
|
|
hb.WriteElementOpen("h2")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "postsections"))
|
|
|
|
hb.WriteElementClose("h2")
|
2022-07-21 17:09:50 +00:00
|
|
|
|
|
|
|
// Update default section
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("h3")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "default"))
|
|
|
|
hb.WriteElementClose("h3")
|
2022-07-21 17:09:50 +00:00
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("form", "class", "fw p", "method", "post")
|
|
|
|
hb.WriteElementOpen("select", "name", "defaultsection")
|
2022-07-21 17:09:50 +00:00
|
|
|
for _, section := range srd.sections {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("option", "value", section.Name, lo.If(section.Name == srd.defaultSection, "selected").Else(""), "")
|
|
|
|
hb.WriteEscaped(section.Name)
|
|
|
|
hb.WriteElementClose("option")
|
2022-07-21 17:09:50 +00:00
|
|
|
}
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("select")
|
|
|
|
hb.WriteElementOpen(
|
2022-07-21 17:09:50 +00:00
|
|
|
"input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "update"),
|
|
|
|
"formaction", rd.Blog.getRelativePath(settingsPath+settingsUpdateDefaultSectionPath),
|
|
|
|
)
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("form")
|
2022-07-21 17:09:50 +00:00
|
|
|
|
|
|
|
for _, section := range srd.sections {
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("details")
|
2022-07-21 17:09:50 +00:00
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("summary")
|
|
|
|
hb.WriteElementOpen("h3")
|
|
|
|
hb.WriteEscaped(section.Name)
|
|
|
|
hb.WriteElementClose("h3")
|
|
|
|
hb.WriteElementClose("summary")
|
2022-07-21 17:09:50 +00:00
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("form", "class", "fw p", "method", "post")
|
2022-07-21 17:09:50 +00:00
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("input", "type", "hidden", "name", "sectionname", "value", section.Name)
|
2022-07-21 17:09:50 +00:00
|
|
|
|
|
|
|
// Title
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("input", "type", "text", "name", "sectiontitle", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectiontitle"), "required", "", "value", section.Title)
|
2022-07-21 17:09:50 +00:00
|
|
|
// Description
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen(
|
2022-07-21 17:09:50 +00:00
|
|
|
"textarea",
|
|
|
|
"name", "sectiondescription",
|
|
|
|
"class", "monospace",
|
|
|
|
"placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectiondescription"),
|
|
|
|
)
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteEscaped(section.Description)
|
|
|
|
hb.WriteElementClose("textarea")
|
2022-07-21 17:09:50 +00:00
|
|
|
// Path template
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("input", "type", "text", "name", "sectionpathtemplate", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectionpathtemplate"), "value", section.PathTemplate)
|
2022-07-21 17:09:50 +00:00
|
|
|
// Show full
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("input", "type", "checkbox", "name", "sectionshowfull", "id", "showfull-"+section.Name, lo.If(section.ShowFull, "checked").Else(""), "")
|
|
|
|
hb.WriteElementOpen("label", "for", "showfull-"+section.Name)
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectionshowfull"))
|
|
|
|
hb.WriteElementClose("label")
|
2022-07-21 17:09:50 +00:00
|
|
|
|
|
|
|
// Actions
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div", "class", "p")
|
2022-07-21 17:09:50 +00:00
|
|
|
// Update
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen(
|
2022-07-21 17:09:50 +00:00
|
|
|
"input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "update"),
|
|
|
|
"formaction", rd.Blog.getRelativePath(settingsPath+settingsUpdateSectionPath),
|
|
|
|
)
|
|
|
|
// Delete
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen(
|
2022-07-21 17:09:50 +00:00
|
|
|
"input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "delete"),
|
|
|
|
"formaction", rd.Blog.getRelativePath(settingsPath+settingsDeleteSectionPath),
|
|
|
|
"class", "confirm", "data-confirmmessage", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "confirmdelete"),
|
|
|
|
)
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("div")
|
2022-07-21 17:09:50 +00:00
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("form")
|
|
|
|
hb.WriteElementClose("details")
|
2022-07-21 17:09:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create new section
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("form", "class", "fw p", "method", "post")
|
2022-07-21 17:09:50 +00:00
|
|
|
// Name
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("input", "type", "text", "name", "sectionname", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectionname"), "required", "")
|
2022-07-21 17:09:50 +00:00
|
|
|
// Title
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("input", "type", "text", "name", "sectiontitle", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectiontitle"), "required", "")
|
2022-07-21 17:09:50 +00:00
|
|
|
// Create button
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div")
|
|
|
|
hb.WriteElementOpen(
|
2022-07-21 17:09:50 +00:00
|
|
|
"input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "create"),
|
|
|
|
"formaction", rd.Blog.getRelativePath(settingsPath+settingsCreateSectionPath),
|
|
|
|
)
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("div")
|
|
|
|
hb.WriteElementClose("form")
|
2022-07-21 17:09:50 +00:00
|
|
|
}
|
|
|
|
|
2022-10-07 15:08:37 +00:00
|
|
|
func (a *goBlog) renderBooleanSetting(hb *htmlbuilder.HtmlBuilder, rd *renderData, path, description, name string, value bool) {
|
|
|
|
hb.WriteElementOpen("form", "class", "fw p", "method", "post", "action", path)
|
2022-07-21 17:09:50 +00:00
|
|
|
|
2022-10-07 15:08:37 +00:00
|
|
|
hb.WriteElementOpen("input", "type", "checkbox", "class", "autosubmit", "name", name, "id", "cb-"+name, lo.If(value, "checked").Else(""), "")
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("label", "for", "cb-"+name)
|
|
|
|
hb.WriteEscaped(description)
|
|
|
|
hb.WriteElementClose("label")
|
2022-07-21 17:09:50 +00:00
|
|
|
|
2022-10-07 15:08:37 +00:00
|
|
|
hb.WriteElementOpen("noscript")
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementOpen("div", "class", "p")
|
|
|
|
hb.WriteElementOpen(
|
2022-10-07 15:08:37 +00:00
|
|
|
"input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "update"),
|
2022-07-21 17:09:50 +00:00
|
|
|
)
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("div")
|
2022-10-07 15:08:37 +00:00
|
|
|
hb.WriteElementClose("noscript")
|
2022-07-21 17:09:50 +00:00
|
|
|
|
2022-08-12 10:48:16 +00:00
|
|
|
hb.WriteElementClose("form")
|
2022-07-21 17:09:50 +00:00
|
|
|
}
|
2022-11-27 06:20:49 +00:00
|
|
|
|
|
|
|
func (a *goBlog) renderUserSettings(hb *htmlbuilder.HtmlBuilder, rd *renderData, srd *settingsRenderData) {
|
|
|
|
hb.WriteElementOpen("h2")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "user"))
|
|
|
|
hb.WriteElementClose("h2")
|
|
|
|
|
|
|
|
hb.WriteElementOpen("form", "class", "fw p", "method", "post")
|
|
|
|
hb.WriteElementOpen("input", "type", "text", "name", "usernick", "required", "", "value", srd.userNick, "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "settingsusernick"))
|
|
|
|
hb.WriteElementOpen("input", "type", "text", "name", "username", "required", "", "value", srd.userName, "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "settingsusername"))
|
|
|
|
hb.WriteElementOpen(
|
|
|
|
"input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "update"),
|
|
|
|
"formaction", rd.Blog.getRelativePath(settingsPath+settingsUpdateUserPath),
|
|
|
|
)
|
|
|
|
hb.WriteElementClose("form")
|
2022-11-27 14:06:43 +00:00
|
|
|
|
|
|
|
hb.WriteElementOpen("h3")
|
|
|
|
hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "profileimage"))
|
|
|
|
hb.WriteElementClose("h3")
|
|
|
|
|
|
|
|
hb.WriteElementOpen("form", "class", "fw p", "method", "post", "enctype", "multipart/form-data")
|
|
|
|
hb.WriteElementOpen("input", "type", "file", "name", "file")
|
|
|
|
hb.WriteElementOpen(
|
|
|
|
"input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "upload"),
|
|
|
|
"formaction", rd.Blog.getRelativePath(settingsPath+settingsUpdateProfileImagePath),
|
|
|
|
)
|
|
|
|
hb.WriteElementClose("form")
|
|
|
|
|
|
|
|
hb.WriteElementOpen("form", "class", "fw p", "method", "post")
|
|
|
|
hb.WriteElementOpen(
|
|
|
|
"input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "delete"),
|
|
|
|
"formaction", rd.Blog.getRelativePath(settingsPath+settingsDeleteProfileImagePath),
|
|
|
|
)
|
|
|
|
hb.WriteElementClose("form")
|
2022-11-27 06:20:49 +00:00
|
|
|
}
|