This covers how HTT and indeed Lua resolves and imports code and how this relates to module names. This is important both when debugging errors and laying out your projects.
A template is a <file>.htt file, written in the HTT template syntax. HTT will compile this template to a Lua module, <file>.out.lua when it is first loaded. A template may also have a companion Code file, <file>.htt.lua, whose contents is prepended to the compiled module.
A module is a Lua concept and is, like a Python module, some unit of code and data. A module is typically a .lua file which would typically "export" a table of functions and data, defining the module's public API.
In the broader Lua ecosystem, modules may be implemented in C or similar by using the C API.
A component is a HTT concept. It is a "mini-template", a fragment of templating which can be called and passed around as a function to be rendered inside other components. See more in the Quick Start
By script file, we refer to the <file>.lua file which is passed to htt when running the program and which kicks off the code-generation process.
You start the code-generation process by passing a script file to HTT, e.g. htt <file>.lua.
As the script is loaded HTT resolves the path to the script file itself, and treats the directory of that file as the HTT root. All Lua modules and HTT template files are resolved relative to the HTT root directory.
When importing modules, Lua uses the string in package.path to build a list of paths to try, in-order. We can see the package.path by printing it:
$ cat /tmp/test.lua
print(package.path)
$ htt /tmp/test.lua
/tmp/?.lua;/tmp/?/init.lua;
Each path in package.path is separated by ;, with ? being the placeholder which is replaced by the module name (the string argument to require).
If package.path is /tmp/?.lua;/tmp/?/init.lua; and we require("foo"), Lua would:
/tmp/foo.lua/tmp/foo/init.lua
If package.path is /tmp/?.lua;/tmp/?/init.lua; and we require("foo.bar"), Lua would:
/tmp/foo/bar.lua/tmp/foo/bar/init.lua
HTT extends Lua's regular require function to also work for importing HTT templates. When requiring templates, three things are different from importing regular Lua modules:
require string with /// (instead of Lua's .), also on Windows.htt file extension
Basically, we write what looks like a relative path, using the Unix path-separator (/) with // prefixed.
-- look for "foo.htt", relative to HTT root
local mod = require("//foo.htt")
-- look for "bar/foo.htt", relative to HTT root
local mod2 = require("//bar/foo.htt")