mirror of https://github.com/jlelse/GoBlog
Add method to generate post summaries, extend feeds
parent
4b7507c781
commit
4f71a2a090
|
@ -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
|
||||
|
|
9
feeds.go
9
feeds.go
|
@ -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),
|
||||
})
|
||||
|
|
6
go.mod
6
go.mod
|
@ -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
|
||||
|
|
12
go.sum
12
go.sum
|
@ -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
|
||||
}
|
13
posts.go
13
posts.go
|
@ -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>
|
||||
|
|
12
utils.go
12
utils.go
|
@ -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…
Reference in New Issue