Version: v0.6.0 - Beta.  We welcome contributors & feedback.  THanks!


THT introduces template functions, which let you embed HTML and other content within your scripts.


Templates look and act just like functions, but use the template keyword.

The type of template (e.g. 'html') is indicated in the name of the template.

Instead of code, the body of a template is a freeform multiline string.

When it called, the body is transformed according to its type and then returned as a TypeString, which can then be passed to your output.

Whitespace and extra indentation is trimmed so you can indent however you wish.

    title: 'My Website',
    body: pageHtml()

// An HTML template
template pageHtml() {

    <h1>My Website</h1>
    <p>Welcome to my site!</p>


TipBecause templates are just functions, they can be be organized any way you like: by page, modules, classes, etc.


Calls to the Db, File, and System modules are not allowed within templates.

This keeps your front-end (“view”) code separate from your back-end code, making your app easier to maintain over time.


Template functions are compiled to PHP as pure string concatenation functions, so they usually execute very quickly.

HTML templates are parsed at compile time and cached.

Template Logic 

There are two ways to include THT logic in a template.

Expressions {{ ... }}

THT expressions can be embedded with double-curly braces.

The result is automatically escaped according to the type of template.

template pageHtml($userName) {

    <h1>My Website</h1>
    <p>Hello, {{ $userName.upperCase() }}!</p>


Code Lines --

Lines starting with the Code Line operator -- will be evaluated as inline THT.

Code lines must end in a semicolon or curly brace. If you need a larger block of logic, you should probably put it in a separate function.

template userListHtml($users) {

    -- $numUsers = $users.length();

    -- if !$numUsers {
        <p>No users here!</p>
    -- } else {
        <p>There are {{ $numUsers }} users:</p>
        -- foreach $users as $user {
            <li>{{ $user }}</li>
        -- }
    -- }

Nested Templates 

The output of other templates are included as-is (without escaping) if the template types are the same.

In this way, you can use smaller templates as “partials”.

// a single post link
template postLinkHtml($post) {

    <a href={{ $post.url }}>{{ $post.title }}</a>


// a list of post links
template allPostsHtml($posts) {

    -- foreach $posts as $p {
        <li>{{ postLinkHtml($p) }}</li>
    -- }


Template Types 

The name of your template must end in a suffix that tells THT how it should process the content.

Supported types are:

HTML Templates 

See HTML-C shortcuts for quicker ways to write HTML in your templates.

Extra whitespace inside of multiline tags is automatically trimmed so you can indent your tags without affecting the output with stray spaces.

See also: Format Checker rules for HTML templates.

// An HTML template
template pageHtml() {

    <h1>My Website</h1>
    <p>Welcome to my site!</p>


CSS Templates 

THT expressions within CSS should only be used as property values.

Characters like ; and { } will be removed.

template siteCss($brandColor) {

    header {
        background-color: {{ $brandColor }};


When a CSS TypeString is included in an HTML template, it will wrap the content in a <style> block.

See the Css module for stylesheet helpers.

JavaScript (Js) Templates 

THT expressions within a Js template are converted to JavaScript data values.

It handles Strings, Booleans, Numbers. Maps & Lists are converted to JSON.

When a Js TypeString is included in an HTML template, it will wrap the content in a <script> block and a self-executing function.

// In THT...
mainJs('Tim Plate');

template mainJs($userName) {

    var userName = {{ $userName }};


// When included in an HTML template, it looks like this:
    var userName = "Tim Plate";

JCON Templates 

Jcon templates can be used to define hardcoded data using JCON syntax. It returns a Map or List instead of a TypeString.

THT expressions or logic are not supported in this type of template.

$data = dataJcon();
print($data.myKey[1]);  //= 'list item 1'

template dataJcon() {
        myKey: [
            list item 0
            list item 1

        myOtherKey: true

Litemark (Lite) Templates 

Lite templates support embedded Litemark content for writing page content, documentation, etc.

NoteTHT expressions aren’t well supported in Litemark templates yet. For now, it is recommended that you use Lite templates for content that is not dynamic.

template mainLite() {

    # Heading

    Lorem ipsum thtum.

    - List Item 1
    - List Item 2

Text Templates 

Text templates do not transform or escape the content.

They return a plain string instead of a TypeString.

template emailText($name) {

     Hello {{ $name }},

     Thanks for joining our app!

     - The Team