heroagent/aiprompts/jet_instructions.md
2025-04-23 04:18:28 +02:00

5.5 KiB

Jet Template Engine Syntax Reference

Delimiters

Template delimiters are {{ and }}.
Delimiters can use . to output the execution context:

hello {{ . }} <!-- context = "world" => "hello world" -->

Whitespace Trimming

Whitespace around delimiters can be trimmed using {{- and -}}:

foo {{- "bar" -}} baz <!-- outputs "foobarbaz" -->

Whitespace includes spaces, tabs, carriage returns, and newlines.

Comments

Comments use {* ... *}:

{* this is a comment *}

{*
    Multiline
    {{ expressions }} are ignored
*}

Variables

Initialization

{{ foo := "bar" }}

Assignment

{{ foo = "asd" }}
{{ foo = 4711 }}

Skip assignment but still evaluate:

{{ _ := stillRuns() }}
{{ _ = stillRuns() }}

Expressions

Identifiers

Identifiers resolve to values:

{{ len("hello") }}
{{ isset(foo, bar) }}

Indexing

String

{{ s := "helloworld" }}
{{ s[1] }} <!-- 101 (ASCII of 'e') -->

Slice / Array

{{ s := slice("foo", "bar", "asd") }}
{{ s[0] }}
{{ s[2] }}

Map

{{ m := map("foo", 123, "bar", 456) }}
{{ m["foo"] }}

Struct

{{ user["Name"] }}

Field Access

Map

{{ m.foo }}
{{ range s }}
    {{ .foo }}
{{ end }}

Struct

{{ user.Name }}
{{ range users }}
    {{ .Name }}
{{ end }}

Slicing

{{ s := slice(6, 7, 8, 9, 10, 11) }}
{{ sevenEightNine := s[1:4] }}

Arithmetic

{{ 1 + 2 * 3 - 4 }}
{{ (1 + 2) * 3 - 4.1 }}

String Concatenation

{{ "HELLO" + " " + "WORLD!" }}

Logical Operators

  • &&
  • ||
  • !
  • ==, !=
  • <, >, <=, >=
{{ item == true || !item2 && item3 != "test" }}
{{ item >= 12.5 || item < 6 }}

Ternary Operator

<title>{{ .HasTitle ? .Title : "Title not set" }}</title>

Method Calls

{{ user.Rename("Peter") }}
{{ range users }}
    {{ .FullName() }}
{{ end }}

Function Calls

{{ len(s) }}
{{ isset(foo, bar) }}

Prefix Syntax

{{ len: s }}
{{ isset: foo, bar }}

Pipelining

{{ "123" | len }}
{{ "FOO" | lower | len }}
{{ "hello" | repeat: 2 | len }}

Escapers must be last in a pipeline:

{{ "hello" | upper | raw }} <!-- valid -->
{{ raw: "hello" }}          <!-- valid -->
{{ raw: "hello" | upper }}  <!-- invalid -->

Piped Argument Slot

{{ 2 | repeat("foo", _) }}
{{ 2 | repeat("foo", _) | repeat(_, 3) }}

Control Structures

if

{{ if foo == "asd" }}
    foo is 'asd'!
{{ end }}

if / else

{{ if foo == "asd" }}
    ...
{{ else }}
    ...
{{ end }}

if / else if

{{ if foo == "asd" }}
{{ else if foo == 4711 }}
{{ end }}

if / else if / else

{{ if foo == "asd" }}
{{ else if foo == 4711 }}
{{ else }}
{{ end }}

range

Slices / Arrays

{{ range s }}
    {{ . }}
{{ end }}

{{ range i := s }}
    {{ i }}: {{ . }}
{{ end }}

{{ range i, v := s }}
    {{ i }}: {{ v }}
{{ end }}

Maps

{{ range k := m }}
    {{ k }}: {{ . }}
{{ end }}

{{ range k, v := m }}
    {{ k }}: {{ v }}
{{ end }}

Channels

{{ range v := c }}
    {{ v }}
{{ end }}

Custom Ranger

Any Go type implementing Ranger can be ranged over.

else

{{ range searchResults }}
    {{ . }}
{{ else }}
    No results found :(
{{ end }}

try

{{ try }}
    {{ foo }}
{{ end }}

try / catch

{{ try }}
    {{ foo }}
{{ catch }}
    Fallback content
{{ end }}

{{ try }}
    {{ foo }}
{{ catch err }}
    {{ log(err.Error()) }}
    Error: {{ err.Error() }}
{{ end }}

Templates

include

{{ include "./user.jet" }}

<!-- user.jet -->
<div class="user">
    {{ .["name"] }}: {{ .["email"] }}
</div>

return

<!-- foo.jet -->
{{ return "foo" }}

<!-- bar.jet -->
{{ foo := exec("./foo.jet") }}
Hello, {{ foo }}!

Blocks

block

{{ block copyright() }}
    <div>© ACME, Inc. 2020</div>
{{ end }}

{{ block inputField(type="text", label, id, value="", required=false) }}
    <label for="{{ id }}">{{ label }}</label>
    <input type="{{ type }}" value="{{ value }}" id="{{ id }}" {{ required ? "required" : "" }} />
{{ end }}

yield

{{ yield copyright() }}

{{ yield inputField(id="firstname", label="First name", required=true) }}

{{ block buff() }}
    <strong>{{ . }}</strong>
{{ end }}

{{ yield buff() "Batman" }}

content

{{ block link(target) }}
    <a href="{{ target }}">{{ yield content }}</a>
{{ end }}

{{ yield link(target="https://example.com") content }}
    Example Inc.
{{ end }}
{{ block header() }}
    <div class="header">
    {{ yield content }}
    </div>
{{ content }}
    <h1>Hey {{ name }}!</h1>
{{ end }}

Recursion

{{ block menu() }}
    <ul>
        {{ range . }}
            <li>{{ .Text }}{{ if len(.Children) }}{{ yield menu() .Children }}{{ end }}</li>
        {{ end }}
    </ul>
{{ end }}

extends

<!-- content.jet -->
{{ extends "./layout.jet" }}
{{ block body() }}
<main>This content can be yielded anywhere.</main>
{{ end }}

<!-- layout.jet -->
<html>
<body>
    {{ yield body() }}
</body>
</html>

import

<!-- my_blocks.jet -->
{{ block body() }}
<main>This content can be yielded anywhere.</main>
{{ end }}

<!-- index.jet -->
{{ import "./my_blocks.jet" }}
<html>
<body>
    {{ yield body() }}
</body>
</html>