Suggestion: allow accessing parameter names
pmlopes opened this issue · 7 comments
It would be nice to have this API made public:
The use case:
You have a generic template and allow users to pass you a generic map with all possible variables.
If the variables do not match the template arguments you'll get an error. Sometimes variables do not match because the user passed some extra values, imagine a map that gets enriched as it is processed by the user API.
Having a way to know the expected arguments, we could bind the required arguments only ignoring the extras and making the template always to succeed.
Also note that there's a small bug on that method, the logged message refers to a different method name that the one really accessed by reflection.
The concept you're referring to already exists. That class you referenced returns a BindableRockerModel which has a bind() method that accepts a map. It compares what you provided against the arguments defined.
String rendered = Rocker.template("views/index.rocker.html")
.bind(map_is_accepted_here)
.render()
.toString();
Finally, the reflection you are talking about is not a bug. We're accessing a method in the Model class, not the Rocker class. If what you mentioned was a bug, there is extensive test coverage of Rocker and BindableRockerModel would catch it. I just think you're a little confused what Rocker is doing vs. BindableRockerModel.
I don't think I explained the problem well enough, my case was, Imagine that in a application lifecycle a Map (session data) is populated with some state and the end of the processing we want to render a template. This state will contain more information that what is needed by the template. Imagine:
This would be the map:
{
"id": "session-id",
"name": "Paulo"
}
If my template is:
@args (String name)
Hello @name
Then the render will throw because the number of arguments don't match with a message property id
not found.
I'd like either to relax this rule or know in advance what arguments are accepted so I can bind only the correct ones.
The logic is already present the generated code contains:
...
public static String[] getArgumentNames() {
return new String[]{"name"};
}
...
It's just a matter of making this accessible.
Regarding the "bug" it was on the log message:
The method name is getArgumentNames
but the log message says Unable to read getModifiedAt
which is some other method.
@pmlopes Thank you for your new explanation -- I think I get your use case better now. You basically want a relaxed version of setting arguments by supplying a map of values.
I'd be open to a PR that added another method to Rocker.java that builds a model from a map of values. Since Rocker is usually strict with enforcing variable names match templates, I'd suggest the Map of values by default will be strict and check they match what the template accepts. However, let the caller also turn off that functionality, so it just sets what it can.
I'll make the PR after the Christmas break! Thanks!
Fixed in latest release.