1 use super::block_util
::create_block
;
2 use crate::block
::BlockParams
;
3 use crate::context
::Context
;
4 use crate::error
::RenderError
;
5 use crate::helpers
::{HelperDef, HelperResult}
;
6 use crate::json
::value
::JsonTruthy
;
7 use crate::output
::Output
;
8 use crate::registry
::Registry
;
9 use crate::render
::{Helper, RenderContext, Renderable}
;
11 #[derive(Clone, Copy)]
12 pub struct WithHelper
;
14 impl HelperDef
for WithHelper
{
15 fn call
<'reg
: 'rc
, 'rc
>(
17 h
: &Helper
<'reg
, 'rc
>,
18 r
: &'reg Registry
<'reg
>,
20 rc
: &mut RenderContext
<'reg
, 'rc
>,
25 .ok_or_else(|| RenderError
::new("Param not found for helper \"with\""))?
;
27 let not_empty
= param
.value().is_truthy(false);
28 let template
= if not_empty { h.template() }
else { h.inverse() }
;
31 let mut block
= create_block(¶m
)?
;
33 if let Some(block_param
) = h
.block_param() {
34 let mut params
= BlockParams
::new();
35 if param
.context_path().is_some() {
36 params
.add_path(block_param
, Vec
::with_capacity(0))?
;
38 params
.add_value(block_param
, param
.value().clone())?
;
41 block
.set_block_params(params
);
47 let result
= match template
{
48 Some(t
) => t
.render(r
, ctx
, rc
, out
),
59 pub static WITH_HELPER
: WithHelper
= WithHelper
;
63 use crate::json
::value
::to_json
;
64 use crate::registry
::Registry
;
83 city
: "Beijing".to_string(),
84 country
: "China".to_string(),
88 name
: "Ning Sun".to_string(),
91 titles
: vec
!["programmer".to_string(), "cartographier".to_string()],
94 let mut handlebars
= Registry
::new();
96 .register_template_string("t0", "{{#with addr}}{{city}}{{/with}}")
99 .register_template_string("t1", "{{#with notfound}}hello{{else}}world{{/with}}")
102 .register_template_string("t2", "{{#with addr/country}}{{this}}{{/with}}")
105 let r0
= handlebars
.render("t0", &person
);
106 assert_eq
!(r0
.ok().unwrap(), "Beijing".to_string());
108 let r1
= handlebars
.render("t1", &person
);
109 assert_eq
!(r1
.ok().unwrap(), "world".to_string());
111 let r2
= handlebars
.render("t2", &person
);
112 assert_eq
!(r2
.ok().unwrap(), "China".to_string());
116 fn test_with_block_param() {
118 city
: "Beijing".to_string(),
119 country
: "China".to_string(),
122 let person
= Person
{
123 name
: "Ning Sun".to_string(),
126 titles
: vec
!["programmer".to_string(), "cartographier".to_string()],
129 let mut handlebars
= Registry
::new();
131 .register_template_string("t0", "{{#with addr as |a|}}{{a.city}}{{/with}}")
134 .register_template_string("t1", "{{#with notfound as |c|}}hello{{else}}world{{/with}}")
137 .register_template_string("t2", "{{#with addr/country as |t|}}{{t}}{{/with}}")
140 let r0
= handlebars
.render("t0", &person
);
141 assert_eq
!(r0
.ok().unwrap(), "Beijing".to_string());
143 let r1
= handlebars
.render("t1", &person
);
144 assert_eq
!(r1
.ok().unwrap(), "world".to_string());
146 let r2
= handlebars
.render("t2", &person
);
147 assert_eq
!(r2
.ok().unwrap(), "China".to_string());
151 fn test_with_in_each() {
153 city
: "Beijing".to_string(),
154 country
: "China".to_string(),
157 let person
= Person
{
158 name
: "Ning Sun".to_string(),
161 titles
: vec
!["programmer".to_string(), "cartographier".to_string()],
164 let addr2
= Address
{
165 city
: "Beijing".to_string(),
166 country
: "China".to_string(),
169 let person2
= Person
{
170 name
: "Ning Sun".to_string(),
173 titles
: vec
!["programmer".to_string(), "cartographier".to_string()],
176 let people
= vec
![person
, person2
];
178 let mut handlebars
= Registry
::new();
180 .register_template_string(
182 "{{#each this}}{{#with addr}}{{city}}{{/with}}{{/each}}"
186 .register_template_string(
188 "{{#each this}}{{#with addr}}{{../age}}{{/with}}{{/each}}"
192 .register_template_string(
194 "{{#each this}}{{#with addr}}{{@../index}}{{/with}}{{/each}}"
198 let r0
= handlebars
.render("t0", &people
);
199 assert_eq
!(r0
.ok().unwrap(), "BeijingBeijing".to_string());
201 let r1
= handlebars
.render("t1", &people
);
202 assert_eq
!(r1
.ok().unwrap(), "2727".to_string());
204 let r2
= handlebars
.render("t2", &people
);
205 assert_eq
!(r2
.ok().unwrap(), "01".to_string());
210 let mut handlebars
= Registry
::new();
212 .register_template_string("t0", "{{#with a}}{{#with b}}{{../../d}}{{/with}}{{/with}}")
214 let data
= btreemap
! {
215 "a".to_string() => to_json(&btreemap
! {
216 "b".to_string() => vec
![btreemap
!{"c".to_string() => vec![1]}
]
218 "d".to_string() => to_json(1)
221 let r0
= handlebars
.render("t0", &data
);
222 assert_eq
!(r0
.ok().unwrap(), "1".to_string());
226 fn test_else_context() {
227 let reg
= Registry
::new();
228 let template
= "{{#with list}}A{{else}}{{foo}}{{/with}}";
229 let input
= json
!({"list": [], "foo": "bar"}
);
230 let rendered
= reg
.render_template(template
, &input
).unwrap();
231 assert_eq
!("bar", rendered
);
235 fn test_derived_value() {
236 let hb
= Registry
::new();
237 let data
= json
!({"a": {"b": {"c": "d"}
}});
238 let template
= "{{#with (lookup a.b \"c\")}}{{this}}{{/with}}";
239 assert_eq
!("d", hb
.render_template(template
, &data
).unwrap());
243 fn test_nested_derived_value() {
244 let hb
= Registry
::new();
245 let data
= json
!({"a": {"b": {"c": "d"}
}});
246 let template
= "{{#with (lookup a \"b\")}}{{#with this}}{{c}}{{/with}}{{/with}}";
247 assert_eq
!("d", hb
.render_template(template
, &data
).unwrap());