aboutsummaryrefslogtreecommitdiffstats
path: root/site
diff options
context:
space:
mode:
Diffstat (limited to 'site')
-rw-r--r--site/init.go164
-rw-r--r--site/site.go135
2 files changed, 299 insertions, 0 deletions
diff --git a/site/init.go b/site/init.go
new file mode 100644
index 0000000..dc17cfa
--- /dev/null
+++ b/site/init.go
@@ -0,0 +1,164 @@
+package site
+
+import (
+ "path"
+ "snkt/render"
+ "snkt/config"
+ "os"
+ "log"
+ "gopkg.in/yaml.v2"
+)
+
+type skeleton struct {
+ Dir string
+ Filename string
+ Content []byte
+}
+
+var skeletons = []skeleton {
+ {
+ Dir: "tmpl",
+ Filename: "base",
+ Content: []byte(
+`{{define "base"}}
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>{{template "title" .}}</title>
+ </head>
+ <body>
+ <h1>{{template "title"}}</h1>
+ {{template "content" .}}
+ <hr />
+ <p><a href="{{.Site.URL}}/index.html">Home</a></p>
+ <p><a href="{{.Site.URL}}/archive.html">Archive</a></p>
+ </body>
+</html>
+{{end}}
+{{define "title"}}{{end}}
+{{define "content"}}{{end}}
+`)},
+ {
+ Dir: "tmpl",
+ Filename: "home",
+ Content: []byte(
+`{{define "title"}}{{.Site.Title}}{{end}}
+{{define "content"}}
+<h1>{{.Site.Title}}</h1>
+{{range .Posts.Limit 15}}
+<h2><a href="{{.Permalink}}">{{.Title}}</a></h2>
+{{.Content}}
+{{end}}
+{{end}}
+`)},
+ {
+ Dir: "tmpl",
+ Filename: "post",
+ Content: []byte(
+`{{define "title"}}{{ .Post.Title }}{{end}}
+{{define "content"}}
+<h2>{{ .Post.Title }}</h2>
+{{.Post.Content}}
+{{if .Post.Next.Title}}
+<p><a href="{{.Post.Next.Permalink}}">{{.Post.Next.Title}}</a></p>
+{{end}}
+ {{if .Post.Prev.Title}}
+<p><a href="{{.Post.Prev.Permalink}}">{{.Post.Prev.Title}}</a></p>
+{{end}}
+{{end}}
+`)},
+ {
+ Dir: "tmpl",
+ Filename: "archive",
+ Content: []byte(
+`{{define "title"}}{{.Site.Title}} Archives{{end}}
+{{define "content"}}
+<h1>{{ .Site.Title }}</h1>
+{{range .Posts}}
+{{if .}}<h2><a href="{{.Permalink}}">{{.Title}}</a></h2>{{end}}
+{{end}}
+{{end}}
+`)},
+ {
+ Dir: "tmpl",
+ Filename: "rss",
+ Content: []byte(
+`{{define "base"}}
+<?xml version="1.0" encoding="UTF-8" ?>
+<rss version="2.0">
+<channel>
+ <title>{{ .Site.Title }}</title>
+ <link>{{ .Site.URL }}</link>
+ <description></description>
+ {{ range .Posts.Limit 15 }}
+ <item>
+ <link>{{ .Permalink }}</link>
+ <title><![CDATA[{{ .Title }}]]></title>
+ <pubDate>{{ .RssDate }}</pubDate>
+ <description><![CDATA[
+ {{ .AbsoluteContent }}
+ ]]>
+ </description>
+ </item>
+ {{ end }}
+</channel>
+</rss>
+{{end}}
+`)}}
+
+/*
+Init initializes a new site in `directory` This includes: create `directory` and populate with:
+config.json with sane defaults
+txt, html directories for input/output
+tmpl directory with barebones [base,post,archive,rss] templates
+*/
+var init_dir = ""
+func Init(directory string) {
+ init_dir = directory
+
+ if init_dir[0] != '/' {
+ wd, err := os.Getwd()
+ if err == nil {
+ init_dir = path.Join(wd, init_dir)
+ }
+ }
+
+ var cfg = config.Settings{
+ TxtDir: path.Join(init_dir, "txt"),
+ HtmlDir: path.Join(init_dir, "html"),
+ TmplDir: path.Join(init_dir, "tmpl"),
+ }
+
+ cyaml, err := yaml.Marshal(cfg)
+ if err != nil {
+ log.Fatal("marshalling yaml error: ", err)
+ }
+
+ c := skeleton{
+ Dir: "",
+ Filename: "config.yml",
+ Content: cyaml,
+ }
+ skeletons = append(skeletons, c)
+
+ os.MkdirAll( cfg.TxtDir , 0755)
+ os.MkdirAll( cfg.HtmlDir , 0755)
+ os.MkdirAll( cfg.TmplDir , 0755)
+
+ writeSkeletons()
+}
+
+
+func (s skeleton) Render() []byte {
+ return s.Content
+}
+
+func (s skeleton) Target() string {
+ return path.Join(init_dir, s.Dir, s.Filename)
+}
+
+func writeSkeletons() {
+ for _,skeleton := range skeletons {
+ render.Write(skeleton)
+ }
+}
diff --git a/site/site.go b/site/site.go
new file mode 100644
index 0000000..87aa7fc
--- /dev/null
+++ b/site/site.go
@@ -0,0 +1,135 @@
+package site
+
+import (
+ "snkt/archive"
+ "snkt/config"
+ "snkt/post"
+ "snkt/render"
+ "io/ioutil"
+ "log"
+ "path"
+ "sort"
+)
+
+type Site struct {
+ Title string
+ URL string
+
+ Posts post.Posts
+
+ // all archives are optional based on presence of template
+ Archive *archive.ListArchive
+ Home *archive.ListArchive
+ Rss *archive.ListArchive
+ Paged *archive.PagedArchives
+}
+
+/*
+Read reads post data from the filesystem and populates posts and archives
+*/
+func (s *Site) Read() {
+ s.Title = config.Config.SiteTitle
+ s.URL = config.Config.SiteURL
+ s.ReadPosts()
+
+ if render.TmplExists("archive") {
+ s.Archive = archive.NewListArchive(s.Posts)
+ s.Archive.Site = *s
+ sort.Sort(sort.Reverse(s.Archive.Posts))
+ }
+ if render.TmplExists("rss") {
+ s.Rss = archive.NewRssArchive(s.Posts)
+ s.Rss.Site = *s
+ }
+ if render.TmplExists("paged") {
+ s.Paged = archive.CreatePaged(15, s.Posts)
+ }
+ if render.TmplExists("home") {
+ s.Home = archive.NewListArchive(s.Posts)
+ s.Home.Tgt = path.Join(config.Config.HtmlDir, "index.html")
+ s.Home.Template = "home"
+ s.Home.Site = s
+ }
+}
+
+/*
+ReadPosts reads all files from the Config.TxtDir, parses them and stores in s.Posts
+*/
+func (s *Site) ReadPosts() {
+ // TODO: filter this as needed
+ files, err := ioutil.ReadDir(config.Config.TxtDir)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ for _, file := range files {
+ p := post.NewPost(s)
+ p.Read(file)
+
+ // Ignore post-dated posts unless overriden in config
+ if !config.Config.ShowFuture && p.InFuture {
+ log.Printf("Skipping future dated post: %s\n", p.SourceFile)
+ } else {
+ s.Posts = append(s.Posts, p)
+ }
+ }
+
+ // Sort the posts by date, earliest first
+ sort.Sort(s.Posts)
+
+ // Add next/previous to each post.
+ // An allocated but empty post is set at start/end
+ // This prevents templates from failing at start/end if nil checks are not made properly
+ for i, p := range s.Posts {
+ if i > 0 {
+ p.Prev = s.Posts[i-1]
+ } else {
+ p.Prev = new(post.Post)
+ }
+ if i+1 < len(s.Posts) {
+ p.Next = s.Posts[i+1]
+ } else {
+ p.Next = new(post.Post)
+ }
+ }
+}
+
+/*
+Write writes posts and archives to the filesystem
+*/
+func (s *Site) Write() {
+ s.WritePosts()
+ s.WriteArchives()
+}
+
+func (s *Site) WriteArchives() {
+ if render.TmplExists("archive") {
+ render.Write(s.Archive)
+ }
+ if render.TmplExists("rss") {
+ render.Write(s.Rss)
+ }
+ if render.TmplExists("home") {
+ render.Write(s.Home)
+ }
+ if render.TmplExists("paged") {
+ for _, p := range *s.Paged {
+ p.Site = s
+ render.Write(p)
+ }
+ }
+}
+
+func (s *Site) WritePosts() {
+ for _, p := range s.Posts {
+ render.Write(p)
+ }
+}
+
+func (s Site) GetTitle() string {
+ return s.Title
+}
+
+func (s Site) GetURL() string {
+ return s.URL
+}