diff --git a/config.go b/config.go index 1e575be..0ce35d5 100644 --- a/config.go +++ b/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") diff --git a/example-config.yaml b/example-config.yaml index f5f2c31..8621947 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -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 diff --git a/http.go b/http.go index 01025fd..38c6adc 100644 --- a/http.go +++ b/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" diff --git a/posts.go b/posts.go index a5d7a09..f4aee8a 100644 --- a/posts.go +++ b/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 + "'))" } diff --git a/render.go b/render.go index e6b5d53..fa2e80d 100644 --- a/render.go +++ b/render.go @@ -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 diff --git a/templates/index.gohtml b/templates/index.gohtml index e226ce1..6462faf 100644 --- a/templates/index.gohtml +++ b/templates/index.gohtml @@ -1,17 +1,21 @@ {{ define "title" }} - {{ blog.Title }} - - - + {{ if .Title }} + {{ .Title }} - {{ blog.Title }} + {{ else }} + {{ blog.Title }} + {{ end }} + + + {{ end }} {{ define "main" }} diff --git a/templates/photos.gohtml b/templates/photos.gohtml new file mode 100644 index 0000000..ea15a79 --- /dev/null +++ b/templates/photos.gohtml @@ -0,0 +1,30 @@ +{{ define "title" }} + {{ if blog.Photos.Title }} + {{ blog.Photos.Title }} - {{ blog.Title }} + {{ else }} + {{ blog.Title }} + {{ end }} +{{ end }} + +{{ define "main" }} +
+ {{ with blog.Photos.Title }}

{{ . }}

{{ end }} + {{ with blog.Photos.Description }}{{ md . }}{{ end }} + {{ if (or blog.Photos.Title blog.Photos.Description) }} +
+ {{ end }} + {{ range $i, $post := .Posts }} + {{ include "photosummary" . }} + {{ end }} + {{ if .HasPrev }} +

Prev

+ {{ end }} + {{ if .HasNext }} +

Next

+ {{ end }} +
+{{ end }} + +{{ define "photos" }} + {{ template "base" . }} +{{ end }} \ No newline at end of file diff --git a/templates/photosummary.gohtml b/templates/photosummary.gohtml new file mode 100644 index 0000000..772a82c --- /dev/null +++ b/templates/photosummary.gohtml @@ -0,0 +1,12 @@ +{{ define "photosummary" }} +
+ {{ with p . "title" }}

{{ . }}

{{ end }} + {{ with .Published }}

{{ dateformat . "02. Jan 2006" }}

{{ end }} + {{ range $i, $photo := ( ps . blog.Photos.Parameter ) }} + {{ md ( printf "![](%s)" $photo ) }} + {{ end }} +

{{ summary . }}

+ View +
+
+{{ end }} \ No newline at end of file