Skip to content

Commit

Permalink
Merge pull request #655 from cmrschwarz/set_block_parameter
Browse files Browse the repository at this point in the history
Allow users to set single block params.
  • Loading branch information
sunng87 authored Jul 2, 2024
2 parents 3504412 + 12b2f56 commit 57454fc
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 2 deletions.
65 changes: 65 additions & 0 deletions examples/block_helper_macro_let.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use handlebars::{
BlockParamHolder, Context, Handlebars, Helper, Output, RenderContext, RenderError,
RenderErrorReason,
};
use serde_json::{json, Value};

// a custom block helper to bind a variable name to a value
pub fn helper_let<'reg, 'rc>(
h: &Helper<'rc>,
_r: &'reg Handlebars<'reg>,
_ctx: &'rc Context,
rc: &mut RenderContext<'reg, 'rc>,
_out: &mut dyn Output,
) -> Result<(), RenderError> {
let name_param = h
.param(0)
.ok_or_else(|| RenderErrorReason::ParamNotFoundForIndex("let", 0))?;

let Some(Value::String(name_constant)) = name_param.try_get_constant_value() else {
return Err(RenderErrorReason::ParamTypeMismatchForName(
"let",
"0".to_string(),
"constant string".to_string(),
)
.into());
};

let value = h
.param(1)
.as_ref()
.map(|v| v.value().to_owned())
.ok_or_else(|| RenderErrorReason::ParamNotFoundForIndex("let", 2))?;

let block = rc.block_mut().unwrap();

block.set_block_param(name_constant, BlockParamHolder::Value(value));

Ok(())
}

fn main() -> Result<(), RenderError> {
// create the handlebars registry
let mut handlebars = Handlebars::new();

handlebars.register_helper("let", Box::new(helper_let));

let input = r#"
{{#if foo}}
{{let "mixin_classes" "foo-bar baz"}}
{{else}}
{{let "mixin_classes" "quux"}}
{{/if}}
<div class="content-main {{mixin_classes}}">
<p> content </p>
</div>
"#;

println!(
"{}",
handlebars.render_template(input, &json!({"foo": true}))?
);

Ok(())
}
7 changes: 6 additions & 1 deletion src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,13 @@ impl<'rc> BlockContext<'rc> {
self.block_params.get(block_param_name)
}

/// Set a block parameter into this block.
/// Reassign the block parameters for this block.
pub fn set_block_params(&mut self, block_params: BlockParams<'rc>) {
self.block_params = block_params;
}

/// Set a block parameter into this block.
pub fn set_block_param(&mut self, key: &'rc str, value: BlockParamHolder) {
self.block_params.data.insert(key, value);
}
}
8 changes: 8 additions & 0 deletions src/json/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ impl<'rc> PathAndJson<'rc> {
self.value.as_json()
}

/// Returns the value, if it is a constant. Otherwise returns None.
pub fn try_get_constant_value(&self) -> Option<&'rc Json> {
match &self.value {
ScopedJson::Constant(value) => Some(*value),
ScopedJson::Context(_, _) | ScopedJson::Derived(_) | ScopedJson::Missing => None,
}
}

/// Test if value is missing
pub fn is_value_missing(&self) -> bool {
self.value.is_missing()
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ extern crate serde_derive;
#[macro_use]
extern crate serde_json;

pub use self::block::{BlockContext, BlockParams};
pub use self::block::{BlockContext, BlockParamHolder, BlockParams};
pub use self::context::Context;
pub use self::decorators::DecoratorDef;
pub use self::error::{RenderError, RenderErrorReason, TemplateError, TemplateErrorReason};
Expand Down

0 comments on commit 57454fc

Please sign in to comment.