Version: v0.7.1 - Beta.  We welcome contributors & feedback.



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


In PHP, it is common to use a third-party template language (e.g. Twig) to keep your front-end code separated from the rest.

THT templates have some advantages over this approach:

How Templates Work 

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

The body of a template is a freeform multi-line string.

You define the type of a template (e.g. 'html', 'js') by appending it to the template name. (e.g. 'contactFormHtml', 'componentJs', etc.)

Extra indentation is automatically trimmed.

tm pageHtml {

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

Template Types 

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

Supported types are:

Return Values

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

Template Logic 

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

Expressions {{...}}

THT expressions can be embedded with double-curly braces.

tm pageHtml($userName) {

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

Code Lines ---

Lines that start with the Code Line operator --- will be evaluated as inline THT code.

(The lines also help to visually separate blocks of code.)

tm userListHtml($users) {

    --- if !$users {

        <p> No users here!

    --- } else {

        <p> There are {{ $users.length() }} users:
        --- foreach $users as $user {
            <li> {{ $user }}
        --- }

    --- }

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
tm postLinkHtml($post) {
    <a href="{{ $post.url }}"> {{ $post.title }}

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

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



Within templates, backslashes \ are treated as literal characters.

If you need to escape characters like --- and {{, just use a template expression with a literal string.

tm html {
    \n is a newline character.
    {{ '---' }} This is not a code line.

// Output:

\n is a newline character.
--- This is not a code line.

HTML Templates 

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

// An HTML template
tm pageHtml {

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


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.

Closing Tags

THT expects you to close any multiline tag that is opened within a template.

If you want to bypass this requirement, add a “continue” <...> tag at the end.

tm myHtml {
       <h1> My Page


Litemark (Lm) Templates 

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

tm mainLm {

    # Heading

    Lorem ipsum thtum.

    - List Item 1
    - List Item 2

CSS Templates 

tm siteCss($brandColor) {

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



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

Characters like ; and { } will be removed.

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

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.


tm mainHtml {
    <h1> Profile
    {{ mainJs('Tim Plate') }}

tm mainJs($userName) {
    let userName = {{ $userName }};

// Output of mainHtml:

<script nonce="93jsf252...">
    let 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'

tm dataJcon {
        myKey: [
            list item 0
            list item 1

        myOtherKey: true

Text Templates 

Text templates do not transform or escape the content.

They return a plain string instead of a TypeString.

tm emailText($name) {

     Hello {{ $name }},

     Thanks for joining our app!

     - The Team