Skip to content
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

Recusive variable resolving #600

Open
montoner0 opened this issue Oct 10, 2023 · 1 comment
Open

Recusive variable resolving #600

montoner0 opened this issue Oct 10, 2023 · 1 comment

Comments

@montoner0
Copy link

Hi!
Is there some easy way to recursively resolve a variable?
E. g. when template {{ variable1 }} with variable1="{{ variable2 }}" and variable2="value" resolves to value.
For now, the only way I see is doing parse-render in a cycle.

@marcel-hofer
Copy link

If you want this behavior globally - I would probably use the same approach you mentioned.

We had a similar requirement but the re-rendering was limited to a few variables.
Our templates were translated using resources and some of them contained placeholders. For those translations (we managed them), we added a filter to replace the variables. Usage: {{ variable1 | template }}

It is not recursive but is already sufficient for many use cases like the example you mentioned.

public string Render<TModel>(string template, TModel model)
{
    var parser = new FluidParser();
    if (!parser.TryParse(template, out var compiledTemplate, out var error))
    {
        throw new TemplateParseException(error, template);
    }

    var templateOptions = new TemplateOptions
    {
        MemberAccessStrategy = new UnsafeMemberAccessStrategy(),
    };
    templateOptions.Filters.AddFilter("template", TemplateFilter);

    var context = new TemplateContext(model, templateOptions);
    var result = compiledTemplate.Render(context);

    return result;
}

private ValueTask<FluidValue> TemplateFilter(
    FluidValue input,
    FilterArguments arguments,
    TemplateContext context)
{
    var template = input.ToStringValue();

    if (!fluidParser.TryParse(template, out var compiledTemplate, out var error))
    {
        throw new TemplateParseException(error, template);
    }

    var result = compiledTemplate.Render(context);
    return new ValueTask<FluidValue>(new StringValue(result));
}

public class TemplateParseException : Exception
{
    public TemplateParseException(string message, string template)
        : base(message)
    {
        Template = template;
    }

    public string Template { get; set; }
}

Usage:

var model = new { Format = "Hello, {{ Name }}", Name = "John" };
const string template = "{{ Format | template }}!";

// Returns "Hello, John!"
var result = Render(template, model);

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

No branches or pull requests

2 participants