Closed ringods closed 8 months ago
That is a great idea. Did you check out the relatively orphaned davidsneighbour/hugo-blockify#16? I was wondering how to approach the overriding issue. A folder approach would solve it.
Some thoughts before I get it on:
I would probably go for partials/hooks/hookname/filename-cached.html
instead of two folders per hookname, to keep them grouped together. I can check the filename for the -cached
part and act accordingly. I also have cases where I cache the hook call itself without having it named cached, which is a hack, but that way I can control the context that is cached. I'll add another issue to think about the caching approach(es). Right now with the ending it will cache 100% or 0% of the calls.
What if the hook should not be in addition to existing hooks. For instance there could be a social media button plugin that adds it's button, then a hook in the theme wants to override that hook. We need a configuration parameter somewhere that clears up existing hooks further down the rabbit hole. This might have to be done via data configuration.
For backwards compatibility, we could still resolve the files (current implementation) as a last resort.
I would keep that as "first" resort. Basically, if a hookname(-cached).html exists, but no hookname/filename.html
then run with the filebased hook. After that check the hookname
directory. The call for the hook could in the most verbose setup add, what approach/hook path is executed.
What about order of hooks. I think a weight parameter would be the proper way to approach it. from 0 to 100 with 50 as (unconfigured) default so developers can fine tune. WP (ehem) does it that way.
I'll sleep on that idea and will add more thoughts in a bit.
Ideas:
Easiest: file name based configuration
cached
keyword in the filenameSample:
init/my-function-50-cached.html
will be exploded into ["my", "function", "50", "cached"]. last item is equal to "cached", so the partial will be cached. last-1 item is when evaluated as integer to an integer, so this will be the weight.
init/my-function-50.html
- last item is not equal to cached
so no caching. last item is an integer, so used as weight.
After running through all hooks the map is sorted and partials are loaded. We assume but don't actively sort the rest inside of the weight by filename.
Harder, but better configurable:
Configuration via data configuration in the plugin: data/$namespace/$pluginname/hugo-hooks.toml
with configuration of something like this:
[hookname."filename"]
weight = 50
cached = true
Issues here: filename needs to go in quotation marks so the file extension won't break the config.
Additional ideas:
cached
config could instead of true/false contain a keyword like page
, section
, etc. and cache based on that as caching context, which makes the caching more flexible.If a file has a data configuration then that is used (the file would not have weight and cached parameters in it's name anyway). If not then the file name rules are applied. if all are "missing" the default is to not cache.
Thoughts?
Issue with the data config approach: The plugin has to go through all data configurations to "collect" their configurations. That will need time. So that will have to be done in itself as a hook on init or setup and then either put into a scratch (cached per page) or that new feature where the scratch stays constant throughout the run of hugo... never tested that.
Before picking up the conversation again on this feature, let's first review the use of hugo-hooks
as I interpret it. I would like to verify if we are looking into a similar direction before going forward.
If you scan the Hugo Themes gallery, a lot of themes include functionality which one could argue shouldn't be linked to the theme:
... and other stuff. With hugo-hooks
used in a theme, the theme builder integrates the "invocation" of the hooks in the right places of the various layouts, and styles everything nicely. The theme itself doesn't provide any implementation for the different hooks. Theme builders can focus more on the UI/UX rather than all the additional features.
Coming back to the idea of using folders as hooks. The main reason to propose folders as hooks, is that additional features are activated just by installing a Hugo module:
Building the site will then automatically pick up the hooked-in features.
In one of your previous comments, you started discussing the order of multiple files in a specific hook folder. Before implementing this, I would like to verify if this is a real problem. My thinking is as follows. If I would build a theme, and I would use the hooks specified in your Best Practice
section, the theme would have 20 hooks. As a Hugo module implementator, I take care of identifying the right hook folder(s) to put my stuff in. But what is the chance that, at the level of a single hook folder, the order of two hook snippets, coming from different Hugo moduls, render a problem?
But assume it would happen, can we fall back to using Hugo module mounts
, includeFiles
and excludeFiles
to re-map files?
But what is the chance that, at the level of a single hook folder, the order of two hook snippets, coming from different Hugo modules, render a problem?
Let's assume a hook that adds a script that requires another script, maybe both in two different modules (libraries with jquery vs. theme switcher). The second would require the first and I want all those scripts at the end of my page (for SEO reasons).
I can think of more complicated hook systems. This is where these weight settings come into play. I wouldn't make it an enforced setting, but additional. For now, having them in folders is enough to become a feature.
The theme itself doesn't provide any implementation for the different hooks.
That's true, but the user of the theme might want to add a CTA before the content, or an ad after the first post, or the tracking code of his analytics program somewhere. The users for hooks are module authors and users IMHO.
Closing this in favour of config based hook setups.
Note that in a subsequent release the requirement of a namespace was introduced. See docs...
Is your feature request related to a problem? Please describe.
Hooks map onto files with the same name as the hook (and its cached variant). For instance, taking the
head-start
hook from theBest Practice
list, the hook will load:But there can only be a single file implementing that hook as a result, which means that the hook implementation is custom to a site or theme and not really pluggable.
Describe the solution you'd like
What if we would change this to work with folders? Taking the same
head-start
hook, resolving this hook would load all files in this folder(s):More than one Hugo module could then contribute snippets to the same hook.
For backwards compatibility, we could still resolve the files (current implementation) as a last resort.
Describe alternatives you've considered
Making a "clone" of your
hugo-hooks
, but I rather bundle forces instead of creating my ownhugo-hooks
variant.Additional context
I use
hugo-netlification
. If we would implementfolders as hooks
, the netlification module could be updated to provide the snippets placed in the correct folder(s):After adding the
hugo-netlification
module to my site, only the netlification configuration is required separately. Files are already at the correct place for inclusion.