From ded6e3b25bca083cabe21bda6f4d01f6766587bc Mon Sep 17 00:00:00 2001 From: Adam Mathes Date: Thu, 9 Feb 2017 19:40:44 -0800 Subject: initial commit (fmstatic -> snkt) --- site/init.go | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ site/site.go | 135 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 299 insertions(+) create mode 100644 site/init.go create mode 100644 site/site.go (limited to 'site') 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"}} + + + + {{template "title" .}} + + +

{{template "title"}}

+ {{template "content" .}} +
+

Home

+

Archive

+ + +{{end}} +{{define "title"}}{{end}} +{{define "content"}}{{end}} +`)}, + { + Dir: "tmpl", + Filename: "home", + Content: []byte( +`{{define "title"}}{{.Site.Title}}{{end}} +{{define "content"}} +

{{.Site.Title}}

+{{range .Posts.Limit 15}} +

{{.Title}}

+{{.Content}} +{{end}} +{{end}} +`)}, + { + Dir: "tmpl", + Filename: "post", + Content: []byte( +`{{define "title"}}{{ .Post.Title }}{{end}} +{{define "content"}} +

{{ .Post.Title }}

+{{.Post.Content}} +{{if .Post.Next.Title}} +

{{.Post.Next.Title}}

+{{end}} + {{if .Post.Prev.Title}} +

{{.Post.Prev.Title}}

+{{end}} +{{end}} +`)}, + { + Dir: "tmpl", + Filename: "archive", + Content: []byte( +`{{define "title"}}{{.Site.Title}} Archives{{end}} +{{define "content"}} +

{{ .Site.Title }}

+{{range .Posts}} +{{if .}}

{{.Title}}

{{end}} +{{end}} +{{end}} +`)}, + { + Dir: "tmpl", + Filename: "rss", + Content: []byte( +`{{define "base"}} + + + + {{ .Site.Title }} + {{ .Site.URL }} + + {{ range .Posts.Limit 15 }} + + {{ .Permalink }} + <![CDATA[{{ .Title }}]]> + {{ .RssDate }} + + + + {{ end }} + + +{{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 +} -- cgit v1.2.3