# Salix [![Go Reference](https://pkg.go.dev/badge/go.elara.ws/salix.svg)](https://pkg.go.dev/go.elara.ws/salix) [![Go Report Card](https://goreportcard.com/badge/go.elara.ws/salix)](https://goreportcard.com/report/go.elara.ws/salix) Salix (pronounced *say-lix*) is a Go templating engine inspired by [Leaf](https://github.com/vapor/leaf). Salix's syntax is similar to Leaf and (in my opinion at least), it's much more fun to write than the Go template syntax. If you like this project, please star the repo. I hope you enjoy! :) ## Table of contents - [Examples](#examples) - [Template](#template) - [API Usage](#api-usage) - [Tags](#tags) - [Creating custom tags](#creating-custom-tags) - [`for` tag](#for-tag) - [`if` tag](#if-tag) - [`include` tag](#include-tag) - [`macro` tag](#macro-tag) - [Functions](#functions) - [Global Functions](#global-functions) - [Adding Custom Functions](#adding-custom-functions) - [Expressions](#expressions) - [Ternary Expressions](#ternary-expressions) - [Coalescing operator](#coalescing-operator) - [The `in` operator](#the-in-operator) - [Acknowledgements](#acknowledgements) ## Examples ### Template ```html
User ID: #(i)
#if(user.LoggedIn):This user is logged in
#!if #if(user.IsAdmin):This user is an admin!
#!ifRegistered: #(user.RegisteredTime.Format("01-02-2006"))
It's a hot day!
#elif(weather.Temp < 0):It's freezing!
#else:The temperature is between 0 and 30
Content #!macro #macro("content") ``` When a macro tag has a block, it sets the macro's content. When it doesn't, it inserts the contents of the macro. In the above example, a macro is defined and then inserted. #### Using the `macro` tag with extra arguments Similar to the `include` tag, the `macro` tag can accept extra local variables as arguments. You can define these variables when including the macro. Here's an example: ``` #macro("content", x = 1, y = x + 2) ``` ## Functions Functions used in a template can accept any number of arguments but are limited to returning a maximum of two values. When a function returns two values, the second one must be an error value. ### Global Functions Salix includes several useful global functions in all templates: - `len(v any) int`: Returns the length of the value passed in. If the length cannot be found, it returns `-1`. - `toUpper(s string) string`: Returns `s`, but with all characters mapped to their uppercase equivalents. - `toLower(s string) string`: Returns `s`, but with all characters mapped to their lowercase equivalents. - `hasPrefix(s, prefix string) bool`: Returns true if `s` starts with `prefix`. - `trimPrefix(s, prefix string) string`: Returns `s`, but with `prefix` removed from the beginning. - `hasSuffix(s, suffix string) bool`: Returns true if `s` ends with `suffix`. - `trimSuffix(s, suffix string) string`: Returns `s`, but with `suffix` removed from the end. - `trimSpace(s string) string`: Returns `s`, but with any whitespace characters removed from the beginning and end. - `equalFold(s1, s2 string) bool`: Returns true if `s1` is equal to `s2` under Unicode case-folding, which is a general form of case-insensitivity. - `count(s, substr string) int`: Returns the amount of times that `substr` appears in `s`. - `split(s, sep string) []string`: Returns a slice containing all substrings separated by `sep`. - `join(ss []string, sep string) string`: Returns a string with all substrings in `ss` joined by `sep`. ### Adding Custom Functions You can include custom functions as variables using the WithVarMap method on templates or namespaces. Methods that fit the above conditions can also be used as template functions. ## Expressions Salix's expressions mostly work like Go's, but there are some extra features worth mentioning. ### Ternary Expressions Salix supports ternary expressions, which allow you to choose a value based on whether a condition is true. For example: ``` #(len(matches) > 1 ? "several matches" : "one match") ``` This example returns `"several matches"` if the length of matches is greater than one. Otherwise, it returns `"one match"`. ### Coalescing operator The coalescing operator allows you to return a default value if a variable isn't defined. Here's an example: ```