TemplateContext¶
Configuration for template parsing. Provides named filters that can be
applied to values via {{ value | filter }}, and named partials that can
be inlined via {{ include "name" }} or used as base templates for
inheritance via {{ extends "name" }}.
Seven built-in filters are always available: upper, lower, trim,
capitalize, title, default, and replace. User-supplied filters
with the same name override the built-in.
Constructors¶
create¶
new val create(
filters': Map[String val, AnyFilter] val = primitive _RawBlock
type _BlockKind is (_RegularBlock | _CommentBlock | _RawBlock)
// A resolved filter argument: either a string literal or a property reference.
type _ResolvedArg is (String | _PropNode)
class _Pipe
"""
A fully resolved pipe expression ready for rendering. The source — either a
property reference or a string literal — is piped through each filter in
order. Each filter has been validated at parse time for existence and correct
arity.
"""
let source: (_PropNode | String)
let filters: Array[(AnyFilter, Array[_ResolvedArg] box)] box
new box create(
source': (_PropNode | String),
filters': Array[(AnyFilter, Array[_ResolvedArg] box)] box
) =>
source = source'
filters = filters'
class _If
let value: _PropNode
let body: Array[_Part] box
let else_body: (Array[_Part] box | None)
new box create(
value': _PropNode,
body': Array[_Part] box,
else_body': (Array[_Part] box | None) = None
) =>
value = value'
body = body'
else_body = else_body'
class box _IfElse
"""
Marker on the open-block stack indicating an `if` block that has transitioned
to its `else` branch. Stores the original condition and if-body so they can
be assembled into the final `_If` node when `end` is encountered.
"""
let value: _PropNode
let if_body: Array[_Part] box
new box create(value': _PropNode, if_body': Array[_Part] box) =>
value = value'
if_body = if_body'
class box _IfNotElse
"""
Marker on the open-block stack indicating an `ifnot` block that has
transitioned to its `else` branch. Stores the original condition and if-body
so they can be assembled into the final `_IfNot` node when `end` is
encountered.
"""
let value: _PropNode
let if_body: Array[_Part] box
new box create(value': _PropNode, if_body': Array[_Part] box) =>
value = value'
if_body = if_body'
class _IfNot
let value: _PropNode
let body: Array[_Part] box
let else_body: (Array[_Part] box | None)
new box create(
value': _PropNode,
body': Array[_Part] box,
else_body': (Array[_Part] box | None) = None
) =>
value = value'
body = body'
else_body = else_body'
class _Loop
let target: String
let source: _PropNode
let body: Array[_Part] box
new box create(
target': String,
source': _PropNode,
body': Array[_Part] box
) =>
target = target'
source = source'
body = body'
class _Block
let name: String
let body: Array[_Part] box
new box create(name': String, body': Array[_Part] box) =>
name = name'
body = body'
type _Part is
( (_Literal, String) | _Pipe box | _PropNode
| _If box | _IfNot box | _Loop box | _Block box )
class box TemplateValue
"""
A value that can be used in a template. Either a single value or a
sequence of values.
When used with `HTMLTemplate`, values are automatically escaped based on
their HTML context. To bypass escaping for trusted content, use the
`unescaped` constructor instead of `create`.
"""
let _data: (String | Seq[TemplateValue] box)
let _properties: Map[String, TemplateValue] box
let _renderable: RenderableValue
new box create(
value: (String | Seq[TemplateValue] box),
properties: Map[String, TemplateValue] box = Map[String, TemplateValue]
) =>
_data = value
_properties = properties
_renderable = _HTMLEscapingRenderer
new box unescaped(
value: (String | Seq[TemplateValue] box),
properties: Map[String, TemplateValue] box = Map[String, TemplateValue]
) =>
"""
Create a value that bypasses HTML auto-escaping in `HTMLTemplate`.
The content is inserted as-is, without context-aware escaping. Use this
only for content you trust (e.g., pre-sanitized HTML fragments).
Has no effect when used with plain `Template`, which does not escape.
Note: the unescaped annotation applies only to direct variable
substitution (`{{ name }}`). When a value passes through a filter pipe
(`{{ name | upper }}`), the result is always escaped — filters could
introduce unsafe content.
"""
_data = value
_properties = properties
_renderable = _NoEscapeRenderer
fun apply(name: String): TemplateValue ? => _properties(name)?
fun string(): String ? => _data as String
fun renderable(): RenderableValue =>
"""
The rendering strategy for this value. `HTMLTemplate` calls this to
determine how to escape the value based on HTML context.
"""
_renderable
fun values(): Iterator[TemplateValue] =>
match _data
| let seq: Seq[TemplateValue] box => seq.values()
else Array[TemplateValue].values()
end
fun box _is_truthy(): Bool =>
match \exhaustive\ _data
| let _: String => true
| let seq: Seq[TemplateValue] box => seq.values().has_next()
end
class TemplateValues
"""
A scoped key-value store for template rendering. Values are stored as
`TemplateValue` entries and looked up by name. Lookups check the local
scope first, then walk up the parent chain.
Use `scope()` to create a writable child that inherits all values from
this set without copying. Use `update()` and `unescaped()` to add values.
"""
let _parent: (TemplateValues box | None)
let _values: Map[String, TemplateValue]
new _create(
parent: TemplateValues box,
values: Map[String, TemplateValue]
) =>
_parent = parent
_values = values
new create() =>
_parent = None
_values = Map[String, TemplateValue]
fun box apply(name: String): TemplateValue ? =>
try _values(name)?
else
match \exhaustive\ _parent
| let parent: TemplateValues box => parent(name)?
| None => error
end
end
fun box _lookup(prop: _PropNode): TemplateValue ? =>
var value = this(prop.name)?
for name in prop.props.values() do
value = value(name)?
end
value
fun ref update(name: String, value: (String | TemplateValue)) =>
"""
Store a value under the given name. String values are wrapped in a
`TemplateValue` automatically. This is also the target of Pony's
sugar for `values("key") = "value"`.
"""
_values(name) =
match \exhaustive\ value
| let string: String => TemplateValue(string)
| let template_value: TemplateValue => template_value
end
fun ref unescaped(name: String, value: String) =>
"""
Store a string value that bypasses HTML auto-escaping in `HTMLTemplate`.
See `TemplateValue.unescaped` for details. For structured values (with
properties or sequences), use `TemplateValue.unescaped()` directly and
pass the result to `update()`.
"""
_values(name) = TemplateValue.unescaped(value)
fun box scope(): TemplateValues =>
"""
Create an empty writable child scope backed by this value set as a
read-only parent. Writes go to the child; lookups that miss in the
child fall through to the parent.
"""
TemplateValues._create(this, Map[String, TemplateValue])
fun box _override(name: String, value: TemplateValue): TemplateValues =>
let values = Map[String, TemplateValue]
values(name) = value
TemplateValues._create(this, values)
class TemplateContext
"""
Configuration for template parsing. Provides named filters that can be
applied to values via `{{ value | filter }}`, and named partials that can
be inlined via `{{ include "name" }}` or used as base templates for
inheritance via `{{ extends "name" }}`.
Seven built-in filters are always available: `upper`, `lower`, `trim`,
`capitalize`, `title`, `default`, and `replace`. User-supplied filters
with the same name override the built-in.
"""
let filters: Map[String, AnyFilter] box
let partials: Map[String, String] box
new val create(
filters': Map[String, AnyFilter] val =
recover Map[String, AnyFilter] end,
partials': Map[String val, String val] val = primitive _RawBlock
type _BlockKind is (_RegularBlock | _CommentBlock | _RawBlock)
// A resolved filter argument: either a string literal or a property reference.
type _ResolvedArg is (String | _PropNode)
class _Pipe
"""
A fully resolved pipe expression ready for rendering. The source — either a
property reference or a string literal — is piped through each filter in
order. Each filter has been validated at parse time for existence and correct
arity.
"""
let source: (_PropNode | String)
let filters: Array[(AnyFilter, Array[_ResolvedArg] box)] box
new box create(
source': (_PropNode | String),
filters': Array[(AnyFilter, Array[_ResolvedArg] box)] box
) =>
source = source'
filters = filters'
class _If
let value: _PropNode
let body: Array[_Part] box
let else_body: (Array[_Part] box | None)
new box create(
value': _PropNode,
body': Array[_Part] box,
else_body': (Array[_Part] box | None) = None
) =>
value = value'
body = body'
else_body = else_body'
class box _IfElse
"""
Marker on the open-block stack indicating an `if` block that has transitioned
to its `else` branch. Stores the original condition and if-body so they can
be assembled into the final `_If` node when `end` is encountered.
"""
let value: _PropNode
let if_body: Array[_Part] box
new box create(value': _PropNode, if_body': Array[_Part] box) =>
value = value'
if_body = if_body'
class box _IfNotElse
"""
Marker on the open-block stack indicating an `ifnot` block that has
transitioned to its `else` branch. Stores the original condition and if-body
so they can be assembled into the final `_IfNot` node when `end` is
encountered.
"""
let value: _PropNode
let if_body: Array[_Part] box
new box create(value': _PropNode, if_body': Array[_Part] box) =>
value = value'
if_body = if_body'
class _IfNot
let value: _PropNode
let body: Array[_Part] box
let else_body: (Array[_Part] box | None)
new box create(
value': _PropNode,
body': Array[_Part] box,
else_body': (Array[_Part] box | None) = None
) =>
value = value'
body = body'
else_body = else_body'
class _Loop
let target: String
let source: _PropNode
let body: Array[_Part] box
new box create(
target': String,
source': _PropNode,
body': Array[_Part] box
) =>
target = target'
source = source'
body = body'
class _Block
let name: String
let body: Array[_Part] box
new box create(name': String, body': Array[_Part] box) =>
name = name'
body = body'
type _Part is
( (_Literal, String) | _Pipe box | _PropNode
| _If box | _IfNot box | _Loop box | _Block box )
class box TemplateValue
"""
A value that can be used in a template. Either a single value or a
sequence of values.
When used with `HTMLTemplate`, values are automatically escaped based on
their HTML context. To bypass escaping for trusted content, use the
`unescaped` constructor instead of `create`.
"""
let _data: (String | Seq[TemplateValue] box)
let _properties: Map[String, TemplateValue] box
let _renderable: RenderableValue
new box create(
value: (String | Seq[TemplateValue] box),
properties: Map[String, TemplateValue] box = Map[String, TemplateValue]
) =>
_data = value
_properties = properties
_renderable = _HTMLEscapingRenderer
new box unescaped(
value: (String | Seq[TemplateValue] box),
properties: Map[String, TemplateValue] box = Map[String, TemplateValue]
) =>
"""
Create a value that bypasses HTML auto-escaping in `HTMLTemplate`.
The content is inserted as-is, without context-aware escaping. Use this
only for content you trust (e.g., pre-sanitized HTML fragments).
Has no effect when used with plain `Template`, which does not escape.
Note: the unescaped annotation applies only to direct variable
substitution (`{{ name }}`). When a value passes through a filter pipe
(`{{ name | upper }}`), the result is always escaped — filters could
introduce unsafe content.
"""
_data = value
_properties = properties
_renderable = _NoEscapeRenderer
fun apply(name: String): TemplateValue ? => _properties(name)?
fun string(): String ? => _data as String
fun renderable(): RenderableValue =>
"""
The rendering strategy for this value. `HTMLTemplate` calls this to
determine how to escape the value based on HTML context.
"""
_renderable
fun values(): Iterator[TemplateValue] =>
match _data
| let seq: Seq[TemplateValue] box => seq.values()
else Array[TemplateValue].values()
end
fun box _is_truthy(): Bool =>
match \exhaustive\ _data
| let _: String => true
| let seq: Seq[TemplateValue] box => seq.values().has_next()
end
class TemplateValues
"""
A scoped key-value store for template rendering. Values are stored as
`TemplateValue` entries and looked up by name. Lookups check the local
scope first, then walk up the parent chain.
Use `scope()` to create a writable child that inherits all values from
this set without copying. Use `update()` and `unescaped()` to add values.
"""
let _parent: (TemplateValues box | None)
let _values: Map[String, TemplateValue]
new _create(
parent: TemplateValues box,
values: Map[String, TemplateValue]
) =>
_parent = parent
_values = values
new create() =>
_parent = None
_values = Map[String, TemplateValue]
fun box apply(name: String): TemplateValue ? =>
try _values(name)?
else
match \exhaustive\ _parent
| let parent: TemplateValues box => parent(name)?
| None => error
end
end
fun box _lookup(prop: _PropNode): TemplateValue ? =>
var value = this(prop.name)?
for name in prop.props.values() do
value = value(name)?
end
value
fun ref update(name: String, value: (String | TemplateValue)) =>
"""
Store a value under the given name. String values are wrapped in a
`TemplateValue` automatically. This is also the target of Pony's
sugar for `values("key") = "value"`.
"""
_values(name) =
match \exhaustive\ value
| let string: String => TemplateValue(string)
| let template_value: TemplateValue => template_value
end
fun ref unescaped(name: String, value: String) =>
"""
Store a string value that bypasses HTML auto-escaping in `HTMLTemplate`.
See `TemplateValue.unescaped` for details. For structured values (with
properties or sequences), use `TemplateValue.unescaped()` directly and
pass the result to `update()`.
"""
_values(name) = TemplateValue.unescaped(value)
fun box scope(): TemplateValues =>
"""
Create an empty writable child scope backed by this value set as a
read-only parent. Writes go to the child; lookups that miss in the
child fall through to the parent.
"""
TemplateValues._create(this, Map[String, TemplateValue])
fun box _override(name: String, value: TemplateValue): TemplateValues =>
let values = Map[String, TemplateValue]
values(name) = value
TemplateValues._create(this, values)
class TemplateContext
"""
Configuration for template parsing. Provides named filters that can be
applied to values via `{{ value | filter }}`, and named partials that can
be inlined via `{{ include "name" }}` or used as base templates for
inheritance via `{{ extends "name" }}`.
Seven built-in filters are always available: `upper`, `lower`, `trim`,
`capitalize`, `title`, `default`, and `replace`. User-supplied filters
with the same name override the built-in.
"""
let filters: Map[String, AnyFilter] box
let partials: Map[String, String] box
new val create(
filters': Map[String, AnyFilter] val =
recover Map[String, AnyFilter] end,
partials': Map[String, String] val =
recover Map[String, String] end)
: TemplateContext val^
Parameters¶
- filters': Map[String val, AnyFilter] val = primitive _RawBlock type _BlockKind is (_RegularBlock | _CommentBlock | _RawBlock)
// A resolved filter argument: either a string literal or a property reference. type _ResolvedArg is (String | _PropNode)
class _Pipe """ A fully resolved pipe expression ready for rendering. The source — either a property reference or a string literal — is piped through each filter in order. Each filter has been validated at parse time for existence and correct arity. """ let source: (_PropNode | String) let filters: Array[(AnyFilter, Array[_ResolvedArg] box)] box
new box create( source': (_PropNode | String), filters': Array[(AnyFilter, Array[_ResolvedArg] box)] box ) => source = source' filters = filters'
class _If let value: _PropNode let body: Array[_Part] box let else_body: (Array[_Part] box | None)
new box create( value': _PropNode, body': Array[_Part] box, else_body': (Array[_Part] box | None) = None ) => value = value' body = body' else_body = else_body'
class box _IfElse
"""
Marker on the open-block stack indicating an if block that has transitioned
to its else branch. Stores the original condition and if-body so they can
be assembled into the final _If node when end is encountered.
"""
let value: _PropNode
let if_body: Array[_Part] box
new box create(value': _PropNode, if_body': Array[_Part] box) => value = value' if_body = if_body'
class box _IfNotElse
"""
Marker on the open-block stack indicating an ifnot block that has
transitioned to its else branch. Stores the original condition and if-body
so they can be assembled into the final _IfNot node when end is
encountered.
"""
let value: _PropNode
let if_body: Array[_Part] box
new box create(value': _PropNode, if_body': Array[_Part] box) => value = value' if_body = if_body'
class _IfNot let value: _PropNode let body: Array[_Part] box let else_body: (Array[_Part] box | None)
new box create( value': _PropNode, body': Array[_Part] box, else_body': (Array[_Part] box | None) = None ) => value = value' body = body' else_body = else_body'
class _Loop let target: String let source: _PropNode let body: Array[_Part] box
new box create( target': String, source': _PropNode, body': Array[_Part] box ) => target = target' source = source' body = body'
class _Block let name: String let body: Array[_Part] box
new box create(name': String, body': Array[_Part] box) => name = name' body = body'
type _Part is ( (_Literal, String) | _Pipe box | _PropNode | _If box | _IfNot box | _Loop box | _Block box )
class box TemplateValue """ A value that can be used in a template. Either a single value or a sequence of values.
When used with HTMLTemplate, values are automatically escaped based on
their HTML context. To bypass escaping for trusted content, use the
unescaped constructor instead of create.
"""
let _data: (String | Seq[TemplateValue] box)
let _properties: Map[String, TemplateValue] box
let _renderable: RenderableValue
new box create( value: (String | Seq[TemplateValue] box), properties: Map[String, TemplateValue] box = Map[String, TemplateValue] ) => _data = value _properties = properties _renderable = _HTMLEscapingRenderer
new box unescaped(
value: (String | Seq[TemplateValue] box),
properties: Map[String, TemplateValue] box = Map[String, TemplateValue]
) =>
"""
Create a value that bypasses HTML auto-escaping in HTMLTemplate.
The content is inserted as-is, without context-aware escaping. Use this
only for content you trust (e.g., pre-sanitized HTML fragments).
Has no effect when used with plain `Template`, which does not escape.
Note: the unescaped annotation applies only to direct variable
substitution (`{{ name }}`). When a value passes through a filter pipe
(`{{ name | upper }}`), the result is always escaped — filters could
introduce unsafe content.
"""
_data = value
_properties = properties
_renderable = _NoEscapeRenderer
fun apply(name: String): TemplateValue ? => _properties(name)?
fun string(): String ? => _data as String
fun renderable(): RenderableValue =>
"""
The rendering strategy for this value. HTMLTemplate calls this to
determine how to escape the value based on HTML context.
"""
_renderable
fun values(): Iterator[TemplateValue] => match _data | let seq: Seq[TemplateValue] box => seq.values() else Array[TemplateValue].values() end
fun box is_truthy(): Bool => match \exhaustive\ _data | let : String => true | let seq: Seq[TemplateValue] box => seq.values().has_next() end
class TemplateValues
"""
A scoped key-value store for template rendering. Values are stored as
TemplateValue entries and looked up by name. Lookups check the local
scope first, then walk up the parent chain.
Use scope() to create a writable child that inherits all values from
this set without copying. Use update() and unescaped() to add values.
"""
let _parent: (TemplateValues box | None)
let _values: Map[String, TemplateValue]
new _create( parent: TemplateValues box, values: Map[String, TemplateValue] ) => _parent = parent _values = values
new create() => _parent = None _values = Map[String, TemplateValue]
fun box apply(name: String): TemplateValue ? => try _values(name)? else match \exhaustive\ _parent | let parent: TemplateValues box => parent(name)? | None => error end end
fun box _lookup(prop: _PropNode): TemplateValue ? => var value = this(prop.name)? for name in prop.props.values() do value = value(name)? end
value
fun ref update(name: String, value: (String | TemplateValue)) =>
"""
Store a value under the given name. String values are wrapped in a
TemplateValue automatically. This is also the target of Pony's
sugar for values("key") = "value".
"""
_values(name) =
match \exhaustive\ value
| let string: String => TemplateValue(string)
| let template_value: TemplateValue => template_value
end
fun ref unescaped(name: String, value: String) =>
"""
Store a string value that bypasses HTML auto-escaping in HTMLTemplate.
See TemplateValue.unescaped for details. For structured values (with
properties or sequences), use TemplateValue.unescaped() directly and
pass the result to update().
"""
_values(name) = TemplateValue.unescaped(value)
fun box scope(): TemplateValues => """ Create an empty writable child scope backed by this value set as a read-only parent. Writes go to the child; lookups that miss in the child fall through to the parent. """ TemplateValues._create(this, Map[String, TemplateValue])
fun box _override(name: String, value: TemplateValue): TemplateValues => let values = Map[String, TemplateValue] values(name) = value TemplateValues._create(this, values)
class TemplateContext
"""
Configuration for template parsing. Provides named filters that can be
applied to values via {{ value | filter }}, and named partials that can
be inlined via {{ include "name" }} or used as base templates for
inheritance via {{ extends "name" }}.
Seven built-in filters are always available: upper, lower, trim,
capitalize, title, default, and replace. User-supplied filters
with the same name override the built-in.
"""
let filters: Map[String, AnyFilter] box
let partials: Map[String, String] box
new val create( filters': Map[String, AnyFilter] val = recover Map[String, AnyFilter] end * partials': Map[String val, String val] val = primitive _RawBlock type _BlockKind is (_RegularBlock | _CommentBlock | _RawBlock)
// A resolved filter argument: either a string literal or a property reference. type _ResolvedArg is (String | _PropNode)
class _Pipe """ A fully resolved pipe expression ready for rendering. The source — either a property reference or a string literal — is piped through each filter in order. Each filter has been validated at parse time for existence and correct arity. """ let source: (_PropNode | String) let filters: Array[(AnyFilter, Array[_ResolvedArg] box)] box
new box create( source': (_PropNode | String), filters': Array[(AnyFilter, Array[_ResolvedArg] box)] box ) => source = source' filters = filters'
class _If let value: _PropNode let body: Array[_Part] box let else_body: (Array[_Part] box | None)
new box create( value': _PropNode, body': Array[_Part] box, else_body': (Array[_Part] box | None) = None ) => value = value' body = body' else_body = else_body'
class box _IfElse
"""
Marker on the open-block stack indicating an if block that has transitioned
to its else branch. Stores the original condition and if-body so they can
be assembled into the final _If node when end is encountered.
"""
let value: _PropNode
let if_body: Array[_Part] box
new box create(value': _PropNode, if_body': Array[_Part] box) => value = value' if_body = if_body'
class box _IfNotElse
"""
Marker on the open-block stack indicating an ifnot block that has
transitioned to its else branch. Stores the original condition and if-body
so they can be assembled into the final _IfNot node when end is
encountered.
"""
let value: _PropNode
let if_body: Array[_Part] box
new box create(value': _PropNode, if_body': Array[_Part] box) => value = value' if_body = if_body'
class _IfNot let value: _PropNode let body: Array[_Part] box let else_body: (Array[_Part] box | None)
new box create( value': _PropNode, body': Array[_Part] box, else_body': (Array[_Part] box | None) = None ) => value = value' body = body' else_body = else_body'
class _Loop let target: String let source: _PropNode let body: Array[_Part] box
new box create( target': String, source': _PropNode, body': Array[_Part] box ) => target = target' source = source' body = body'
class _Block let name: String let body: Array[_Part] box
new box create(name': String, body': Array[_Part] box) => name = name' body = body'
type _Part is ( (_Literal, String) | _Pipe box | _PropNode | _If box | _IfNot box | _Loop box | _Block box )
class box TemplateValue """ A value that can be used in a template. Either a single value or a sequence of values.
When used with HTMLTemplate, values are automatically escaped based on
their HTML context. To bypass escaping for trusted content, use the
unescaped constructor instead of create.
"""
let _data: (String | Seq[TemplateValue] box)
let _properties: Map[String, TemplateValue] box
let _renderable: RenderableValue
new box create( value: (String | Seq[TemplateValue] box), properties: Map[String, TemplateValue] box = Map[String, TemplateValue] ) => _data = value _properties = properties _renderable = _HTMLEscapingRenderer
new box unescaped(
value: (String | Seq[TemplateValue] box),
properties: Map[String, TemplateValue] box = Map[String, TemplateValue]
) =>
"""
Create a value that bypasses HTML auto-escaping in HTMLTemplate.
The content is inserted as-is, without context-aware escaping. Use this
only for content you trust (e.g., pre-sanitized HTML fragments).
Has no effect when used with plain `Template`, which does not escape.
Note: the unescaped annotation applies only to direct variable
substitution (`{{ name }}`). When a value passes through a filter pipe
(`{{ name | upper }}`), the result is always escaped — filters could
introduce unsafe content.
"""
_data = value
_properties = properties
_renderable = _NoEscapeRenderer
fun apply(name: String): TemplateValue ? => _properties(name)?
fun string(): String ? => _data as String
fun renderable(): RenderableValue =>
"""
The rendering strategy for this value. HTMLTemplate calls this to
determine how to escape the value based on HTML context.
"""
_renderable
fun values(): Iterator[TemplateValue] => match _data | let seq: Seq[TemplateValue] box => seq.values() else Array[TemplateValue].values() end
fun box is_truthy(): Bool => match \exhaustive\ _data | let : String => true | let seq: Seq[TemplateValue] box => seq.values().has_next() end
class TemplateValues
"""
A scoped key-value store for template rendering. Values are stored as
TemplateValue entries and looked up by name. Lookups check the local
scope first, then walk up the parent chain.
Use scope() to create a writable child that inherits all values from
this set without copying. Use update() and unescaped() to add values.
"""
let _parent: (TemplateValues box | None)
let _values: Map[String, TemplateValue]
new _create( parent: TemplateValues box, values: Map[String, TemplateValue] ) => _parent = parent _values = values
new create() => _parent = None _values = Map[String, TemplateValue]
fun box apply(name: String): TemplateValue ? => try _values(name)? else match \exhaustive\ _parent | let parent: TemplateValues box => parent(name)? | None => error end end
fun box _lookup(prop: _PropNode): TemplateValue ? => var value = this(prop.name)? for name in prop.props.values() do value = value(name)? end
value
fun ref update(name: String, value: (String | TemplateValue)) =>
"""
Store a value under the given name. String values are wrapped in a
TemplateValue automatically. This is also the target of Pony's
sugar for values("key") = "value".
"""
_values(name) =
match \exhaustive\ value
| let string: String => TemplateValue(string)
| let template_value: TemplateValue => template_value
end
fun ref unescaped(name: String, value: String) =>
"""
Store a string value that bypasses HTML auto-escaping in HTMLTemplate.
See TemplateValue.unescaped for details. For structured values (with
properties or sequences), use TemplateValue.unescaped() directly and
pass the result to update().
"""
_values(name) = TemplateValue.unescaped(value)
fun box scope(): TemplateValues => """ Create an empty writable child scope backed by this value set as a read-only parent. Writes go to the child; lookups that miss in the child fall through to the parent. """ TemplateValues._create(this, Map[String, TemplateValue])
fun box _override(name: String, value: TemplateValue): TemplateValues => let values = Map[String, TemplateValue] values(name) = value TemplateValues._create(this, values)
class TemplateContext
"""
Configuration for template parsing. Provides named filters that can be
applied to values via {{ value | filter }}, and named partials that can
be inlined via {{ include "name" }} or used as base templates for
inheritance via {{ extends "name" }}.
Seven built-in filters are always available: upper, lower, trim,
capitalize, title, default, and replace. User-supplied filters
with the same name override the built-in.
"""
let filters: Map[String, AnyFilter] box
let partials: Map[String, String] box
new val create( filters': Map[String, AnyFilter] val = recover Map[String, AnyFilter] end, partials': Map[String, String] val = recover Map[String, String] end
Returns¶
- TemplateContext val^