~kungtotte/dtt

a436136b5a33354861fbc9cfb21e9f9e52e8e38b — Thomas Landin 4 months ago 62e1609
Detect blog posts and render them accordingly

We add an extra walk of the content dir to pick out anything that we
assume is a blog, and we render it as a blog using the appropriate
templates; e.g. post.mustache.

Right now nothing happens with this; we just dump it into a seq for
future use, but it's going to let you add a blog index thing
automatically.
1 files changed, 48 insertions(+), 3 deletions(-)

M src/dtt.nim
M src/dtt.nim => src/dtt.nim +48 -3
@@ 1,5 1,6 @@
import os, strutils, strformat
import parsecfg
import parsecfg, strscans
import unicode, times

import docopt
import mustache


@@ 13,6 14,7 @@ const
  content_dir = "content"
  template_dir = "templates"
  output_dir = "output"
  blog_dirs = ["blog", "blogs", "post", "posts", "articles", "journal", "journals"]

let
  version = "0.1.2"


@@ 104,11 106,49 @@ proc renderTemplate(context: Context, file: string,
                    tmpldir: string = "templates"): string =
  let
    tpl = readFile(tmpldir / tmpl)
    (dir,fname,ext) = splitFile(file)
    (_,_,ext) = splitFile(file)
  if ext == ".md":
    context["content"] = markdown(readFile(file))
    result = tpl.render(context)

proc getSlug(filename: string, hasYMD: bool): string =
  result = filename
  if hasYMD:
    result = result[11..^1]
  result = result.title().multiReplace(("-", " "), ("_", " "))

proc getBlogDate(file: string, datestring: tuple[year, month, day: int]): string =
  if datestring.year > 0:
    let
      # fmt will use parseInt and kill leading zeroes, and this is the easiest
      # way to get a proper yyyy-MM-dd format using format strings
      y = intToStr(datestring.year)
      m = intToStr(datestring.month, 2)
      d = intToStr(datestring.day, 2)
    result = fmt"{y}-{m}-{d}"
  else:
    # We guess that the creation time of the post is usually what you want as
    # the datestamp of the blog. If you don't want this, you can rename the file
    # using the yyyy-MM-dd-slug.md format.
    result = getCreationTime(file).format("yyyy-MM-dd")

proc findBlogPosts(directory: string, tmpldir: string, tmpl: string = "post.mustache"): seq[Table[string, string]] =
  for f in walkDirRec(directory):
    let (dir, name, ext) = splitFile(f)
    if ext == ".md":
      var
        year, month, day: int
      discard scanf(name, "$i-$i-$i", year, month, day)
      let
        basedir = lastPathPart(dir)
        blog = if basedir in blog_dirs or year > 0: true else: false
      if blog:
        var blogContext = newContext(searchDirs = @[tmpldir])
        blogContext["slug"] = getSlug(name, year > 0)
        blogContext["date"] = getBlogDate(f, (year, month, day))
        let rendered = blogContext.renderTemplate(f, tmpl)
        result.add({"post": rendered}.toTable)

proc buildCmd() =
  let
    wd = os.getCurrentDir()


@@ 123,6 163,8 @@ proc buildCmd() =

  loadMetaData(wd / "config.cfg", mcontext)

  let blogs = findBlogPosts(condir, tmpldir)

  for f in walkDirRec(condir, {pcFile, pcDir}, relative = true):
    case getFileInfo(condir / f).kind:
      of pcDir:


@@ 132,7 174,10 @@ proc buildCmd() =
          (dir, fname, ext) = splitFile(f)
          savepath = joinPath(outdir, dir)
        if ext == ".md":
          let output  = mcontext.renderTemplate(condir / f, tmpldir = tmpldir)
          var tmpl = "page.mustache"
          if blogs.len > 0:
            mcontext["posts"] = blogs
          let output  = mcontext.renderTemplate(condir / f, tmpl, tmpldir = tmpldir)
          writeFile(savepath / fname & ".html", output)
        else:
          copyFile(condir / f, savepath / fname & ext)