diff --git a/config.go b/config.go index 5830ac4..d6f856c 100644 --- a/config.go +++ b/config.go @@ -50,6 +50,7 @@ type configBlog struct { Photos *photos `mapstructure:"photos"` ActivityStreams *activityStreams `mapstructure:"activitystreams"` DefaultSection string `mapstructure:"defaultsection"` + CustomPages []*customPage `mapstructure:"custompages"` } type section struct { @@ -88,6 +89,13 @@ type activityStreams struct { ImagesParameter string `mapstructure:"imagesParameter"` } +type customPage struct { + Path string `mapstructure:"path"` + Template string `mapstructure:"template"` + Cache bool `mapstructure:"cache"` + Data *interface{} `mapstructure:"data"` +} + type configUser struct { Nick string `mapstructure:"nick"` Name string `mapstructure:"name"` diff --git a/customPages.go b/customPages.go new file mode 100644 index 0000000..4e45207 --- /dev/null +++ b/customPages.go @@ -0,0 +1,12 @@ +package main + +import "net/http" + +func serveCustomPage(blog *configBlog, page *customPage) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + render(w, page.Template, &renderData{ + Blog: blog, + Data: page.Data, + }) + } +} diff --git a/feeds.go b/feeds.go index 27e28a4..28ef134 100644 --- a/feeds.go +++ b/feeds.go @@ -45,26 +45,22 @@ func generateFeed(blog string, f feedType, w http.ResponseWriter, r *http.Reques var err error switch f { case rssFeed: + w.Header().Add(contentType, "application/rss+xml; charset=utf-8") feedStr, err = feed.ToRss() case atomFeed: + w.Header().Add(contentType, "application/atom+xml; charset=utf-8") feedStr, err = feed.ToAtom() case jsonFeed: + w.Header().Add(contentType, "application/feed+json; charset=utf-8") feedStr, err = feed.ToJSON() default: return } if err != nil { + w.Header().Del(contentType) http.Error(w, err.Error(), http.StatusInternalServerError) return } - switch f { - case rssFeed: - w.Header().Add(contentType, "application/rss+xml; charset=utf-8") - case atomFeed: - w.Header().Add(contentType, "application/atom+xml; charset=utf-8") - case jsonFeed: - w.Header().Add(contentType, "application/feed+json; charset=utf-8") - } w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(feedStr)) } diff --git a/http.go b/http.go index 27201b6..cc77f9c 100644 --- a/http.go +++ b/http.go @@ -12,9 +12,11 @@ import ( ) const contentType = "Content-Type" -const contentTypeHTMLUTF8 = "text/html; charset=utf-8" -const contentTypeJSONUTF8 = "application/json; charset=utf-8" +const charsetUtf8Suffix = "; charset=utf-8" +const contentTypeHTML = "text/html" +const contentTypeHTMLUTF8 = contentTypeHTML + charsetUtf8Suffix const contentTypeJSON = "application/json" +const contentTypeJSONUTF8 = contentTypeJSON + charsetUtf8Suffix const contentTypeWWWForm = "application/x-www-form-urlencoded" const contentTypeMultipartForm = "multipart/form-data" @@ -171,6 +173,16 @@ func buildHandler() (http.Handler, error) { r.With(cacheMiddleware, minifier.Middleware).Get(fullBlogPath+jsonPath, serveHome(blog, blogPath, jsonFeed)) r.With(cacheMiddleware, minifier.Middleware).Get(fullBlogPath+atomPath, serveHome(blog, blogPath, atomFeed)) r.With(cacheMiddleware, minifier.Middleware).Get(blogPath+paginationPath, serveHome(blog, blogPath, noFeed)) + + // Custom pages + for _, cp := range blogConfig.CustomPages { + serveFunc := serveCustomPage(blogConfig, cp) + if cp.Cache { + r.With(cacheMiddleware, minifier.Middleware).Get(cp.Path, serveFunc) + } else { + r.With(minifier.Middleware).Get(cp.Path, serveFunc) + } + } } // Sitemap diff --git a/minify.go b/minify.go index 5f46381..ca1efcd 100644 --- a/minify.go +++ b/minify.go @@ -13,7 +13,7 @@ var minifier *minify.M func initMinify() { minifier = minify.New() - minifier.AddFunc("text/html", mHtml.Minify) + minifier.AddFunc(contentTypeHTML, mHtml.Minify) minifier.AddFunc("text/css", mCss.Minify) minifier.AddFunc("application/javascript", mJs.Minify) minifier.AddFunc("application/rss+xml", mXml.Minify) diff --git a/render.go b/render.go index 9483950..46ea2dc 100644 --- a/render.go +++ b/render.go @@ -2,7 +2,9 @@ package main import ( "bytes" + "fmt" "html/template" + "io/ioutil" "log" "net/http" "os" @@ -92,6 +94,20 @@ func initRendering() error { } return path }, + "jsonFile": func(filename string) *interface{} { + parsed := []*interface{}{} + content, err := ioutil.ReadFile(filename) + if err != nil { + return nil + } + contentString := "[" + string(content) + "]" + err = json.Unmarshal([]byte(contentString), &parsed) + if err != nil { + fmt.Println(err.Error()) + return nil + } + return parsed[0] + }, } templates = make(map[string]*template.Template) diff --git a/templates/custom/blogroll.gohtml b/templates/custom/blogroll.gohtml new file mode 100644 index 0000000..daabee8 --- /dev/null +++ b/templates/custom/blogroll.gohtml @@ -0,0 +1,21 @@ +{{ define "title" }} + Blogroll - {{ .Blog.Title }} +{{ end }} + +{{ define "main" }} +
+ {{ $opmlJson := index ( jsonFile "data/opml.json" ) "outline" }} + {{ range $opmlJson }} + {{ md (printf "%s %s" "##" ._text) }} + + {{ end }} +
+{{ end }} + +{{ define "blogroll" }} + {{ template "base" . }} +{{ end }} \ No newline at end of file