The magic (or not) of Gills


One thing I've mentioned more than once in my recent articles on Jungle Coder is how the Gills software has been rather handy for different things, but I've never really dived into what using Gills is like. And, the real answer to what I've liked about Gills is that it's a decently flexible CMS, for what it does.

The technical details are as follows:

Gills has a database that contains Notes and Scripts. Scripts are Lua files that can either represent a page to be rendered, or a library file that can be included from other scripts.

Lua scripts, other than the small core Lua language, have a few things they can do: echo a string to the output buffer, flush the output buffer using a given output format (either HTML escaped, markdown, or "raw", which means text without HTML escaping). They can also run a search of the notes in the database, which returns a table of all of the notes that matched a given SQLite %TERM% search. Overall, it's not an incredibly sophisicated system.

However, it does have some nice properties.

For one, it makes it easy to put up a simple page without a lot of fuss and fiddle. Right now, if I want to make a page on the internet, I have a few options: I can create a Nim web app using Jester, I can add a page to, I can write a blog article, or, I can add a relevant page to my personal Gills instance. Just echo out the bits of things you need, and you're good to go. For two, there are times when it's just easier to write bits of Markdown for descriptive bits of text, but you still want to be able to make a checklist.

So, to give some examples of different Gills pages:

The Catering Checklist:

This one is pretty simple It's just a checklist of steps to remember when running a cater. It doesn't try to do anything fancy, if you reload the page, you'll lose your checklist state.


function raw(str) echo(str) flush_raw() end
function check(item) 
   raw([[<div style="margin:3px;"><label><input type="checkbox">]]..item..[[</label></div>]])

raw [[<meta name="viewport" content="width=device-width, initial-scale=1.0">]]
raw([[<form id="foo">]]) 

# Catering Checklist
## Before going out
]=]) flush_markdown()
check("Ensure I have my lighter for the sternos")
check("Set route to destination")
check("Count paper goods")
check("Get 1 bottle of water per 2 chafing stands, rounded up")
check("Get a bag of ice per two gallons to drink")
check("Take out paper goods first")
check("Take out Chips")
check("Take out cold goods")
check("Take out hot goods")
check("With the hot bag, liquid on bottom")
check("Make sure to grab receipt")
check("Make sure to grab temp paper")

echo([=[## Returning from Cater]=]) flush_markdown()
check("Give paperwork to manager")
check("Split tip with cook")
check("Bring in bags")



The List of (Comic/Blog/Other) Links

One thing that is nice to have is a list of sites you visit on a semi-regular basis. For instance, I keep up with Gunnerkrigg Court, Order of the Stick, Swords Comic, and a few others on a regular basis. So, rather than

The Kanban Pages

This one is a bit more involved, as it involves having real notes. The basic gist is that

function findMarks(mark, fn)
    local notes = search_notes("@"..mark.."[")
    local search = regexp.compile("@"..mark.."\\[([^\\]]+)\\]")

    for i=1,#notes do 
         local n = notes[i] 
         local toCopy = search.findAllSubmatch(n.content, -1)
         for j=1,#toCopy do 
             local tc = toCopy[j]
             fn(n, tc[2])