-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
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
Proof of concept: Custom functions #11085
base: master
Are you sure you want to change the base?
Conversation
This is a rough sketch of code that allows users of Hugo to provide custom code for use in templates, via Typescript (or Javascript). The use of the [goja runtime](https://github.com/dop251/goja) means execution is entirely within Go, and sandboxed.
You may want to have a look at https://github.com/bep/gojap Creating a new runtime for each function is bound to be very slow, memory hungry. I like the idea of this (given the above, I have been thinking about it ...), but there are lots of caveats, and I suspect a proof of concept would have a better chance of success if it tested out the hard parts first, mainly:
|
Thank you for the rapid reply @bep! For me this was indeed hard thing #1 ("is it at all possible"), but you're absolutely right, passing The two things I'll work on next:
That challenge I faced of all function calls needing to be Go methods; do you think this is worth addressing in a proof of concept? I'm not particularly familiar with the Hugo codebase, so I'd be very willing to leave it to a later round of thought (if we get there). |
You don't want to tackle all problems -- but what I would have wanted to see is something like (pseudo code, I just made up these, so they're not particulary clever): function getLastMod(pages) {
// return the newest .Date from the page list given
}
function filter(pages, predicate) {
// return the pages matching the predicate func.
} |
I got the software equivalent of an earworm and decided to turn it into a proof of concept.
👀 I'm seeking feedback of any kind, which could include "this isn't something Hugo is interested in"; I'll be happy to turn this sorry state of affairs into quality, tested code, or to close this line of thinking down.
What is it?
Code similar to this would allow Hugo users to write and use custom Typescript (or Javascript) functions for use inside their templates.
See the
external.md
at the top of the PR for more detail.Can I test it out?
Yes!
layouts/index.html
andfunctions/*.ts
../path/to/built/hugo
in the site rootpublic/index.html
to see the outputWhy is this useful?
A lot of Hugo's Github Issues seem to be about changing or adding new functions to Hugo. Though contributing to Hugo's codebase is an admirable, it's a long-term solution to these requests and likely isn't available option to many.
Writing and sharing function files, storing them in the site files (eg. in
functions/*.ts
), is a cross-platform, simple, accessible way to be able to write and share helper functions.Some important benefits:
fetch
, but there are lots of new challenges there.import
-able*, so custom code writers can build on the shoulders of the JS community. (*Caveat: I haven't tried this, it'd likely be a little complex right now)Why this PR isn't at all ready
I've thrown this together to understand if it's interesting to the community. There are lots of sharp edges. Some of the ones I've found/considered but not addressed:
{{ fn "filename.FunctionName" "args" }}
instead of{{ filename.FunctionName "args" }}
), as Hugo seems to require namespaced functions to be methods in Go and, because these are dynamically generated from JS, I can't do that (without substantial codechange)<FunctionName>Examples
, expecting it to be in the[][2]string
format used for other function examples, is useless right now.Thanks for reading this far! Let me know what you think.