Struct handlebars::BlockContext
source · pub struct BlockContext<'reg> { /* private fields */ }
Expand description
A data structure holds contextual data for current block scope.
Implementations§
source§impl<'reg> BlockContext<'reg>
impl<'reg> BlockContext<'reg>
sourcepub fn new() -> BlockContext<'reg>
pub fn new() -> BlockContext<'reg>
create a new BlockContext
with default data
Examples found in repository?
src/helpers/block_util.rs (line 7)
4 5 6 7 8 9 10 11 12 13 14 15 16 17
pub(crate) fn create_block<'reg: 'rc, 'rc>(
param: &'rc PathAndJson<'reg, 'rc>,
) -> BlockContext<'reg> {
let mut block = BlockContext::new();
if let Some(new_path) = param.context_path() {
*block.base_path_mut() = new_path.clone();
} else {
// use clone for now
block.set_base_value(param.value().clone());
}
block
}
More examples
src/render.rs (line 69)
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
pub fn new(root_template: Option<&'reg String>) -> RenderContext<'reg, 'rc> {
let inner = Rc::new(RenderContextInner {
partials: BTreeMap::new(),
partial_block_stack: VecDeque::new(),
partial_block_depth: 0,
local_helpers: BTreeMap::new(),
current_template: None,
root_template,
disable_escape: false,
indent_string: None,
});
let mut blocks = VecDeque::with_capacity(5);
blocks.push_front(BlockContext::new());
let modified_context = None;
RenderContext {
inner,
blocks,
modified_context,
}
}
pub(crate) fn new_for_block(&self) -> RenderContext<'reg, 'rc> {
let inner = self.inner.clone();
let mut blocks = VecDeque::with_capacity(2);
blocks.push_front(BlockContext::new());
let modified_context = self.modified_context.clone();
RenderContext {
inner,
blocks,
modified_context,
}
}
src/partial.rs (line 80)
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
pub fn expand_partial<'reg: 'rc, 'rc>(
d: &Decorator<'reg, 'rc>,
r: &'reg Registry<'reg>,
ctx: &'rc Context,
rc: &mut RenderContext<'reg, 'rc>,
out: &mut dyn Output,
) -> Result<(), RenderError> {
// try eval inline partials first
if let Some(t) = d.template() {
t.eval(r, ctx, rc)?;
}
let tname = d.name();
if rc.is_current_template(tname) {
return Err(RenderError::new("Cannot include self in >"));
}
let partial = find_partial(rc, r, d, tname)?;
if let Some(t) = partial {
// clone to avoid lifetime issue
// FIXME refactor this to avoid
let mut local_rc = rc.clone();
// if tname == PARTIAL_BLOCK
let is_partial_block = tname == PARTIAL_BLOCK;
// add partial block depth there are consecutive partial
// blocks in the stack.
if is_partial_block {
local_rc.inc_partial_block_depth();
} else {
// depth cannot be lower than 0, which is guaranted in the
// `dec_partial_block_depth` method
local_rc.dec_partial_block_depth();
}
let mut block_created = false;
// create context if param given
if let Some(base_path) = d.param(0).and_then(|p| p.context_path()) {
// path given, update base_path
let mut block_inner = BlockContext::new();
*block_inner.base_path_mut() = base_path.to_vec();
// because block is moved here, we need another bool variable to track
// its status for later cleanup
block_created = true;
// clear blocks to prevent block params from parent
// template to be leaked into partials
// see `test_partial_context_issue_495` for the case.
local_rc.clear_blocks();
local_rc.push_block(block_inner);
}
if !d.hash().is_empty() {
// hash given, update base_value
let hash_ctx = d
.hash()
.iter()
.map(|(k, v)| (*k, v.value()))
.collect::<HashMap<&str, &Json>>();
// create block if we didn't (no param provided for partial expression)
if !block_created {
let block_inner = if let Some(block) = local_rc.block() {
// reuse current block information, including base_path and
// base_value if any
block.clone()
} else {
BlockContext::new()
};
local_rc.clear_blocks();
local_rc.push_block(block_inner);
}
// evaluate context within current block, this includes block
// context provided by partial expression parameter
let merged_context = merge_json(
local_rc.evaluate2(ctx, &Path::current())?.as_json(),
&hash_ctx,
);
// update the base value, there must be a block for this so it's
// also safe to unwrap.
if let Some(block) = local_rc.block_mut() {
block.set_base_value(merged_context);
}
}
// @partial-block
if let Some(pb) = d.template() {
local_rc.push_partial_block(pb);
}
// indent
local_rc.set_indent_string(d.indent());
let result = t.render(r, ctx, &mut local_rc, out);
// cleanup
if block_created {
local_rc.pop_block();
}
if d.template().is_some() {
local_rc.pop_partial_block();
}
result
} else {
Ok(())
}
}
sourcepub fn set_local_var(&mut self, name: &str, value: Json)
pub fn set_local_var(&mut self, name: &str, value: Json)
set a local variable into current scope
Examples found in repository?
src/helpers/helper_each.rs (line 99)
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
fn call<'reg: 'rc, 'rc>(
&self,
h: &Helper<'reg, 'rc>,
r: &'reg Registry<'reg>,
ctx: &'rc Context,
rc: &mut RenderContext<'reg, 'rc>,
out: &mut dyn Output,
) -> HelperResult {
let value = h
.param(0)
.ok_or_else(|| RenderError::new("Param not found for helper \"each\""))?;
let template = h.template();
match template {
Some(t) => match *value.value() {
Json::Array(ref list)
if !list.is_empty() || (list.is_empty() && h.inverse().is_none()) =>
{
let block_context = create_block(value);
rc.push_block(block_context);
let len = list.len();
let array_path = value.context_path();
for (i, v) in list.iter().enumerate().take(len) {
if let Some(ref mut block) = rc.block_mut() {
let is_first = i == 0usize;
let is_last = i == len - 1;
let index = to_json(i);
block.set_local_var("first", to_json(is_first));
block.set_local_var("last", to_json(is_last));
block.set_local_var("index", index.clone());
update_block_context(block, array_path, i.to_string(), is_first, v);
set_block_param(block, h, array_path, &index, v)?;
}
t.render(r, ctx, rc, out)?;
}
rc.pop_block();
Ok(())
}
Json::Object(ref obj)
if !obj.is_empty() || (obj.is_empty() && h.inverse().is_none()) =>
{
let block_context = create_block(value);
rc.push_block(block_context);
let len = obj.len();
let obj_path = value.context_path();
for (i, (k, v)) in obj.iter().enumerate() {
if let Some(ref mut block) = rc.block_mut() {
let is_first = i == 0usize;
let is_last = i == len - 1;
let key = to_json(k);
block.set_local_var("first", to_json(is_first));
block.set_local_var("last", to_json(is_last));
block.set_local_var("key", key.clone());
update_block_context(block, obj_path, k.to_string(), is_first, v);
set_block_param(block, h, obj_path, &key, v)?;
}
t.render(r, ctx, rc, out)?;
}
rc.pop_block();
Ok(())
}
_ => {
if let Some(else_template) = h.inverse() {
else_template.render(r, ctx, rc, out)
} else if r.strict_mode() {
Err(RenderError::strict_error(value.relative_path()))
} else {
Ok(())
}
}
},
None => Ok(()),
}
}
sourcepub fn get_local_var(&self, name: &str) -> Option<&Json>
pub fn get_local_var(&self, name: &str) -> Option<&Json>
get a local variable from current scope
sourcepub fn base_path(&self) -> &Vec<String>
pub fn base_path(&self) -> &Vec<String>
borrow a reference to current scope’s base path all paths inside this block will be relative to this path
Examples found in repository?
src/context.rs (line 89)
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
fn parse_json_visitor<'a, 'reg>(
relative_path: &[PathSeg],
block_contexts: &'a VecDeque<BlockContext<'reg>>,
always_for_absolute_path: bool,
) -> ResolvedPath<'a> {
let mut path_context_depth: i64 = 0;
let mut with_block_param = None;
let mut from_root = false;
// peek relative_path for block param, @root and "../../"
for path_seg in relative_path {
match path_seg {
PathSeg::Named(the_path) => {
if let Some((holder, base_path)) = get_in_block_params(block_contexts, the_path) {
with_block_param = Some((holder, base_path));
}
break;
}
PathSeg::Ruled(the_rule) => match the_rule {
Rule::path_root => {
from_root = true;
break;
}
Rule::path_up => path_context_depth += 1,
_ => break,
},
}
}
let mut path_stack = Vec::with_capacity(relative_path.len() + 5);
match with_block_param {
Some((BlockParamHolder::Value(ref value), _)) => {
merge_json_path(&mut path_stack, &relative_path[1..]);
ResolvedPath::BlockParamValue(path_stack, value)
}
Some((BlockParamHolder::Path(ref paths), base_path)) => {
extend(&mut path_stack, base_path);
if !paths.is_empty() {
extend(&mut path_stack, paths);
}
merge_json_path(&mut path_stack, &relative_path[1..]);
ResolvedPath::AbsolutePath(path_stack)
}
None => {
if path_context_depth > 0 {
let blk = block_contexts
.get(path_context_depth as usize)
.or_else(|| block_contexts.front());
if let Some(base_value) = blk.and_then(|blk| blk.base_value()) {
merge_json_path(&mut path_stack, relative_path);
ResolvedPath::LocalValue(path_stack, base_value)
} else {
if let Some(base_path) = blk.map(|blk| blk.base_path()) {
extend(&mut path_stack, base_path);
}
merge_json_path(&mut path_stack, relative_path);
ResolvedPath::AbsolutePath(path_stack)
}
} else if from_root {
merge_json_path(&mut path_stack, relative_path);
ResolvedPath::AbsolutePath(path_stack)
} else if always_for_absolute_path {
if let Some(base_value) = block_contexts.front().and_then(|blk| blk.base_value()) {
merge_json_path(&mut path_stack, relative_path);
ResolvedPath::LocalValue(path_stack, base_value)
} else {
if let Some(base_path) = block_contexts.front().map(|blk| blk.base_path()) {
extend(&mut path_stack, base_path);
}
merge_json_path(&mut path_stack, relative_path);
ResolvedPath::AbsolutePath(path_stack)
}
} else {
merge_json_path(&mut path_stack, relative_path);
ResolvedPath::RelativePath(path_stack)
}
}
}
}
fn get_data<'a>(d: Option<&'a Json>, p: &str) -> Result<Option<&'a Json>, RenderError> {
let result = match d {
Some(&Json::Array(ref l)) => p.parse::<usize>().map(|idx_u| l.get(idx_u))?,
Some(&Json::Object(ref m)) => m.get(p),
Some(_) => None,
None => None,
};
Ok(result)
}
fn get_in_block_params<'a, 'reg>(
block_contexts: &'a VecDeque<BlockContext<'reg>>,
p: &str,
) -> Option<(&'a BlockParamHolder, &'a Vec<String>)> {
for bc in block_contexts {
let v = bc.get_block_param(p);
if v.is_some() {
return v.map(|v| (v, bc.base_path()));
}
}
None
}
sourcepub fn base_path_mut(&mut self) -> &mut Vec<String>
pub fn base_path_mut(&mut self) -> &mut Vec<String>
borrow a mutable reference to the base path
Examples found in repository?
src/helpers/block_util.rs (line 10)
4 5 6 7 8 9 10 11 12 13 14 15 16 17
pub(crate) fn create_block<'reg: 'rc, 'rc>(
param: &'rc PathAndJson<'reg, 'rc>,
) -> BlockContext<'reg> {
let mut block = BlockContext::new();
if let Some(new_path) = param.context_path() {
*block.base_path_mut() = new_path.clone();
} else {
// use clone for now
block.set_base_value(param.value().clone());
}
block
}
More examples
src/helpers/helper_each.rs (line 23)
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
fn update_block_context<'reg>(
block: &mut BlockContext<'reg>,
base_path: Option<&Vec<String>>,
relative_path: String,
is_first: bool,
value: &Json,
) {
if let Some(p) = base_path {
if is_first {
*block.base_path_mut() = copy_on_push_vec(p, relative_path);
} else if let Some(ptr) = block.base_path_mut().last_mut() {
*ptr = relative_path;
}
} else {
block.set_base_value(value.clone());
}
}
src/partial.rs (line 81)
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
pub fn expand_partial<'reg: 'rc, 'rc>(
d: &Decorator<'reg, 'rc>,
r: &'reg Registry<'reg>,
ctx: &'rc Context,
rc: &mut RenderContext<'reg, 'rc>,
out: &mut dyn Output,
) -> Result<(), RenderError> {
// try eval inline partials first
if let Some(t) = d.template() {
t.eval(r, ctx, rc)?;
}
let tname = d.name();
if rc.is_current_template(tname) {
return Err(RenderError::new("Cannot include self in >"));
}
let partial = find_partial(rc, r, d, tname)?;
if let Some(t) = partial {
// clone to avoid lifetime issue
// FIXME refactor this to avoid
let mut local_rc = rc.clone();
// if tname == PARTIAL_BLOCK
let is_partial_block = tname == PARTIAL_BLOCK;
// add partial block depth there are consecutive partial
// blocks in the stack.
if is_partial_block {
local_rc.inc_partial_block_depth();
} else {
// depth cannot be lower than 0, which is guaranted in the
// `dec_partial_block_depth` method
local_rc.dec_partial_block_depth();
}
let mut block_created = false;
// create context if param given
if let Some(base_path) = d.param(0).and_then(|p| p.context_path()) {
// path given, update base_path
let mut block_inner = BlockContext::new();
*block_inner.base_path_mut() = base_path.to_vec();
// because block is moved here, we need another bool variable to track
// its status for later cleanup
block_created = true;
// clear blocks to prevent block params from parent
// template to be leaked into partials
// see `test_partial_context_issue_495` for the case.
local_rc.clear_blocks();
local_rc.push_block(block_inner);
}
if !d.hash().is_empty() {
// hash given, update base_value
let hash_ctx = d
.hash()
.iter()
.map(|(k, v)| (*k, v.value()))
.collect::<HashMap<&str, &Json>>();
// create block if we didn't (no param provided for partial expression)
if !block_created {
let block_inner = if let Some(block) = local_rc.block() {
// reuse current block information, including base_path and
// base_value if any
block.clone()
} else {
BlockContext::new()
};
local_rc.clear_blocks();
local_rc.push_block(block_inner);
}
// evaluate context within current block, this includes block
// context provided by partial expression parameter
let merged_context = merge_json(
local_rc.evaluate2(ctx, &Path::current())?.as_json(),
&hash_ctx,
);
// update the base value, there must be a block for this so it's
// also safe to unwrap.
if let Some(block) = local_rc.block_mut() {
block.set_base_value(merged_context);
}
}
// @partial-block
if let Some(pb) = d.template() {
local_rc.push_partial_block(pb);
}
// indent
local_rc.set_indent_string(d.indent());
let result = t.render(r, ctx, &mut local_rc, out);
// cleanup
if block_created {
local_rc.pop_block();
}
if d.template().is_some() {
local_rc.pop_partial_block();
}
result
} else {
Ok(())
}
}
sourcepub fn base_value(&self) -> Option<&Json>
pub fn base_value(&self) -> Option<&Json>
borrow the base value
Examples found in repository?
src/context.rs (line 85)
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
fn parse_json_visitor<'a, 'reg>(
relative_path: &[PathSeg],
block_contexts: &'a VecDeque<BlockContext<'reg>>,
always_for_absolute_path: bool,
) -> ResolvedPath<'a> {
let mut path_context_depth: i64 = 0;
let mut with_block_param = None;
let mut from_root = false;
// peek relative_path for block param, @root and "../../"
for path_seg in relative_path {
match path_seg {
PathSeg::Named(the_path) => {
if let Some((holder, base_path)) = get_in_block_params(block_contexts, the_path) {
with_block_param = Some((holder, base_path));
}
break;
}
PathSeg::Ruled(the_rule) => match the_rule {
Rule::path_root => {
from_root = true;
break;
}
Rule::path_up => path_context_depth += 1,
_ => break,
},
}
}
let mut path_stack = Vec::with_capacity(relative_path.len() + 5);
match with_block_param {
Some((BlockParamHolder::Value(ref value), _)) => {
merge_json_path(&mut path_stack, &relative_path[1..]);
ResolvedPath::BlockParamValue(path_stack, value)
}
Some((BlockParamHolder::Path(ref paths), base_path)) => {
extend(&mut path_stack, base_path);
if !paths.is_empty() {
extend(&mut path_stack, paths);
}
merge_json_path(&mut path_stack, &relative_path[1..]);
ResolvedPath::AbsolutePath(path_stack)
}
None => {
if path_context_depth > 0 {
let blk = block_contexts
.get(path_context_depth as usize)
.or_else(|| block_contexts.front());
if let Some(base_value) = blk.and_then(|blk| blk.base_value()) {
merge_json_path(&mut path_stack, relative_path);
ResolvedPath::LocalValue(path_stack, base_value)
} else {
if let Some(base_path) = blk.map(|blk| blk.base_path()) {
extend(&mut path_stack, base_path);
}
merge_json_path(&mut path_stack, relative_path);
ResolvedPath::AbsolutePath(path_stack)
}
} else if from_root {
merge_json_path(&mut path_stack, relative_path);
ResolvedPath::AbsolutePath(path_stack)
} else if always_for_absolute_path {
if let Some(base_value) = block_contexts.front().and_then(|blk| blk.base_value()) {
merge_json_path(&mut path_stack, relative_path);
ResolvedPath::LocalValue(path_stack, base_value)
} else {
if let Some(base_path) = block_contexts.front().map(|blk| blk.base_path()) {
extend(&mut path_stack, base_path);
}
merge_json_path(&mut path_stack, relative_path);
ResolvedPath::AbsolutePath(path_stack)
}
} else {
merge_json_path(&mut path_stack, relative_path);
ResolvedPath::RelativePath(path_stack)
}
}
}
}
sourcepub fn set_base_value(&mut self, value: Json)
pub fn set_base_value(&mut self, value: Json)
set the base value
Examples found in repository?
src/helpers/block_util.rs (line 13)
4 5 6 7 8 9 10 11 12 13 14 15 16 17
pub(crate) fn create_block<'reg: 'rc, 'rc>(
param: &'rc PathAndJson<'reg, 'rc>,
) -> BlockContext<'reg> {
let mut block = BlockContext::new();
if let Some(new_path) = param.context_path() {
*block.base_path_mut() = new_path.clone();
} else {
// use clone for now
block.set_base_value(param.value().clone());
}
block
}
More examples
src/helpers/helper_each.rs (line 28)
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
fn update_block_context<'reg>(
block: &mut BlockContext<'reg>,
base_path: Option<&Vec<String>>,
relative_path: String,
is_first: bool,
value: &Json,
) {
if let Some(p) = base_path {
if is_first {
*block.base_path_mut() = copy_on_push_vec(p, relative_path);
} else if let Some(ptr) = block.base_path_mut().last_mut() {
*ptr = relative_path;
}
} else {
block.set_base_value(value.clone());
}
}
src/partial.rs (line 125)
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
pub fn expand_partial<'reg: 'rc, 'rc>(
d: &Decorator<'reg, 'rc>,
r: &'reg Registry<'reg>,
ctx: &'rc Context,
rc: &mut RenderContext<'reg, 'rc>,
out: &mut dyn Output,
) -> Result<(), RenderError> {
// try eval inline partials first
if let Some(t) = d.template() {
t.eval(r, ctx, rc)?;
}
let tname = d.name();
if rc.is_current_template(tname) {
return Err(RenderError::new("Cannot include self in >"));
}
let partial = find_partial(rc, r, d, tname)?;
if let Some(t) = partial {
// clone to avoid lifetime issue
// FIXME refactor this to avoid
let mut local_rc = rc.clone();
// if tname == PARTIAL_BLOCK
let is_partial_block = tname == PARTIAL_BLOCK;
// add partial block depth there are consecutive partial
// blocks in the stack.
if is_partial_block {
local_rc.inc_partial_block_depth();
} else {
// depth cannot be lower than 0, which is guaranted in the
// `dec_partial_block_depth` method
local_rc.dec_partial_block_depth();
}
let mut block_created = false;
// create context if param given
if let Some(base_path) = d.param(0).and_then(|p| p.context_path()) {
// path given, update base_path
let mut block_inner = BlockContext::new();
*block_inner.base_path_mut() = base_path.to_vec();
// because block is moved here, we need another bool variable to track
// its status for later cleanup
block_created = true;
// clear blocks to prevent block params from parent
// template to be leaked into partials
// see `test_partial_context_issue_495` for the case.
local_rc.clear_blocks();
local_rc.push_block(block_inner);
}
if !d.hash().is_empty() {
// hash given, update base_value
let hash_ctx = d
.hash()
.iter()
.map(|(k, v)| (*k, v.value()))
.collect::<HashMap<&str, &Json>>();
// create block if we didn't (no param provided for partial expression)
if !block_created {
let block_inner = if let Some(block) = local_rc.block() {
// reuse current block information, including base_path and
// base_value if any
block.clone()
} else {
BlockContext::new()
};
local_rc.clear_blocks();
local_rc.push_block(block_inner);
}
// evaluate context within current block, this includes block
// context provided by partial expression parameter
let merged_context = merge_json(
local_rc.evaluate2(ctx, &Path::current())?.as_json(),
&hash_ctx,
);
// update the base value, there must be a block for this so it's
// also safe to unwrap.
if let Some(block) = local_rc.block_mut() {
block.set_base_value(merged_context);
}
}
// @partial-block
if let Some(pb) = d.template() {
local_rc.push_partial_block(pb);
}
// indent
local_rc.set_indent_string(d.indent());
let result = t.render(r, ctx, &mut local_rc, out);
// cleanup
if block_created {
local_rc.pop_block();
}
if d.template().is_some() {
local_rc.pop_partial_block();
}
result
} else {
Ok(())
}
}
sourcepub fn get_block_param(
&self,
block_param_name: &str
) -> Option<&BlockParamHolder>
pub fn get_block_param(
&self,
block_param_name: &str
) -> Option<&BlockParamHolder>
Get a block parameter from this block. Block parameters needed to be supported by the block helper. The typical syntax for block parameter is:
{{#myblock param1 as |block_param1|}}
...
{{/myblock}}
Examples found in repository?
src/context.rs (line 132)
127 128 129 130 131 132 133 134 135 136 137 138 139
fn get_in_block_params<'a, 'reg>(
block_contexts: &'a VecDeque<BlockContext<'reg>>,
p: &str,
) -> Option<(&'a BlockParamHolder, &'a Vec<String>)> {
for bc in block_contexts {
let v = bc.get_block_param(p);
if v.is_some() {
return v.map(|v| (v, bc.base_path()));
}
}
None
}
sourcepub fn set_block_params(&mut self, block_params: BlockParams<'reg>)
pub fn set_block_params(&mut self, block_params: BlockParams<'reg>)
Set a block parameter into this block.
Examples found in repository?
src/helpers/helper_each.rs (line 47)
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
fn set_block_param<'reg: 'rc, 'rc>(
block: &mut BlockContext<'reg>,
h: &Helper<'reg, 'rc>,
base_path: Option<&Vec<String>>,
k: &Json,
v: &Json,
) -> Result<(), RenderError> {
if let Some(bp_val) = h.block_param() {
let mut params = BlockParams::new();
if base_path.is_some() {
params.add_path(bp_val, Vec::with_capacity(0))?;
} else {
params.add_value(bp_val, v.clone())?;
}
block.set_block_params(params);
} else if let Some((bp_val, bp_key)) = h.block_param_pair() {
let mut params = BlockParams::new();
if base_path.is_some() {
params.add_path(bp_val, Vec::with_capacity(0))?;
} else {
params.add_value(bp_val, v.clone())?;
}
params.add_value(bp_key, k.clone())?;
block.set_block_params(params);
}
Ok(())
}
More examples
src/helpers/helper_with.rs (line 38)
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
fn call<'reg: 'rc, 'rc>(
&self,
h: &Helper<'reg, 'rc>,
r: &'reg Registry<'reg>,
ctx: &'rc Context,
rc: &mut RenderContext<'reg, 'rc>,
out: &mut dyn Output,
) -> HelperResult {
let param = h
.param(0)
.ok_or_else(|| RenderError::new("Param not found for helper \"with\""))?;
if param.value().is_truthy(false) {
let mut block = create_block(param);
if let Some(block_param) = h.block_param() {
let mut params = BlockParams::new();
if param.context_path().is_some() {
params.add_path(block_param, Vec::with_capacity(0))?;
} else {
params.add_value(block_param, param.value().clone())?;
}
block.set_block_params(params);
}
rc.push_block(block);
if let Some(t) = h.template() {
t.render(r, ctx, rc, out)?;
};
rc.pop_block();
Ok(())
} else if let Some(t) = h.inverse() {
t.render(r, ctx, rc, out)
} else if r.strict_mode() {
Err(RenderError::strict_error(param.relative_path()))
} else {
Ok(())
}
}
Trait Implementations§
source§impl<'reg> Clone for BlockContext<'reg>
impl<'reg> Clone for BlockContext<'reg>
source§fn clone(&self) -> BlockContext<'reg>
fn clone(&self) -> BlockContext<'reg>
Returns a copy of the value. Read more
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source
. Read moresource§impl<'reg> Debug for BlockContext<'reg>
impl<'reg> Debug for BlockContext<'reg>
source§impl<'reg> Default for BlockContext<'reg>
impl<'reg> Default for BlockContext<'reg>
source§fn default() -> BlockContext<'reg>
fn default() -> BlockContext<'reg>
Returns the “default value” for a type. Read more