templ8go
is a small library designed to resolve template strings like Hello {{ user.name }}
utilizing the V8 JavaScript engine. The play on words in the
name stems from blending "template" with "V8" (the JavaScript engine), and "8"
phonetically resembling "ate". Sorry for the dad joke, ChatGPT come up with it.
While traditional templating engines are great for generating large blocks of
text and support a variety of built-in functions and pipe syntax, templ8go
takes a different approach. It leverages the power and flexibility of
JavaScript for manipulating and interpolating short strings. This allows for
more dynamic and programmable template resolution without leaving the comfort
of Go.
Consider the following examples where templ8go
shines:
Hello {{ user.name }}
with{user:{name: Mustafa}}
resolves toHello Mustafa
.Your balance is {{ account.balance.toFixed(2) }}
with{account:{balance: 1234.567}}
becomesYour balance is 1234.57
.
These examples showcase the simplicity and power of using JavaScript expressions within templates.
- Dynamic Expression Evaluation: Use JavaScript expressions right within your template strings.
- Bindings Support: Seamlessly pass Go variables into the JavaScript execution context to be used within your template expressions.
- Easy Integration: Designed to be easily integrated into any Go project that needs flexible string interpolation.
- Security: It leverages V8, the same Javascript engine that runs Cloudflare workers and Chrome. Though we can add even more hardening.
First, ensure you have Go installed on your machine (version 1.21 or newer is
recommended). Then, install templ8go
using go get
:
go get -u github.com/mustafaakin/templ8go
Here's a quick example to get you started:
package main
import (
"fmt"
"github.com/mustafaakin/templ8go"
)
func main() {
template := "Hello {{ user.name }}"
bindings := map[string]any{
"user": map[string]any{
"name": "Mustafa",
},
}
result, err := templ8go.ResolveTemplate(bindings, template)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Println(result) // Output: Hello Mustafa
}
Or you can use the Javascript resolve directly to get the result of object without string interpolation which can be useful in some environments.
package main
import (
"fmt"
"github.com/mustafaakin/templ8go"
)
func main() {
bindings := map[string]any{
"user": map[string]any{
"name": "Mustafa",
},
}
result, err := templ8go.ResolveJSExpression(bindings, "user.name")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Println(result) // Output: Mustafa
}
You can change the default execution timeout via calling;
// now you have 200 Milliseconds for execution
SetDefaultExecutionTimeout(200 * time.Millisecond)
// rest is the same...
result, err := templ8go.ResolveJSExpression(bindings, "user.name")
...
Since we use V8 engine underneath, many things are possible.
-
Simple Arithmetic:
- Template:
The sum of 5 and 3 is {{ 5 + 3 }}.
- Bindings:
{}
- Output:
The sum of 5 and 3 is 8.
- Template:
-
Conditional Greetings:
- Template:
Good {{ hour < 12 ? 'morning' : 'afternoon' }}, {{ user.name }}!
- Bindings:
{ "hour": 9, "user": {"name": "Alice"} }
- Output:
Good morning, Alice!
- Template:
-
Array Operations:
- Template:
Users list: {{ users.map(user => user.name).join(', ') }}
- Bindings
{users: [{name: 'Alice'}, {name: 'Bob'}, {name: 'Charlie'}]}
- Output:
Users list Alice, Bob, Charlie
- Template:
-
Object Manipulation:
- Template:
{{ user.firstName }} {{ user.lastName }} is {{ user.age }} years old.
- Bindings:
{ "user": {"firstName": "John", "lastName": "Doe", "age": 28} }
- Output:
John Doe is 28 years old.
- Template:
-
Logical Operations:
- Template:
You are {{ age >= 18 ? 'an adult' : 'a minor' }}.
- Bindings:
{ "age": 20 }
- Output:
You are an adult.
- Template:
-
String Concatenation:
- Template:
{{ 'Hello, ' + user.name + '!'}}
- Bindings:
{ "user": {"name": "Jane"} }
- Output:
Hello, Jane!
- Template:
-
Using JavaScript Functions:
- Template:
Your score is {{ Math.min(score, 100) }}.
- Bindings:
{ "score": 105 }
- Output:
Your score is 100.
- Template:
-
Nested Object Access:
- Template:
Project {{ project.details.name }} is due on {{ project.details.dueDate }}.
- Bindings:
{ "project": {"details": {"name": "Apollo", "dueDate": "2024-03-01"}} }
- Output:
Project Apollo is due on 2024-03-01.
- Template:
-
Complex Expressions:
- Template:
{{ user.isActive ? user.name + ' is active and has ' + user.roles.length + ' roles' : user.name + ' is not active' }}.
- Bindings:
{ "user": {"name": "Eve", "isActive": true, "roles": ["admin", "editor"]} }
- Output:
Eve is active and has 2 roles.
- Template:
To contribute or modify templ8go
, clone the repository and ensure all dependencies are properly set up. Run tests with:
go test ./...
Feel free to submit pull requests or create issues for bugs, features, or suggestions.
Contributions are more than welcome! If you have an idea for an improvement or find a bug, please feel free to fork the repository, make your changes, and submit a pull request.
templ8go
is made available under the MIT License. For more details, see the LICENSE file in the repository.