Here is some information about the technologies used in my application:
- Microsoft Visual Studio Enterprise 2022 (64-bit) - Current
- Stubble.Core version 1.10.8 ( library used to apply Mustache "logic-less templates" to json input data )
- .NET 6.0
Here is the snippet of the C# code that invokes Stubble API:
var objData = (JObject)JsonConvert.DeserializeObject(jsonData);
var stubble = new StubbleBuilder().Build();
string body = stubble.Render(template.TemplateBody, objData);
In our C# code, we have a string-based variable called template.TemplateBody which contains the following Mustache-based Stubble template:
{{#should_render}} If the relevant value in the custom_parameters_json
is true then this should be shown! {{/should_render}}
List seems to work as expected {{#my_list}} item: {{.}} {{/my_list}}
{{#truthy_value}} Truthy values should also work {{/truthy_value}}
{{#some_string}} String should be rendered if it is not null {{.}}
{{/some_string}}
Here is a generalized format of the JSON-based input test data:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"should_render": { "type": "boolean" },
"my_list": { "type": "array" },
"truthy_value": { "type": "integer" },
"some_string": { "type": "string" }
}
}
In our C# code, we also have a string-based variable called jsonData:
{
"should_render":true,
"my_list": ["a","b","c"],
"truthy_value":1,
"some_string":"My String"
}
Ultimately, jsonData will be deserialized into a C# object, stored in a variable called objData:
{
"should_render": true,
"my_list": ["a", "b", "c"],
"truthy_value": 1,
"some_string": "My String"
}
After applying the Stubble template to the JSON object data, it renders the following output:
\nList seems to work as expected\nitem: a\nitem: b\nitem: c\n\n\n
In the input JSON test data, should_render is set to true:
"should_render": true
Therefore, I am asking:
- Why did the Stubble API fail to render the statement "If the relevant value in the custom_parameters_json is true then this should be shown!" when
should_renderwas set to true?
{{#should_render}} If the relevant value in the custom_parameters_json is true then this should be shown! {{/should_render}}
- Why did the Stubble API fail to render the statement "Truthy values should also work" when
truthy_valuewas set to 1?
{{#truthy_value}} Truthy values should also work {{/truthy_value}}
- Why did the Stubble API fail to render the statement "String should be rendered if it is not null {{.}}" when
some_stringwas populated?
{{#some_string}} String should be rendered if it is not null {{.}} {{/some_string}}
Could someone please explain what modifications might be needed to get the following rendered output?
If the relevant value in the custom_parameters_json is true then this should be shown!
List seems to work as expected item: a item: b item: c
Truthy values should also work
String should be rendered if it is not null My String
1 Answer 1
All:
Mistral-Medium gave me the following answer:
The issue you're experiencing is related to how Stubble handles the data context when rendering templates. The problem stems from the fact that you're using JObject from Newtonsoft.Json as your data model, which doesn't play perfectly with Stubble's default behavior.
Here's what's happening and how to fix it:
Root Causes:
JObject vs Dictionary: Stubble works best with
Dictionary<string, object>or POCOs (Plain Old CLR Objects). When you deserialize toJObject, Stubble might not properly traverse the object graph.Truthy values: Stubble has specific rules about what it considers "truthy" for boolean checks. Numbers (like your
truthy_value: 1) might not be treated as truthy by default.String rendering: The
.in{{.}}refers to the current context, which might not work as expected withJObject.
Solutions:
- Convert JObject to Dictionary:
csharp
var objData = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonData);
- Or create a proper POCO:
csharp
public class TemplateData
{
public bool ShouldRender { get; set; }
public List<string> MyList { get; set; }
public int TruthyValue { get; set; }
public string SomeString { get; set; }
}
// Then deserialize:
var objData = JsonConvert.DeserializeObject<TemplateData>(jsonData);
- For your specific template, here's how to modify your code:
csharp
// Option 1: Using Dictionary
var objData = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonData);
var stubble = new StubbleBuilder().Build();
string body = stubble.Render(template.TemplateBody, objData);
// Option 2: Using POCO (recommended)
var objData = JsonConvert.DeserializeObject<TemplateData>(jsonData);
var stubble = new StubbleBuilder().Build();
string body = stubble.Render(template.TemplateBody, objData);
Expected Output:
With either solution, you should now get:
livecodeserver
If the relevant value in the custom_parameters_json is true then this should be shown!
List seems to work as expected
item: a
item: b
item: c
Truthy values should also work
String should be rendered if it is not null My String
Additional Notes:
For the
truthy_valueto work, you might need to ensure Stubble treats non-zero numbers as truthy. This is usually the default behavior, but if it's not working, you might need to configure Stubble differently.The
{{.}}syntax works when you're in a section (like#my_list) to refer to the current item. For yoursome_stringcase, you should just use{{some_string}}instead of the section syntax unless you specifically need the section behavior.If you must use
JObject, you could try:
csharp
var objData = JObject.Parse(jsonData);
var stubble = new StubbleBuilder()
.Configure(settings => settings.SetValueDelegate = (obj, propertyName) =>
{
if (obj is JObject jObj && jObj.TryGetValue(propertyName, out var value))
{
return value.ToString();
}
return null;
})
.Build();