ref: 361a7529023a32f43b04c5662116259c2fef6f70 tlog/README.md -rw-r--r-- 3.3 KiB
361a7529Ruben Schuller add a license 1 year, 3 months ago


builds.sr.ht status

simple & flexible templating.


i've gotten annoyed by other static site generators doing a million things. i just want to generate some html pages. so this.


create a hierarchy like the following:

  • content

    • page
      • content.md
      • data.tcl
  • global

    • date.tcl
  • template

    • template.html

then run tlog:

tlog.tcl -t template/template.html global page

this uses template.html as template, reading contents to be inserted from global and page.


a template can be anything plaintext. as subst is the mechanism used, it's rules apply.

a template thus looks kind of like this:


[ insert title ]

[ insert date ]

[ insert content ]

the insert command is another way to insert variables, as a way to have a fixed way to insert stuff in case the internal data representation changes (which it has done multiple times already :P) without requiring touching contents.


content is always consumed as whole directory, the names of the files without extension are being used to reference the contents from a template.

a tradeof which is being made is that contents can be preprocessed. while this could be done in an additional external step, it's common enough to be included. currently there are three types of content:

  • markdown (extension .md) parsed & formatted as html with tcllib "Markdown"
  • tcl (extension .tcl) is evaluated and can reign freely. the output is also stored.
  • html (extension .html) is just copied.

as contents are a whole directory, we can do without the thing other systems call "frontmatter" by evaluating tcl scripts in the content directory.

there can't be contents of the same name, so data.md and data.tcl aren't permitted, not even when in two different directories (as we can load multiple ones). reading the contents of the same name will error out to avoid confusion.

examples for contents:

$ cat content/page0/content.md
# foobar
it's markdown!

$ cat content/page0/data.tcl
dict set context title "the title"

$ cat global/date.tcl
proc date {} {
	set date 0
	foreach { path } [ glob -type f * ] {
		set ndate [ file mtime $path ]
		if [ expr $ndate > $date ] {
			set date $ndate
	return [ clock format $date -format %Y-%m-%d ]

dict set context date [ date ]


contents are read into the context dictionary, with their filenames without extension used as keys. tcl script contents can modify the context dictionary as in the example above.

this context dictionary gets unpacked using dict with before running subst with the template as argument.


to tie everything together, you can use make:

output/%.html: template/template.html global/date.tcl content/%/content.md content/%/data.tcl
	tlog.tcl -t template/template.html global content/$* > $@


in the example directory is a somewhat complete way to build a simple blog.