Add method to generate post summaries, extend feeds

pull/7/head
Jan-Lukas Else 2 years ago
parent 4b7507c781
commit 4f71a2a090
  1. 2
      config.go
  2. 1
      example-config.yaml
  3. 9
      feeds.go
  4. 6
      go.mod
  5. 12
      go.sum
  6. 34
      postFuncs.go
  7. 13
      posts.go
  8. 3
      render.go
  9. 2
      templates/summary.gohtml
  10. 12
      utils.go

@ -16,6 +16,7 @@ type configServer struct {
Logging bool `mapstructure:"logging"`
Port int `mapstructure:"port"`
Domain string `mapstructure:"domain"`
PublicAddress string `mapstructure:"publicAddress"`
PublicHttps bool `mapstructure:"publicHttps"`
LetsEncryptMail string `mapstructure:"letsEncryptMail"`
LocalHttps bool `mapstructure:"localHttps"`
@ -77,6 +78,7 @@ func initConfig() error {
viper.SetDefault("server.logging", false)
viper.SetDefault("server.port", 8080)
viper.SetDefault("server.domain", "example.com")
viper.SetDefault("server.publicAddress", "http://localhost:8080")
viper.SetDefault("server.publicHttps", false)
viper.SetDefault("server.letsEncryptMail", "mail@example.com")
viper.SetDefault("server.localHttps", false)

@ -2,6 +2,7 @@ server:
logging: false
port: 8080
domain: example.com
publicAdress: http://localhost:8080
publicHttps: false
letsEncryptMail: mail@example.com
localHttps: false

@ -3,6 +3,7 @@ package main
import (
"github.com/gorilla/feeds"
"net/http"
"strings"
"time"
)
@ -15,20 +16,20 @@ const (
JSON feedType = "json"
)
func generateFeed(f feedType, w http.ResponseWriter, posts []*Post, title string, description string) {
func generateFeed(f feedType, w http.ResponseWriter, r *http.Request, posts []*Post, title string, description string) {
now := time.Now()
feed := &feeds.Feed{
Title: title,
Description: description,
Link: &feeds.Link{},
Link: &feeds.Link{Href: appConfig.Server.PublicAddress + strings.TrimSuffix(r.URL.Path, "."+string(f))},
Created: now,
}
for _, postItem := range posts {
htmlContent, _ := renderMarkdown(postItem.Content)
feed.Add(&feeds.Item{
Title: postItem.title(),
Link: &feeds.Link{Href: postItem.Path},
Description: string(htmlContent),
Link: &feeds.Link{Href: appConfig.Server.PublicAddress + postItem.Path},
Description: postItem.summary(),
Id: postItem.Path,
Content: string(htmlContent),
})

@ -3,6 +3,8 @@ module git.jlel.se/jlelse/GoBlog
go 1.15
require (
github.com/PuerkitoBio/goquery v1.5.1
github.com/andybalholm/cascadia v1.2.0 // indirect
github.com/caddyserver/certmagic v0.11.2
github.com/cenkalti/backoff/v4 v4.0.2 // indirect
github.com/go-acme/lego/v3 v3.9.0 // indirect
@ -24,7 +26,7 @@ require (
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/pelletier/go-toml v1.8.1 // indirect
github.com/smartystreets/assertions v1.2.0 // indirect
github.com/spf13/afero v1.3.5 // indirect
github.com/spf13/afero v1.4.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.7.1
@ -34,7 +36,7 @@ require (
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect
golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 // indirect
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 // indirect
golang.org/x/sys v0.0.0-20200915084602-288bc346aa39 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
gopkg.in/ini.v1 v1.61.0 // indirect

@ -41,6 +41,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks=
github.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE=
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
@ -49,7 +50,10 @@ github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.18/go.mod h1:L+HB2uBoDgi3+r1pJ
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aliyun/alibaba-cloud-sdk-go v1.61.112/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/andybalholm/cascadia v1.2.0 h1:vuRCkM5Ozh/BfmsaTm26kbjm0mIOM3yS5Ek/F5h18aE=
github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxBp0T0eFw1RUQY=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
@ -388,8 +392,8 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.3.5 h1:AWZ/w4lcfxuh52NVL78p9Eh8j6r1mCTEGSRFBJyIHAE=
github.com/spf13/afero v1.3.5/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.4.0 h1:jsLTaI1zwYO3vjrzHalkVcIHXTNmdQFepW4OI8H3+x8=
github.com/spf13/afero v1.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
@ -581,8 +585,8 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c h1:UIcGWL6/wpCfyGuJnRFJRurA+yj8RrW7Q6x2YMCXt6c=
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200915084602-288bc346aa39 h1:356XA7ITklAU2//sYkjFeco+dH1bCRD8XCJ9FIEsvo4=
golang.org/x/sys v0.0.0-20200915084602-288bc346aa39/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

@ -0,0 +1,34 @@
package main
import (
"github.com/PuerkitoBio/goquery"
"strings"
)
func (p *Post) firstParameter(parameter string) (result string) {
if pp := p.Parameters[parameter]; len(pp) > 0 {
result = pp[0]
}
return
}
func (p *Post) title() string {
return p.firstParameter("title")
}
func (p *Post) summary() (summary string) {
summary = p.firstParameter("summary")
if summary != "" {
return
}
summaryDivider := "<!--more-->"
rendered, _ := renderMarkdown(p.Content)
if strings.Contains(string(rendered), summaryDivider) {
doc, _ := goquery.NewDocumentFromReader(strings.NewReader(strings.Split(string(rendered), summaryDivider)[0]))
summary = doc.Text()
return
}
doc, _ := goquery.NewDocumentFromReader(strings.NewReader(string(rendered)))
summary = firstSentences(doc.Text(), 3)
return
}

@ -23,17 +23,6 @@ type Post struct {
Parameters map[string][]string `json:"parameters"`
}
func (p *Post) firstParameter(parameter string) (result string) {
if pp := p.Parameters[parameter]; len(pp) > 0 {
result = pp[0]
}
return
}
func (p *Post) title() string {
return p.firstParameter("title")
}
func servePost(w http.ResponseWriter, r *http.Request) {
path := slashTrimmedPath(r)
post, err := getPost(r.Context(), path)
@ -147,7 +136,7 @@ func serveIndex(path string, sec *section, tax *taxonomy, taxonomyValue string,
}
// Check if feed
if ft != NONE {
generateFeed(ft, w, posts, title, description)
generateFeed(ft, w, r, posts, title, description)
return
}
// Navigation

@ -42,6 +42,9 @@ func initRendering() {
"title": func(post *Post) string {
return post.title()
},
"summary": func(post *Post) string {
return post.summary()
},
"include": func(templateName string, data interface{}) (template.HTML, error) {
buf := new(bytes.Buffer)
err := templates[templateName].ExecuteTemplate(buf, templateName, data)

@ -1,7 +1,7 @@
{{ define "summary" }}
<article>
{{ with p . "title" }}<h2>{{ . }}</h2>{{ end }}
<p>{{ md .Content }}</p>
<p>{{ summary . }}</p>
<a href="{{ .Path }}">View</a>
</article>
<hr>

@ -26,3 +26,15 @@ func urlize(str string) string {
}
return newStr
}
func firstSentences(value string, count int) string {
for i := range value {
if value[i] == '.' || value[i] == '!' || value[i] == '?' {
count -= 1
if count == 0 && i < len(value) {
return value[0 : i+1]
}
}
}
return value
}

Loading…
Cancel
Save