Module: Abqari::Hooks
- Defined in:
- lib/abqari/hooks.rb
Overview
Plugin hook registry. Plugins register named-event callbacks; the engine invokes them at known points during the build.
Two flavours:
- `register(event, &block)` + `run(event, ...)` — event-style.
Every registered callback is called for its side effect; the
return value is ignored.
- `register(event, &block)` + `run_filter(event, value, ...)` —
filter-style. The value is threaded through every callback;
each callback returns the (possibly modified) value, and the
final result is what the engine consumes downstream.
Events exposed by the engine (see docs/plugins.md for the canonical list):
Lifecycle:
:before_build (site) — Site#build entry
:after_load_pages (site) — after `load_pages`, before generators
:after_generate (site) — after `generate_all`
:before_render_page (site, page) — per page, before its render call
:after_build (site) — Site#build exit (success or failure)
Filters:
:post_process (html, site, page) -> html
:resolved_frontmatter (fm, page) -> fm
Thread safety: registration and run iterate over a snapshot of the callback list, so registering inside a hook callback is safe (the new callback fires on the next event, not the current one).
Class Method Summary collapse
-
.clear! ⇒ Object
Reset the registry.
- .count(event) ⇒ Object
-
.register(event, &block) ⇒ Object
Register a callback for
event. -
.registered_events ⇒ Object
Read-only snapshot of the current registry — useful in tests and for
bin/auditstyle introspection. -
.run(event, *args) ⇒ Object
Run every callback registered for
event. -
.run_filter(event, value, *args) ⇒ Object
Thread
valuethrough every callback registered forevent.
Class Method Details
.clear! ⇒ Object
Reset the registry. Used in tests and any caller that wants a fresh hook table — the engine itself doesn't currently clear between rebuilds (plugins survive incremental rebuilds, matching Jekyll's _plugins/ semantics).
83 84 85 |
# File 'lib/abqari/hooks.rb', line 83 def clear! @mutex.synchronize { @hooks = Hash.new { |h, k| h[k] = [] } } end |
.count(event) ⇒ Object
93 94 95 |
# File 'lib/abqari/hooks.rb', line 93 def count(event) @mutex.synchronize { @hooks[event].size } end |
.register(event, &block) ⇒ Object
Register a callback for event. Returns the block for chaining.
41 42 43 44 45 46 |
# File 'lib/abqari/hooks.rb', line 41 def register(event, &block) raise ArgumentError, "Hooks.register requires a block (event: #{event.inspect})" unless block @mutex.synchronize { @hooks[event] << block } block end |
.registered_events ⇒ Object
Read-only snapshot of the current registry — useful in tests
and for bin/audit style introspection.
89 90 91 |
# File 'lib/abqari/hooks.rb', line 89 def registered_events @mutex.synchronize { @hooks.keys.dup } end |
.run(event, *args) ⇒ Object
Run every callback registered for event. Each return value is
discarded; use run_filter if you need to transform a value.
50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/abqari/hooks.rb', line 50 def run(event, *args) snapshot = @mutex.synchronize { @hooks[event].dup } snapshot.each do |hook| hook.call(*args) rescue StandardError => e Log.error "plugin hook #{event} crashed: #{e.class}: #{e.}" e.backtrace&.first(5)&.each { |line| Log.error " #{line}" } # Re-raise — a misbehaving plugin should fail the build, not # silently produce wrong output. Operators can debug from # the logged backtrace. raise end end |
.run_filter(event, value, *args) ⇒ Object
Thread value through every callback registered for event.
Each callback receives (value, *args) and returns the new
value. Final value flows back to the caller.
67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/abqari/hooks.rb', line 67 def run_filter(event, value, *args) snapshot = @mutex.synchronize { @hooks[event].dup } snapshot.each do |hook| value = hook.call(value, *args) rescue StandardError => e Log.error "plugin filter #{event} crashed: #{e.class}: #{e.}" e.backtrace&.first(5)&.each { |line| Log.error " #{line}" } raise end value end |