Skip to content

Trigger “default” filter when value would result in empty output after ToStringValue() #778

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

JanRomero
Copy link

@JanRomero JanRomero commented Apr 9, 2025

I have some model items that go like this, so they result in their value when they’re tagged without specifying a property:

public class MyModel
{
    public string Value = "";
    public string Description = "Something something";
    public override string ToString() => this.Value;
}

This is to make template authors' lives easier and templates easier to read.

In this configuration the default filter will see that the object is present and not display the default value, even though the object will later be rendered as an empty string.

var template = fluidParser.Parse("{{ InterestingItem | default: '—' }}");

var dict = new Dictionary<string, object>() { ["InterestingItem"] = new MyModel() };

var html = template.Render(new TemplateContext(dict)); // html is "", but I would expect "—"

This PR adds a check for the object's actual string value, so the default filter will do its thing.

Cheers :)

@sebastienros
Copy link
Owner

I am wondering if the issue is that the ToStringValue() -> ToString() is actually invoked when rendering an object directly. I checked in Ruby AND Javascript implementations of Liquid it outputs the type name of the object.

If you want to provide a custom "empty/blank" behavior to your objects you should create a custom FluidValue type that will handle these cases.

I am not decided on the solution, will check how the Object.ToStringValue() should behave first.

@JanRomero
Copy link
Author

Thanks for having a look :)

C# also outputs the fully qualified type name (or for records just the name and the properties), unless ToString() is overridden.

I feel like the target audience for a template is end users who wouldn’t expect or want such internals to surface, so I try to make everything output something sensible. But I understand if you want to keep the current behaviour for compatibility with the original implementations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants