🎭Expressions
On the previous pages we talked a lot about printable expressions and regular expressions. So let's clarify what exactly an expression is.
An expression is a Go expression that yields a value. Valid Expressions are:
A variable or constant
A Go expression/literal like
"abc"
,123
, or"abc" == "def"
.A function call that returns a single value
Additionally, corgi adds a ternary and a "chain" expression. More on that below. And, of course, string interpolation, which you already learned about in the interpolation chapter.
Implementation Note: While you can use `backtick strings
` you cannot span them over multiple lines like you can in Go. Depending on your use case there are better alternatives.
Printable Types
If your expression gets printed, e.g. the value of an attribute, you are restricted to these printable types:
uint
,uint8
,uint16
,uint32
,uint64
int
,int8
,int16
,int32
,int64
string
bool
corgi.HTML
,corgi.HTMLAttr
,corgi.CSS
,corgi.URL
,corgi.Srcset
,corgi.JS
,corgi.JSStr,
andcorgi.JSAttr
in their appropriate contexts (more on them in the Security and Escaping chapter)Any type implementing
fmt.Stringer
A pointer to the above
A (possibly typed)
nil
which will print nothing
If you try to print something else, the generated function will return with an error.
Ternary Expressions
Aside from the expressions listed above, corgi also supports ternary expressions in the form of a special ternary function.
ifTrue
and ifFalse
can be any Go expression.
cond
can be any Go expression that yields a bool
value.
Ternary expressions can be used anywhere in a regular Go expression.
Chain Expressions
You know the problem: You want to access data.MyField.MySlice[3]
, but MyField
could be nil
, and MySlice
might not even be of length 3
. The solution is to add if
s that check nilness, length, and map indexes.
However, checks like these create an enormous bloat in template files. This is why corgi adds a second utility that allows you to perform those kind of checks. You can use a ?
to perform zero value checks, length/index checks, and checked type assertions for any expression that consists of only accessing fields/maps/slices.
Chain Expressions cannot be embedded inside Go expressions.
You can also add a default if your checks fail by appending a ~
. Defaults can be any Go expression.
Depending on the context you use chain expressions, they behave differently:
When assigning a value to an attribute or setting the value of a mixin argument, that attribute or mixin arg will only be set if the value passes all checks. For required arguments you need to provide a default.
When used in interpolation and a check fails, nothing will be printed.
When used as condition for an
if
, theif
will only be executed if all checks pass.When used as a range expression in a
for
loop, that loop will only be executed if the value passes all checks.
Technical Note: Corgi guarantees that it will call each function in a chain expression only once.
If the expression yields a pointer that you want to dereference, you can place an *
at the start of the expression to dereference the resolved value. Defaults are assumed to be already dereferenced.
Here are a couple more examples, just to make sure you undestand everything:
Last updated