Note: Addons are considered experimental for now. This means the hooks are likely to change in the next versions of TwoFold. I need more time to understand what's the best way to interrupt the execution, return values, what's the minimum number of params needed, etc.
Addons are a new feature in TwoFold v0.11 and they are hooks that get executed at the evaluation of the tag function. They allow intercepting the tag node, tag function and the context, or hacking the function results, in order to modify the normal behaviour of the tags.
The builtin addons are:
- freeze/ protect/ freezeChildren -- are used for freezing or protecting tags, or their children
- consume - is used for consuming double tags and even single tags that are normally not destroyed
- cache memory & disk -- used to store the content of a tag for some time and skip the execution of the tag until the cache expires
- into variable -- store the inner text of the tag into a global variable, esentially converting it into a "set variable" tag
There are 3 addon hooks:
- pre-eval
- post-eval
- pre-children
There are 2 types of tags, depending on how they executed, and the order of the hooks is different:
- DFS (depth-first order) are the normal tags and they work as you would expect: the children of the tag get executed first, then the results are passed up to the parent;
- BFS (breadth-first order) are a new type of tag in TwoFold v0.11 and they get executed before the children. Examples of BFS tags are: set, del, json, toml, import, freeze, protect.
So the execution of the hooks for a DFS tag is:
- pre-children (because children get executed first)
- pre-eval
- post-eval
And for a BFS tag is:
- pre-eval
- post-eval
- pre-children (because children get executed last)
I wanted to do "plugins" at least since 2019, see the old Roadmap Document, but it wasn't the rigt time, and I didn't know where they would fit. The old usecase was to cache JSON responses to avoid rate-limiting/ too-many-requests, but addons/ plugins/ middlewares as they are now, are more flexible than that, and probably the most powerful example is the "protect" tag that actually implements a custom evaluation function.