Add the ability to ignore errors in ExprTags

This commit is contained in:
Elara 2024-02-07 18:11:24 -08:00
parent 958a25d559
commit 9df2382a33
6 changed files with 370 additions and 323 deletions

View File

@ -26,6 +26,7 @@ Salix's syntax is similar to Leaf and (in my opinion at least), it's much more f
- [Global Functions](#global-functions)
- [Adding Custom Functions](#adding-custom-functions)
- [Expressions](#expressions)
- [Ignoring errors](#ignoring-errors)
- [Ternary Expressions](#ternary-expressions)
- [Coalescing operator](#coalescing-operator)
- [The `in` operator](#the-in-operator)
@ -189,6 +190,19 @@ You can include custom functions as variables using the WithVarMap method on tem
Salix's expressions mostly work like Go's, but there are some extra features worth mentioning.
### Ignoring errors
If you'd like to ignore errors in an expression tag, you can do that by adding a question mark at the end.
```html
<!-- This would return an error if example wasn't defined or if it didn't have an Example() method -->
#(example.Example())
<!-- This would ignore any error and keep executing the rest of the template -->
#(example.Example())?
```
### Ternary Expressions
Salix supports ternary expressions, which allow you to choose a value based on whether a condition is true. For example:

View File

@ -32,8 +32,9 @@ func (t Tag) Pos() Position {
}
type ExprTag struct {
Value Node
Position Position
Value Node
IgnoreError bool
Position Position
}
func (et ExprTag) Pos() Position {

View File

@ -13,4 +13,4 @@
</div>
#!for
</body>
</html>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -59,12 +59,12 @@ Root = items:(Tag / ExprTag / EndTag / Text)* {
return out, nil
}
Tag = '#' name:Ident params:ParamList? body:':'? {
Tag = '#' name:Ident params:ParamList? ignoreErr:'?'? body:':'? {
return ast.Tag{
Name: name.(ast.Ident),
Params: toNodeSlice(params),
HasBody: body != nil,
Position: getPos(c),
Name: name.(ast.Ident),
Params: toNodeSlice(params),
HasBody: body != nil,
Position: getPos(c),
}, nil
}
@ -75,10 +75,11 @@ EndTag = "#!" name:Ident {
}, nil
}
ExprTag = "#(" item:Expr ')' {
ExprTag = "#(" item:Expr ')' ignoreErr:'?'? {
return ast.ExprTag{
Value: item.(ast.Node),
Position: getPos(c),
Value: item.(ast.Node),
IgnoreError: ignoreErr != nil,
Position: getPos(c),
}, nil
}
@ -248,4 +249,4 @@ ArithmeticOp = ('+' / '-' / '/' / '*' / '%') {
Text = . [^#]* { return ast.Text{Data: c.text, Position: getPos(c)}, nil }
_ "whitespace" ← [ \t\r\n]*
_ "whitespace" ← [ \t\r\n]*

View File

@ -112,7 +112,11 @@ func (t *Template) execute(w io.Writer, nodes []ast.Node, local map[string]any)
case ast.ExprTag:
v, err := t.getValue(node.Value, local)
if err != nil {
return err
if node.IgnoreError {
continue
} else {
return err
}
}
if _, ok := v.(ast.Assignment); ok {
continue