Skip to content

Commit

Permalink
Add support for #gen generator funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
afrankvt committed Jan 26, 2022
1 parent bc8a4e6 commit 7f76029
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## Version 0.9 (working)
* Add support for `#gen` generator funcs
* Add support for new `{{#partial}}` syntax (deprecate `{{> }}` syntax)
* Update copyright to Novant LLC

Expand Down
15 changes: 15 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ f.render(out, map) // stream to out
* [Variables](#variables)
* [If Blocks](#if-blocks)
* [Each Blocks](#each-iterator-blocks)
* [Generators](#generators)
* [Partials](#partials)
* [Comments](#comments)

Expand Down Expand Up @@ -150,6 +151,20 @@ replaced with each element in `var`:
Item #2
Item #3

### Generators

Generators use the `{{#gen var}}` syntax, where `var` is a Fantom function that
dynamically generates content when the template is rendered at runtime:

template:
{{#gen foo}}

map:
["foo": |OutStream out| { out.print("generated") }]

output:
generated

### Partials

Partials use the `{{#partial var}}` syntax to inject content from another
Expand Down
17 changes: 17 additions & 0 deletions src/fanbars/fan/Def.fan
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,23 @@ internal class RawTextDef : Def
}
}

*************************************************************************
** GenDef
*************************************************************************

internal class GenDef : Def
{
new make(|This| f) { f(this) }

VarDef func

override Void dump(OutStream out, Int indent)
{
out.print(Str.spaces(indent))
out.printLine("{{#gen $func.dumpPath")
}
}

*************************************************************************
** PartialDef
*************************************************************************
Expand Down
5 changes: 5 additions & 0 deletions src/fanbars/fan/Parser.fan
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ internal class Parser
parent.children.push(def)
stack.push(def)

case "#gen":
func := parseVarDef
def := GenDef { it.func=func }
parent.children.push(def)

case "#partial":
var := parseVarDef(null, 1)
def := PartialDef { it.var=var }
Expand Down
5 changes: 5 additions & 0 deletions src/fanbars/fan/Renderer.fan
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ internal const class Renderer
else
out.print(v==null ? "" : v.toStr)

case GenDef#:
f := resolveVar(def->func, map) as Func
if (f == null) return
f(out)

case PartialDef#:
partial := resolvePartial(def, partials)
partial?.render(out, map, partials)
Expand Down
17 changes: 17 additions & 0 deletions src/fanbars/test/ParserTest.fan
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,17 @@ class ParserTest : Test
verifyErr(ParseErr#) { p("{{!-- foo {{!-- bar --}}") }
}

//////////////////////////////////////////////////////////////////////////
// Gen
//////////////////////////////////////////////////////////////////////////

Void testGen()
{
d := p("{{#gen func}}")
verifyEq(d.children.size, 1)
verifyGen(d.children[0], "func")
}

//////////////////////////////////////////////////////////////////////////
// Partials
//////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -346,6 +357,12 @@ class ParserTest : Test
verifyVar(d->var, path)
}

private Void verifyGen(Def d, Str ref)
{
verifyEq(d.typeof, GenDef#)
verifyVar(d->func, [ref])
}

private Void verifyPartial(Def d, Str ref)
{
verifyEq(d.typeof, PartialDef#)
Expand Down
23 changes: 23 additions & 0 deletions src/fanbars/test/RendererTest.fan
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,29 @@ class RendererTest : Test
"<tr><td>4</td><td>5</td><td>?</td></tr>")
}

//////////////////////////////////////////////////////////////////////////
// Gen
//////////////////////////////////////////////////////////////////////////

Void testGen()
{
m := ["f1": |OutStream out| { out.print("from generator") }]
s := "{{#gen f1}}"
t := r(s,m)
verifyEq(t, "from generator")

// test closure
x := 12
y := "foo"
f2 := |OutStream out| {
out.print("from generator, where x is ${x} and y is ${y}")
}
m = ["f2":f2]
s = "{{#gen f2}}"
t = r(s,m)
verifyEq(t, "from generator, where x is 12 and y is foo")
}

//////////////////////////////////////////////////////////////////////////
// Partials
//////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit 7f76029

Please sign in to comment.