@ -7,6 +7,7 @@ import (
"github.com/samber/lo"
"go.goblog.app/app/pkgs/bufferpool"
"go.goblog.app/app/pkgs/htmlbuilder"
)
type summaryTyp string
@ -17,7 +18,7 @@ const (
)
// post summary on index pages
func ( a * goBlog ) renderSummary ( hb * html Builder, bc * configBlog , p * post , typ summaryTyp ) {
func ( a * goBlog ) renderSummary ( hb * html builder. Html Builder, bc * configBlog , p * post , typ summaryTyp ) {
if bc == nil || p == nil {
return
}
@ -25,21 +26,21 @@ func (a *goBlog) renderSummary(hb *htmlBuilder, bc *configBlog, p *post, typ sum
typ = defaultSummary
}
// Start article
hb . w riteElementOpen( "article" , "class" , "h-entry border-bottom" )
hb . W riteElementOpen( "article" , "class" , "h-entry border-bottom" )
if p . Priority > 0 {
// Is pinned post
hb . w riteElementOpen( "p" )
hb . w riteEscaped( "📌 " )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( bc . Lang , "pinned" ) )
hb . w riteElementClose( "p" )
hb . W riteElementOpen( "p" )
hb . W riteEscaped( "📌 " )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( bc . Lang , "pinned" ) )
hb . W riteElementClose( "p" )
}
if p . RenderedTitle != "" {
// Has title
hb . w riteElementOpen( "h2" , "class" , "p-name" )
hb . w riteElementOpen( "a" , "class" , "u-url" , "href" , p . Path )
hb . w riteEscaped( p . RenderedTitle )
hb . w riteElementClose( "a" )
hb . w riteElementClose( "h2" )
hb . W riteElementOpen( "h2" , "class" , "p-name" )
hb . W riteElementOpen( "a" , "class" , "u-url" , "href" , p . Path )
hb . W riteEscaped( p . RenderedTitle )
hb . W riteElementClose( "a" )
hb . W riteElementClose( "h2" )
}
// Show photos in photo summary
photos := a . photoLinks ( p )
@ -52,17 +53,17 @@ func (a *goBlog) renderSummary(hb *htmlBuilder, bc *configBlog, p *post, typ sum
a . renderPostMeta ( hb , p , bc , "summary" )
if typ != photoSummary && a . showFull ( p ) {
// Show full content
hb . w riteElementOpen( "div" , "class" , "e-content" )
hb . W riteElementOpen( "div" , "class" , "e-content" )
a . postHtmlToWriter ( hb , p , false )
hb . w riteElementClose( "div" )
hb . W riteElementClose( "div" )
} else {
// Show summary
hb . w riteElementOpen( "p" , "class" , "p-summary" )
hb . w riteEscaped( a . postSummary ( p ) )
hb . w riteElementClose( "p" )
hb . W riteElementOpen( "p" , "class" , "p-summary" )
hb . W riteEscaped( a . postSummary ( p ) )
hb . W riteElementClose( "p" )
}
// Show link to full post
hb . w riteElementOpen( "p" )
hb . W riteElementOpen( "p" )
prefix := bufferpool . Get ( )
if len ( photos ) > 0 {
// Contains photos
@ -74,19 +75,19 @@ func (a *goBlog) renderSummary(hb *htmlBuilder, bc *configBlog, p *post, typ sum
}
if prefix . Len ( ) > 0 {
prefix . WriteRune ( ' ' )
hb . w riteEscaped( prefix . String ( ) )
hb . W riteEscaped( prefix . String ( ) )
}
bufferpool . Put ( prefix )
hb . w riteElementOpen( "a" , "class" , "u-url" , "href" , p . Path )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( bc . Lang , "view" ) )
hb . w riteElementClose( "a" )
hb . w riteElementClose( "p" )
hb . W riteElementOpen( "a" , "class" , "u-url" , "href" , p . Path )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( bc . Lang , "view" ) )
hb . W riteElementClose( "a" )
hb . W riteElementClose( "p" )
// Finish article
hb . w riteElementClose( "article" )
hb . W riteElementClose( "article" )
}
// list of post taxonomy values (tags, series, etc.)
func ( a * goBlog ) renderPostTax ( hb * html Builder, p * post , b * configBlog ) {
func ( a * goBlog ) renderPostTax ( hb * html builder. Html Builder, p * post , b * configBlog ) {
if b == nil || p == nil {
return
}
@ -95,372 +96,372 @@ func (a *goBlog) renderPostTax(hb *htmlBuilder, p *post, b *configBlog) {
// Get all sorted taxonomy values for this post
if taxValues := sortedStrings ( p . Parameters [ tax . Name ] ) ; len ( taxValues ) > 0 {
// Start new paragraph
hb . w riteElementOpen( "p" )
hb . W riteElementOpen( "p" )
// Add taxonomy name
hb . w riteElementOpen( "strong" )
hb . w riteEscaped( a . renderMdTitle ( tax . Title ) )
hb . w riteElementClose( "strong" )
hb . write ( ": " )
hb . W riteElementOpen( "strong" )
hb . W riteEscaped( a . renderMdTitle ( tax . Title ) )
hb . W riteElementClose( "strong" )
hb . WriteUnescaped ( ": " )
// Add taxonomy values
for i , taxValue := range taxValues {
if i > 0 {
hb . write ( ", " )
hb . WriteUnescaped ( ", " )
}
hb . w riteElementOpen(
hb . W riteElementOpen(
"a" ,
"class" , "p-category" ,
"rel" , "tag" ,
"href" , b . getRelativePath ( fmt . Sprintf ( "/%s/%s" , tax . Name , urlize ( taxValue ) ) ) ,
)
hb . w riteEscaped( a . renderMdTitle ( taxValue ) )
hb . w riteElementClose( "a" )
hb . W riteEscaped( a . renderMdTitle ( taxValue ) )
hb . W riteElementClose( "a" )
}
// End paragraph
hb . w riteElementClose( "p" )
hb . W riteElementClose( "p" )
}
}
}
// post meta information.
// typ can be "summary", "post" or "preview".
func ( a * goBlog ) renderPostMeta ( hb * html Builder, p * post , b * configBlog , typ string ) {
func ( a * goBlog ) renderPostMeta ( hb * html builder. Html Builder, p * post , b * configBlog , typ string ) {
if b == nil || p == nil || typ != "summary" && typ != "post" && typ != "preview" {
return
}
if typ == "summary" || typ == "post" {
hb . w riteElementOpen( "div" , "class" , "p" )
hb . W riteElementOpen( "div" , "class" , "p" )
}
// Published time
if published := toLocalTime ( p . Published ) ; ! published . IsZero ( ) {
hb . w riteElementOpen( "div" )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "publishedon" ) )
hb . write ( " " )
hb . w riteElementOpen( "time" , "class" , "dt-published" , "datetime" , published . Format ( time . RFC3339 ) )
hb . w riteEscaped( published . Format ( isoDateFormat ) )
hb . w riteElementClose( "time" )
hb . W riteElementOpen( "div" )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "publishedon" ) )
hb . WriteUnescaped ( " " )
hb . W riteElementOpen( "time" , "class" , "dt-published" , "datetime" , published . Format ( time . RFC3339 ) )
hb . W riteEscaped( published . Format ( isoDateFormat ) )
hb . W riteElementClose( "time" )
// Section
if p . Section != "" {
if section := b . Sections [ p . Section ] ; section != nil {
hb . write ( " in " ) // TODO: Replace with a proper translation
hb . w riteElementOpen( "a" , "href" , b . getRelativePath ( section . Name ) )
hb . w riteEscaped( a . renderMdTitle ( section . Title ) )
hb . w riteElementClose( "a" )
hb . WriteUnescaped ( " in " ) // TODO: Replace with a proper translation
hb . W riteElementOpen( "a" , "href" , b . getRelativePath ( section . Name ) )
hb . W riteEscaped( a . renderMdTitle ( section . Title ) )
hb . W riteElementClose( "a" )
}
}
hb . w riteElementClose( "div" )
hb . W riteElementClose( "div" )
}
// Updated time
if updated := toLocalTime ( p . Updated ) ; ! updated . IsZero ( ) {
hb . w riteElementOpen( "div" )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "updatedon" ) )
hb . write ( " " )
hb . w riteElementOpen( "time" , "class" , "dt-updated" , "datetime" , updated . Format ( time . RFC3339 ) )
hb . w riteEscaped( updated . Format ( isoDateFormat ) )
hb . w riteElementClose( "time" )
hb . w riteElementClose( "div" )
hb . W riteElementOpen( "div" )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "updatedon" ) )
hb . WriteUnescaped ( " " )
hb . W riteElementOpen( "time" , "class" , "dt-updated" , "datetime" , updated . Format ( time . RFC3339 ) )
hb . W riteEscaped( updated . Format ( isoDateFormat ) )
hb . W riteElementClose( "time" )
hb . W riteElementClose( "div" )
}
// IndieWeb Meta
a . renderPostReplyContext ( hb , p , "" )
a . renderPostLikeContext ( hb , p , "" )
// Like ("u-like-of")
if likeLink := a . likeLink ( p ) ; likeLink != "" {
hb . w riteElementOpen( "div" )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "likeof" ) )
hb . w riteEscaped( ": " )
hb . w riteElementOpen( "a" , "class" , "u-like-of" , "rel" , "noopener" , "target" , "_blank" , "href" , likeLink )
hb . W riteElementOpen( "div" )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "likeof" ) )
hb . W riteEscaped( ": " )
hb . W riteElementOpen( "a" , "class" , "u-like-of" , "rel" , "noopener" , "target" , "_blank" , "href" , likeLink )
if likeTitle := a . likeTitle ( p ) ; likeTitle != "" {
hb . w riteEscaped( likeTitle )
hb . W riteEscaped( likeTitle )
} else {
hb . w riteEscaped( likeLink )
hb . W riteEscaped( likeLink )
}
hb . w riteElementClose( "a" )
hb . w riteElementClose( "div" )
hb . W riteElementClose( "a" )
hb . W riteElementClose( "div" )
}
// Geo
if geoURIs := a . geoURIs ( p ) ; len ( geoURIs ) != 0 {
hb . w riteElementOpen( "div" )
hb . w riteEscaped( "📍 " )
hb . W riteElementOpen( "div" )
hb . W riteEscaped( "📍 " )
for i , geoURI := range geoURIs {
if i > 0 {
hb . w riteEscaped( ", " )
hb . W riteEscaped( ", " )
}
hb . w riteElementOpen( "a" , "class" , "p-location h-geo" , "target" , "_blank" , "rel" , "nofollow noopener noreferrer" , "href" , geoOSMLink ( geoURI ) )
hb . w riteElementOpen( "span" , "class" , "p-name" )
hb . w riteEscaped( a . geoTitle ( geoURI , b . Lang ) )
hb . w riteElementClose( "span" )
hb . w riteElementOpen( "data" , "class" , "p-longitude" , "value" , fmt . Sprintf ( "%f" , geoURI . Longitude ) )
hb . w riteElementClose( "data" )
hb . w riteElementOpen( "data" , "class" , "p-latitude" , "value" , fmt . Sprintf ( "%f" , geoURI . Latitude ) )
hb . w riteElementClose( "data" )
hb . w riteElementClose( "a" )
hb . W riteElementOpen( "a" , "class" , "p-location h-geo" , "target" , "_blank" , "rel" , "nofollow noopener noreferrer" , "href" , geoOSMLink ( geoURI ) )
hb . W riteElementOpen( "span" , "class" , "p-name" )
hb . W riteEscaped( a . geoTitle ( geoURI , b . Lang ) )
hb . W riteElementClose( "span" )
hb . W riteElementOpen( "data" , "class" , "p-longitude" , "value" , fmt . Sprintf ( "%f" , geoURI . Longitude ) )
hb . W riteElementClose( "data" )
hb . W riteElementOpen( "data" , "class" , "p-latitude" , "value" , fmt . Sprintf ( "%f" , geoURI . Latitude ) )
hb . W riteElementClose( "data" )
hb . W riteElementClose( "a" )
}
hb . w riteElementClose( "div" )
hb . W riteElementClose( "div" )
}
// Post specific elements
if typ == "post" {
// Translations
if translations := a . postTranslations ( p ) ; len ( translations ) > 0 {
hb . w riteElementOpen( "div" )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "translations" ) )
hb . w riteEscaped( ": " )
hb . W riteElementOpen( "div" )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "translations" ) )
hb . W riteEscaped( ": " )
for i , translation := range translations {
if i > 0 {
hb . w riteEscaped( ", " )
hb . W riteEscaped( ", " )
}
hb . w riteElementOpen( "a" , "translate" , "no" , "href" , translation . Path )
hb . w riteEscaped( translation . RenderedTitle )
hb . w riteElementClose( "a" )
hb . W riteElementOpen( "a" , "translate" , "no" , "href" , translation . Path )
hb . W riteEscaped( translation . RenderedTitle )
hb . W riteElementClose( "a" )
}
hb . w riteElementClose( "div" )
hb . W riteElementClose( "div" )
}
// Short link
if shortLink := a . shortPostURL ( p ) ; shortLink != "" {
hb . w riteElementOpen( "div" )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "shorturl" ) )
hb . w riteEscaped( " " )
hb . w riteElementOpen( "a" , "rel" , "shortlink" , "href" , shortLink )
hb . w riteEscaped( shortLink )
hb . w riteElementClose( "a" )
hb . w riteElementClose( "div" )
hb . W riteElementOpen( "div" )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "shorturl" ) )
hb . W riteEscaped( " " )
hb . W riteElementOpen( "a" , "rel" , "shortlink" , "href" , shortLink )
hb . W riteEscaped( shortLink )
hb . W riteElementClose( "a" )
hb . W riteElementClose( "div" )
}
// Status
if p . Status != statusPublished {
hb . w riteElementOpen( "div" )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "status" ) )
hb . w riteEscaped( ": " )
hb . w riteEscaped( string ( p . Status ) )
hb . w riteElementClose( "div" )
hb . W riteElementOpen( "div" )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "status" ) )
hb . W riteEscaped( ": " )
hb . W riteEscaped( string ( p . Status ) )
hb . W riteElementClose( "div" )
}
}
if typ == "summary" || typ == "post" {
hb . w riteElementClose( "div" )
hb . W riteElementClose( "div" )
}
}
// Reply ("u-in-reply-to")
func ( a * goBlog ) renderPostReplyContext ( hb * html Builder, p * post , htmlWrapperElement string ) {
func ( a * goBlog ) renderPostReplyContext ( hb * html builder. Html Builder, p * post , htmlWrapperElement string ) {
if htmlWrapperElement == "" {
htmlWrapperElement = "div"
}
if replyLink := a . replyLink ( p ) ; replyLink != "" {
hb . w riteElementOpen( htmlWrapperElement )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( a . getBlogFromPost ( p ) . Lang , "replyto" ) )
hb . w riteEscaped( ": " )
hb . w riteElementOpen( "a" , "class" , "u-in-reply-to" , "rel" , "noopener" , "target" , "_blank" , "href" , replyLink )
hb . W riteElementOpen( htmlWrapperElement )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( a . getBlogFromPost ( p ) . Lang , "replyto" ) )
hb . W riteEscaped( ": " )
hb . W riteElementOpen( "a" , "class" , "u-in-reply-to" , "rel" , "noopener" , "target" , "_blank" , "href" , replyLink )
if replyTitle := a . replyTitle ( p ) ; replyTitle != "" {
hb . w riteEscaped( replyTitle )
hb . W riteEscaped( replyTitle )
} else {
hb . w riteEscaped( replyLink )
hb . W riteEscaped( replyLink )
}
hb . w riteElementClose( "a" )
hb . w riteElementClose( htmlWrapperElement )
hb . W riteElementClose( "a" )
hb . W riteElementClose( htmlWrapperElement )
}
}
// Like ("u-like-of")
func ( a * goBlog ) renderPostLikeContext ( hb * html Builder, p * post , htmlWrapperElement string ) {
func ( a * goBlog ) renderPostLikeContext ( hb * html builder. Html Builder, p * post , htmlWrapperElement string ) {
if htmlWrapperElement == "" {
htmlWrapperElement = "div"
}
if likeLink := a . likeLink ( p ) ; likeLink != "" {
hb . w riteElementOpen( htmlWrapperElement )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( a . getBlogFromPost ( p ) . Lang , "likeof" ) )
hb . w riteEscaped( ": " )
hb . w riteElementOpen( "a" , "class" , "u-like-of" , "rel" , "noopener" , "target" , "_blank" , "href" , likeLink )
hb . W riteElementOpen( htmlWrapperElement )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( a . getBlogFromPost ( p ) . Lang , "likeof" ) )
hb . W riteEscaped( ": " )
hb . W riteElementOpen( "a" , "class" , "u-like-of" , "rel" , "noopener" , "target" , "_blank" , "href" , likeLink )
if likeTitle := a . likeTitle ( p ) ; likeTitle != "" {
hb . w riteEscaped( likeTitle )
hb . W riteEscaped( likeTitle )
} else {
hb . w riteEscaped( likeLink )
hb . W riteEscaped( likeLink )
}
hb . w riteElementClose( "a" )
hb . w riteElementClose( htmlWrapperElement )
hb . W riteElementClose( "a" )
hb . W riteElementClose( htmlWrapperElement )
}
}
// warning for old posts
func ( a * goBlog ) renderOldContentWarning ( hb * html Builder, p * post , b * configBlog ) {
func ( a * goBlog ) renderOldContentWarning ( hb * html builder. Html Builder, p * post , b * configBlog ) {
if b == nil || b . hideOldContentWarning || p == nil || ! p . Old ( ) {
return
}
hb . w riteElementOpen( "strong" , "class" , "p border-top border-bottom" )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "oldcontent" ) )
hb . w riteElementClose( "strong" )
hb . W riteElementOpen( "strong" , "class" , "p border-top border-bottom" )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( b . Lang , "oldcontent" ) )
hb . W riteElementClose( "strong" )
}
func ( a * goBlog ) renderInteractions ( hb * html Builder, rd * renderData ) {
func ( a * goBlog ) renderInteractions ( hb * html builder. Html Builder, rd * renderData ) {
// Start accordion
hb . w riteElementOpen( "details" , "class" , "p" , "id" , "interactions" )
hb . w riteElementOpen( "summary" )
hb . w riteElementOpen( "strong" )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "interactions" ) )
hb . w riteElementClose( "strong" )
hb . w riteElementClose( "summary" )
hb . W riteElementOpen( "details" , "class" , "p" , "id" , "interactions" )
hb . W riteElementOpen( "summary" )
hb . W riteElementOpen( "strong" )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "interactions" ) )
hb . W riteElementClose( "strong" )
hb . W riteElementClose( "summary" )
// Render mentions
var renderMentions func ( m [ ] * mention )
renderMentions = func ( m [ ] * mention ) {
if len ( m ) == 0 {
return
}
hb . w riteElementOpen( "ul" )
hb . W riteElementOpen( "ul" )
for _ , mention := range m {
hb . w riteElementOpen( "li" )
hb . w riteElementOpen( "a" , "href" , mention . Url , "target" , "_blank" , "rel" , "nofollow noopener noreferrer ugc" )
hb . w riteEscaped( defaultIfEmpty ( mention . Author , mention . Url ) )
hb . w riteElementClose( "a" )
hb . W riteElementOpen( "li" )
hb . W riteElementOpen( "a" , "href" , mention . Url , "target" , "_blank" , "rel" , "nofollow noopener noreferrer ugc" )
hb . W riteEscaped( defaultIfEmpty ( mention . Author , mention . Url ) )
hb . W riteElementClose( "a" )
if mention . Title != "" {
hb . write ( " " )
hb . w riteElementOpen( "strong" )
hb . w riteEscaped( mention . Title )
hb . w riteElementClose( "strong" )
hb . WriteUnescaped ( " " )
hb . W riteElementOpen( "strong" )
hb . W riteEscaped( mention . Title )
hb . W riteElementClose( "strong" )
}
if mention . Content != "" {
hb . write ( " " )
hb . w riteElementOpen( "i" )
hb . w riteEscaped( mention . Content )
hb . w riteElementClose( "i" )
hb . WriteUnescaped ( " " )
hb . W riteElementOpen( "i" )
hb . W riteEscaped( mention . Content )
hb . W riteElementClose( "i" )
}
if len ( mention . Submentions ) > 0 {
renderMentions ( mention . Submentions )
}
hb . w riteElementClose( "li" )
hb . W riteElementClose( "li" )
}
hb . w riteElementClose( "ul" )
hb . W riteElementClose( "ul" )
}
renderMentions ( a . db . getWebmentionsByAddress ( rd . Canonical ) )
// Show form to send a webmention
hb . w riteElementOpen( "form" , "class" , "fw p" , "method" , "post" , "action" , "/webmention" )
hb . w riteElementOpen( "label" , "for" , "wm-source" , "class" , "p" )
hb . w riteEscaped( a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "interactionslabel" ) )
hb . w riteElementClose( "label" )
hb . w riteElementOpen( "input" , "id" , "wm-source" , "type" , "url" , "name" , "source" , "placeholder" , "URL" , "required" , "" )
hb . w riteElementOpen( "input" , "type" , "hidden" , "name" , "target" , "value" , rd . Canonical )
hb . w riteElementOpen( "input" , "type" , "submit" , "value" , a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "send" ) )
hb . w riteElementClose( "form" )
hb . W riteElementOpen( "form" , "class" , "fw p" , "method" , "post" , "action" , "/webmention" )
hb . W riteElementOpen( "label" , "for" , "wm-source" , "class" , "p" )
hb . W riteEscaped( a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "interactionslabel" ) )
hb . W riteElementClose( "label" )
hb . W riteElementOpen( "input" , "id" , "wm-source" , "type" , "url" , "name" , "source" , "placeholder" , "URL" , "required" , "" )
hb . W riteElementOpen( "input" , "type" , "hidden" , "name" , "target" , "value" , rd . Canonical )
hb . W riteElementOpen( "input" , "type" , "submit" , "value" , a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "send" ) )
hb . W riteElementClose( "form" )
// Show form to create a new comment
hb . w riteElementOpen( "form" , "class" , "fw p" , "method" , "post" , "action" , "/comment" )
hb . w riteElementOpen( "input" , "type" , "hidden" , "name" , "target" , "value" , rd . Canonical )
hb . w riteElementOpen( "input" , "type" , "text" , "name" , "name" , "placeholder" , a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "nameopt" ) )
hb . w riteElementOpen( "input" , "type" , "url" , "name" , "website" , "placeholder" , a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "websiteopt" ) )
hb . w riteElementOpen( "textarea" , "name" , "comment" , "required" , "" , "placeholder" , a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "comment" ) )
hb . w riteElementClose( "textarea" )
hb . w riteElementOpen( "input" , "type" , "submit" , "value" , a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "docomment" ) )
hb . w riteElementClose( "form" )
hb . W riteElementOpen( "form" , "class" , "fw p" , "method" , "post" , "action" , "/comment" )
hb . W riteElementOpen( "input" , "type" , "hidden" , "name" , "target" , "value" , rd . Canonical )
hb . W riteElementOpen( "input" , "type" , "text" , "name" , "name" , "placeholder" , a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "nameopt" ) )
hb . W riteElementOpen( "input" , "type" , "url" , "name" , "website" , "placeholder" , a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "websiteopt" ) )
hb . W riteElementOpen( "textarea" , "name" , "comment" , "required" , "" , "placeholder" , a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "comment" ) )
hb . W riteElementClose( "textarea" )
hb . W riteElementOpen( "input" , "type" , "submit" , "value" , a . ts . GetTemplateStringVariant ( rd . Blog . Lang , "docomment" ) )
hb . W riteElementClose( "form" )
// Finish accordion
hb . w riteElementClose( "details" )
hb . W riteElementClose( "details" )
}
// author h-card
func ( a * goBlog ) renderAuthor ( hb * html Builder) {
func ( a * goBlog ) renderAuthor ( hb * html builder. Html Builder) {
user := a . cfg . User
if user == nil {
return
}
hb . w riteElementOpen( "div" , "class" , "p-author h-card hide" )
hb . W riteElementOpen( "div" , "class" , "p-author h-card hide" )
if user . Picture != "" {
hb . w riteElementOpen( "data" , "class" , "u-photo" , "value" , user . Picture )
hb . w riteElementClose( "data" )
hb . W riteElementOpen( "data" , "class" , "u-photo" , "value" , user . Picture )
hb . W riteElementClose( "data" )
}
if user . Name != "" {
hb . w riteElementOpen( "a" , "class" , "p-name u-url" , "rel" , "me" , "href" , defaultIfEmpty ( user . Link , "/" ) )
hb . w riteEscaped( user . Name )
hb . w riteElementClose( "a" )
hb . W riteElementOpen( "a" , "class" , "p-name u-url" , "rel" , "me" , "href" , defaultIfEmpty ( user . Link , "/" ) )
hb . W riteEscaped( user . Name )
hb . W riteElementClose( "a" )
}
hb . w riteElementClose( "div" )
hb . W riteElementClose( "div" )
}
// head meta tags for a post
func ( a * goBlog ) renderPostHeadMeta ( hb * html Builder, p * post , canonical string ) {
func ( a * goBlog ) renderPostHeadMeta ( hb * html builder. Html Builder, p * post , canonical string ) {
if p == nil {
return
}
if canonical != "" {
hb . w riteElementOpen( "meta" , "property" , "og:url" , "content" , canonical )
hb . w riteElementOpen( "meta" , "property" , "twitter:url" , "content" , canonical )
hb . W riteElementOpen( "meta" , "property" , "og:url" , "content" , canonical )
hb . W riteElementOpen( "meta" , "property" , "twitter:url" , "content" , canonical )
}
if p . RenderedTitle != "" {
hb . w riteElementOpen( "meta" , "property" , "og:title" , "content" , p . RenderedTitle )
hb . w riteElementOpen( "meta" , "property" , "twitter:title" , "content" , p . RenderedTitle )
hb . W riteElementOpen( "meta" , "property" , "og:title" , "content" , p . RenderedTitle )
hb . W riteElementOpen( "meta" , "property" , "twitter:title" , "content" , p . RenderedTitle )
}
if summary := a . postSummary ( p ) ; summary != "" {
hb . w riteElementOpen( "meta" , "name" , "description" , "content" , summary )
hb . w riteElementOpen( "meta" , "property" , "og:description" , "content" , summary )
hb . w riteElementOpen( "meta" , "property" , "twitter:description" , "content" , summary )
hb . W riteElementOpen( "meta" , "name" , "description" , "content" , summary )
hb . W riteElementOpen( "meta" , "property" , "og:description" , "content" , summary )
hb . W riteElementOpen( "meta" , "property" , "twitter:description" , "content" , summary )
}
if published := toLocalTime ( p . Published ) ; ! published . IsZero ( ) {
hb . w riteElementOpen( "meta" , "itemprop" , "datePublished" , "content" , published . Format ( time . RFC3339 ) )
hb . W riteElementOpen( "meta" , "itemprop" , "datePublished" , "content" , published . Format ( time . RFC3339 ) )
}
if updated := toLocalTime ( p . Updated ) ; ! updated . IsZero ( ) {
hb . w riteElementOpen( "meta" , "itemprop" , "dateModified" , "content" , updated . Format ( time . RFC3339 ) )
hb . W riteElementOpen( "meta" , "itemprop" , "dateModified" , "content" , updated . Format ( time . RFC3339 ) )