I did some thinking/prototyping today, mostly having to do with template hooks. The use case I'm thinking of is (from one of the above modifications) adding template fragments around a piece of core template:
- Code: Select all
(fragment from a modification)
(another fragment from the same modification)
The fragments above may contain any template constructs, and in particular they do not need to be complete - e.g., the first fragment opens an IF tag and the second fragment closes it (this is the actual code in the mod).
- code hooks
- template hooksGlossary
Hook: code that is part of a modification that is run as if it was placed in a particular location
(Hook) location: a place in code that will invoke modifications' code, also its name which should satisfy ^\w+$ regexp
Hook manager: class that performs hook-related tasks which are not performance sensitive, that is,
those that are not done on every page load
Hook dispatcher: (?) class that performs performance sensitive hook-related tasks, that is,
those that could be done on every page load
The job of the hook dispatcher is to:
1. Determine which hooks are defined for a particular location,
2. Invoke those hooks
as efficiently as possible. In particular, this means expending as little effort as possible processing hook locations that do not have defined hooks.
The job of the hook manager is to:
1. Determine (or delegate to another component) which modifications are installed,
2. Determine which hooks each modification has defined,
(thus determining which hooks are defined system-wide)
3. Organize the defined hooks into a data structure that may be efficiently queried by the hook dispatcher.Hook definition
Hooks may be declared by modifications or comply with a convention that would allow them to be automatically discovered.
A requirement is that hooks for any particular modification should be determinable without running any of the modification's code. Why this requirement? It would make it possible to remove broken modifications and probably make it easier to repair the board should something go wrong. At the same time it is not absolutely needed, maybe it will end up deferred or removed.Hook ordering
Hooks need to run in a well-defined order. Going back to the template example above if two modifications wrap the same core fragment the order in which the before and after hooks are invoked is important.
Because the set of hooks could be different for each board the hook ordering is, generally speaking, specific to a particular board as well.
The hook manager is responsible for figuring out some usable ordering during installation of board, modifications or hooks or some similar process.Hook priority
It seems useful to give modifications some control over where their hooks end up as far as ordering goes. This could be an absolute numeric value as proposed earlier in this topic or some kind of relationship with other hooks/modifications which was my proposal. The exact details are not necessary for implementing a functional hook manager. It is actually possible that an arbitrary ordering would work for a lot of modifications (here arbitrary is with respect to different modifications, nesting must be done correctly which requires a certain measure of internal consistency).
Template construct to be added:
- Code: Select all
<!-- RUNHOOKS location_name -->
It is evaluated when the template is compiled.
Needed from hooks system:
- ability to get all template fragments for a given hook location, in correct order
Needed from template system:
- reentrant template compilation
Possibly have the order flag in RUNHOOKS call.
But is order resolution not orthogonal concept?
Could be simpler if we have a limited before/after concept instead of arbitrary ordering.
<!-- RUNHOOKS before_something -->
<!-- RUNHOOKS -after_something -->
Whatever order modifications are arranged in, - before location will invert it and use the inverted order.