mirror of https://github.com/jlelse/GoBlog
Photos page
This commit is contained in:
parent
f5cca985bd
commit
1c8da99620
15
config.go
15
config.go
|
@ -49,6 +49,8 @@ type configBlog struct {
|
|||
Taxonomies []*taxonomy `mapstructure:"taxonomies"`
|
||||
// Menus
|
||||
Menus map[string]*menu `mapstructure:"menus"`
|
||||
// Photos
|
||||
Photos *photos `mapstructure:"photos"`
|
||||
}
|
||||
|
||||
type section struct {
|
||||
|
@ -72,6 +74,14 @@ type menuItem struct {
|
|||
Link string `mapstructure:"link"`
|
||||
}
|
||||
|
||||
type photos struct {
|
||||
Enabled bool `mapstructure:"enabled"`
|
||||
Parameter string `mapstructure:"parameter"`
|
||||
Path string `mapstructure:"path"`
|
||||
Title string `mapstructure:"title"`
|
||||
Description string `mapstructure:"description"`
|
||||
}
|
||||
|
||||
type configUser struct {
|
||||
Nick string `mapstructure:"nick"`
|
||||
Name string `mapstructure:"name"`
|
||||
|
@ -119,6 +129,11 @@ func initConfig() error {
|
|||
viper.SetDefault("blog.sections", []*section{{Name: "posts", Title: "Posts", Description: "**Posts** on this blog"}})
|
||||
viper.SetDefault("blog.taxonomies", []*taxonomy{{Name: "tags", Title: "Tags", Description: "**Tags** on this blog"}})
|
||||
viper.SetDefault("blog.menus", map[string]*menu{"main": {Items: []*menuItem{{Title: "Home", Link: "/"}, {Title: "Post", Link: "Posts"}}}})
|
||||
viper.SetDefault("blog.photos.enabled", true)
|
||||
viper.SetDefault("blog.photos.parameter", "images")
|
||||
viper.SetDefault("blog.photos.path", "/photos")
|
||||
viper.SetDefault("blog.photos.title", "Photos")
|
||||
viper.SetDefault("blog.photos.description", "Photos on this blog")
|
||||
viper.SetDefault("user.nick", "admin")
|
||||
viper.SetDefault("user.name", "Admin")
|
||||
viper.SetDefault("user.password", "secret")
|
||||
|
|
|
@ -30,6 +30,12 @@ blog:
|
|||
link: /
|
||||
- title: Posts
|
||||
link: /posts
|
||||
photos:
|
||||
enable: true
|
||||
parameter: images
|
||||
path: /photos
|
||||
title: Photos
|
||||
description: "Photos on this blog"
|
||||
user:
|
||||
nick: admin
|
||||
name: Admin
|
||||
|
|
5
http.go
5
http.go
|
@ -133,6 +133,11 @@ func buildHandler() (http.Handler, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if appConfig.Blog.Photos.Enabled {
|
||||
r.With(cacheMiddleware, minifier.Middleware).Get(appConfig.Blog.Photos.Path, servePhotos(appConfig.Blog.Photos.Path))
|
||||
r.With(cacheMiddleware, minifier.Middleware).Get(appConfig.Blog.Photos.Path+paginationPath, servePhotos(appConfig.Blog.Photos.Path))
|
||||
}
|
||||
|
||||
// Blog
|
||||
rootPath := "/"
|
||||
blogPath := "/blog"
|
||||
|
|
91
posts.go
91
posts.go
|
@ -74,11 +74,18 @@ func (p *postPaginationAdapter) Slice(offset, length int, data interface{}) erro
|
|||
}
|
||||
|
||||
func serveHome(path string, ft feedType) func(w http.ResponseWriter, r *http.Request) {
|
||||
return serveIndex(path, nil, nil, "", ft)
|
||||
return serveIndex(&indexConfig{
|
||||
path: path,
|
||||
feed: ft,
|
||||
})
|
||||
}
|
||||
|
||||
func serveSection(path string, section *section, ft feedType) func(w http.ResponseWriter, r *http.Request) {
|
||||
return serveIndex(path, section, nil, "", ft)
|
||||
return serveIndex(&indexConfig{
|
||||
path: path,
|
||||
section: section,
|
||||
feed: ft,
|
||||
})
|
||||
}
|
||||
|
||||
func serveTaxonomy(tax *taxonomy) func(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -99,21 +106,45 @@ func serveTaxonomy(tax *taxonomy) func(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func serveTaxonomyValue(path string, tax *taxonomy, value string, ft feedType) func(w http.ResponseWriter, r *http.Request) {
|
||||
return serveIndex(path, nil, tax, value, ft)
|
||||
return serveIndex(&indexConfig{
|
||||
path: path,
|
||||
tax: tax,
|
||||
taxValue: value,
|
||||
feed: ft,
|
||||
})
|
||||
}
|
||||
|
||||
func serveIndex(path string, sec *section, tax *taxonomy, taxonomyValue string, ft feedType) func(w http.ResponseWriter, r *http.Request) {
|
||||
func servePhotos(path string) func(w http.ResponseWriter, r *http.Request) {
|
||||
return serveIndex(&indexConfig{
|
||||
path: path,
|
||||
onlyWithParameter: appConfig.Blog.Photos.Parameter,
|
||||
template: templatePhotos,
|
||||
})
|
||||
}
|
||||
|
||||
type indexConfig struct {
|
||||
path string
|
||||
section *section
|
||||
tax *taxonomy
|
||||
taxValue string
|
||||
feed feedType
|
||||
onlyWithParameter string
|
||||
template string
|
||||
}
|
||||
|
||||
func serveIndex(ic *indexConfig) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
pageNoString := chi.URLParam(r, "page")
|
||||
pageNo, _ := strconv.Atoi(pageNoString)
|
||||
sections := appConfig.Blog.Sections
|
||||
if sec != nil {
|
||||
sections = []*section{sec}
|
||||
if ic.section != nil {
|
||||
sections = []*section{ic.section}
|
||||
}
|
||||
p := paginator.New(&postPaginationAdapter{context: r.Context(), config: &postsRequestConfig{
|
||||
sections: sections,
|
||||
taxonomy: tax,
|
||||
taxonomyValue: taxonomyValue,
|
||||
sections: sections,
|
||||
taxonomy: ic.tax,
|
||||
taxonomyValue: ic.taxValue,
|
||||
onlyWithParameter: ic.onlyWithParameter,
|
||||
}}, appConfig.Blog.Pagination)
|
||||
p.SetPage(pageNo)
|
||||
var posts []*Post
|
||||
|
@ -124,15 +155,15 @@ func serveIndex(path string, sec *section, tax *taxonomy, taxonomyValue string,
|
|||
}
|
||||
// Meta
|
||||
var title, description string
|
||||
if tax != nil {
|
||||
title = fmt.Sprintf("%s: %s", tax.Title, taxonomyValue)
|
||||
} else if sec != nil {
|
||||
title = sec.Title
|
||||
description = sec.Description
|
||||
if ic.tax != nil {
|
||||
title = fmt.Sprintf("%s: %s", ic.tax.Title, ic.taxValue)
|
||||
} else if ic.section != nil {
|
||||
title = ic.section.Title
|
||||
description = ic.section.Description
|
||||
}
|
||||
// Check if feed
|
||||
if ft != NONE {
|
||||
generateFeed(ft, w, r, posts, title, description)
|
||||
if ic.feed != NONE {
|
||||
generateFeed(ic.feed, w, r, posts, title, description)
|
||||
return
|
||||
}
|
||||
// Navigation
|
||||
|
@ -144,15 +175,19 @@ func serveIndex(path string, sec *section, tax *taxonomy, taxonomyValue string,
|
|||
if err == paginator.ErrNoNextPage {
|
||||
nextPage = p.Page()
|
||||
}
|
||||
render(w, templateIndex, &indexTemplateData{
|
||||
template := ic.template
|
||||
if len(template) == 0 {
|
||||
template = templateIndex
|
||||
}
|
||||
render(w, template, &indexTemplateData{
|
||||
Title: title,
|
||||
Description: description,
|
||||
Posts: posts,
|
||||
HasPrev: p.HasPrev(),
|
||||
HasNext: p.HasNext(),
|
||||
First: path,
|
||||
Prev: fmt.Sprintf("%s/page/%d", path, prevPage),
|
||||
Next: fmt.Sprintf("%s/page/%d", path, nextPage),
|
||||
First: ic.path,
|
||||
Prev: fmt.Sprintf("%s/page/%d", ic.path, prevPage),
|
||||
Next: fmt.Sprintf("%s/page/%d", ic.path, nextPage),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -168,12 +203,13 @@ func getPost(context context.Context, path string) (*Post, error) {
|
|||
}
|
||||
|
||||
type postsRequestConfig struct {
|
||||
path string
|
||||
limit int
|
||||
offset int
|
||||
sections []*section
|
||||
taxonomy *taxonomy
|
||||
taxonomyValue string
|
||||
path string
|
||||
limit int
|
||||
offset int
|
||||
sections []*section
|
||||
taxonomy *taxonomy
|
||||
taxonomyValue string
|
||||
onlyWithParameter string
|
||||
}
|
||||
|
||||
func getPosts(context context.Context, config *postsRequestConfig) (posts []*Post, err error) {
|
||||
|
@ -181,6 +217,9 @@ func getPosts(context context.Context, config *postsRequestConfig) (posts []*Pos
|
|||
var rows *sql.Rows
|
||||
defaultSelection := "select p.path, coalesce(content, ''), coalesce(published, ''), coalesce(updated, ''), coalesce(parameter, ''), coalesce(value, '') "
|
||||
postsTable := "posts"
|
||||
if config.onlyWithParameter != "" {
|
||||
postsTable = "(select distinct p.* from " + postsTable + " p left outer join post_parameters pp on p.path = pp.path where pp.parameter = '" + config.onlyWithParameter + "' and length(coalesce(pp.value, '')) > 1)"
|
||||
}
|
||||
if config.taxonomy != nil && len(config.taxonomyValue) > 0 {
|
||||
postsTable = "(select distinct p.* from " + postsTable + " p left outer join post_parameters pp on p.path = pp.path where pp.parameter = '" + config.taxonomy.Name + "' and lower(pp.value) = lower('" + config.taxonomyValue + "'))"
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ const templateError = "error"
|
|||
const templateRedirect = "redirect"
|
||||
const templateIndex = "index"
|
||||
const templateTaxonomy = "taxonomy"
|
||||
const templatePhotos = "photos"
|
||||
|
||||
var templates map[string]*template.Template
|
||||
var templateFunctions template.FuncMap
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
{{ define "title" }}
|
||||
<title>{{ blog.Title }}</title>
|
||||
<link rel="alternate"
|
||||
type="application/rss+xml"
|
||||
title="RSS"
|
||||
href="{{ .First }}.rss"/>
|
||||
<link rel="alternate"
|
||||
type="application/atom+xml"
|
||||
title="Atom"
|
||||
href="{{ .First }}.atom"/>
|
||||
<link rel="alternate"
|
||||
type="application/feed+json"
|
||||
title="JSON Feed"
|
||||
href="{{ .First }}.json"/>
|
||||
{{ if .Title }}
|
||||
<title>{{ .Title }} - {{ blog.Title }}</title>
|
||||
{{ else }}
|
||||
<title>{{ blog.Title }}</title>
|
||||
{{ end }}
|
||||
<link rel="alternate"
|
||||
type="application/rss+xml"
|
||||
title="RSS"
|
||||
href="{{ .First }}.rss"/>
|
||||
<link rel="alternate"
|
||||
type="application/atom+xml"
|
||||
title="Atom"
|
||||
href="{{ .First }}.atom"/>
|
||||
<link rel="alternate"
|
||||
type="application/feed+json"
|
||||
title="JSON Feed"
|
||||
href="{{ .First }}.json"/>
|
||||
{{ end }}
|
||||
|
||||
{{ define "main" }}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
{{ define "title" }}
|
||||
{{ if blog.Photos.Title }}
|
||||
<title>{{ blog.Photos.Title }} - {{ blog.Title }}</title>
|
||||
{{ else }}
|
||||
<title>{{ blog.Title }}</title>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ define "main" }}
|
||||
<main>
|
||||
{{ with blog.Photos.Title }}<h1>{{ . }}</h1>{{ end }}
|
||||
{{ with blog.Photos.Description }}{{ md . }}{{ end }}
|
||||
{{ if (or blog.Photos.Title blog.Photos.Description) }}
|
||||
<hr>
|
||||
{{ end }}
|
||||
{{ range $i, $post := .Posts }}
|
||||
{{ include "photosummary" . }}
|
||||
{{ end }}
|
||||
{{ if .HasPrev }}
|
||||
<p><a href="{{ .Prev }}">Prev</a></p>
|
||||
{{ end }}
|
||||
{{ if .HasNext }}
|
||||
<p><a href="{{ .Next }}">Next</a></p>
|
||||
{{ end }}
|
||||
</main>
|
||||
{{ end }}
|
||||
|
||||
{{ define "photos" }}
|
||||
{{ template "base" . }}
|
||||
{{ end }}
|
|
@ -0,0 +1,12 @@
|
|||
{{ define "photosummary" }}
|
||||
<article>
|
||||
{{ with p . "title" }}<h2>{{ . }}</h2>{{ end }}
|
||||
{{ with .Published }}<p>{{ dateformat . "02. Jan 2006" }}</p>{{ end }}
|
||||
{{ range $i, $photo := ( ps . blog.Photos.Parameter ) }}
|
||||
{{ md ( printf "![](%s)" $photo ) }}
|
||||
{{ end }}
|
||||
<p>{{ summary . }}</p>
|
||||
<a href="{{ .Path }}">View</a>
|
||||
</article>
|
||||
<hr>
|
||||
{{ end }}
|
Loading…
Reference in New Issue