Support plugins for extending funcMap

Made this as an issue in github, but realized it might be more appropriate here.

Note: I would be willing to implement this if others think it is valuable

In working with another generator, I needed a function that didn’t exist in the funcMap, and adding it required a PR to the generator. It occurred to me that it would be very easy to implement a plugin system to allow users to implement their own functions in the funcMap.

Here’s my suggestion - plugins are very simple executables that follow this pattern:

If a plugin executable is run with no arguments, it should output to stdout a newline delimited list of function names. Hugo would run all the plugins[1] at startup and keep a reference of which plugin produced which function name, for when they’re called from a template.

When a template calls one of the plugin’s functions, the plugin executable is run with with the function name as an argument, and any further arguments are sent as a json array to the plugin’s stdin[2]. The result of the program should be json formatted and written to stdout. If an error is encountered, the executable should exit with a non-zero exit code, and write any error text to stderr.

Bam, now any user can create a plugin in any language they want to extend the functionality of Hugo to support any function they want.

[1] How plugins are discovered by Hugo is left to the developer. I don’t really care if it’s a magic directory or specially named executables in the $PATH or whatever.

[2] We do this to avoid OS character limits on executable arguments.

1 Like

Sounds familiar. :pie: Welcome back. :smiley: Would you use pie for this?

I’ve wanted plugins for a long time, so I’m in favor of exploring this. I love the idea of external executables instead of dynamic linking.

My only real concerns are around security. Regarding Footnote 1, I take you mean that you will provide a working plugin framework, but it’s up to someone else to deal with the concerns in #796. Am I reading you correctly?

How would we handle funcMap entry overloading?

My take: A full blown proposal may help avoid wasted effort. If you can define and implement a working plugin framework, I suspect we would figure out how to solve the security issues in #796.

PS - I’m also curious about a client-server framework where the plugin stays running while we pass it work to do instead of separate exec’s on each funcMap invocation. But I’d like to see how fast (or slow) your framework is before we spend time on a client-server framework.