PebbleTemplates / pebble

Java Template Engine
https://pebbletemplates.io
BSD 3-Clause "New" or "Revised" License
1.1k stars 168 forks source link

Support Dynamic Named Arguments in Function #656

Open haducloc opened 1 year ago

haducloc commented 1 year ago

Requirements: I want to build a function that can produces URL based on MVC action/controller named arguments and list of named parameter arguments:

{{ url( action='index', controller='main', __param1='value1', __param2=value2, __param3=model.property3 ) }}

The issue is: It depends on the context of use, the list of parameter names maybe different -> Need dynamic named parameter argument supported.

My code - The following named argument does not exist .....

    public class UrlTagFunction implements Function {

        @Override
        public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
        String action = (String)args.get("action");
        String controller = (String)args.get("controller");

        // parameters
        for (Map.Entry<String, Object> arg : args.entrySet()) {
            if (arg.getKey().startsWith("__")) {

            // Got a dynamic parameter
            }
        }

        // Build url from action/controller and dynamic parameters

        return url;
        }

        @Override
        public List<String> getArgumentNames() {

        // **** ISSUE ***** : The developers don't know list of named parameters in advance.

        return List.of("action", "controller");
        }
    }

My suggestion:

Remove validating of named arguments from io.pebbletemplates.pebble.node.ArgumentsNode

Remove this code:

          // check if user used an incorrect name
          if (!argumentNames.contains(arg.getName())) {
            throw new PebbleException(null,
                "The following named argument does not exist: " + arg.getName(),
                this.lineNumber, self.getName());
          }

And let the developers validate args inside the Function execute method instead.

FYI: JSP/JSTL supports dynamic attributes.