Module: Bridgetown::Hooks
- Defined in:
- lib/bridgetown-core/hooks.rb
Defined Under Namespace
Classes: HookRegistration
Constant Summary collapse
- DEFAULT_PRIORITY =
20
- PRIORITY_MAP =
{ low: 10, normal: 20, high: 30, }.freeze
- NotAvailable =
Class.new(RuntimeError)
- Uncallable =
Class.new(RuntimeError)
Class Method Summary collapse
-
.clear_reloadable_hooks ⇒ Object
Clear all hooks marked as reloadable from the registry.
-
.prioritized_hooks(hooks) ⇒ Object
Sort registered hooks according to priority and load order.
- .priority_value(priority) ⇒ Object
-
.register(owners, event, priority: DEFAULT_PRIORITY, reloadable: true) {|obj| ... } ⇒ Object
Register one or more hooks which may be triggered later for a particular event.
-
.register_one(owner, event, priority: DEFAULT_PRIORITY, reloadable: true) {|obj| ... } ⇒ Proc
Register a hook which may be triggered later for a particular event.
-
.remove_hook(owner, block) ⇒ Object
Delete a previously-registered hook.
-
.trigger(owner, event, *args) ⇒ Object
Trigger all registered hooks for a particular owner and event.
Class Method Details
.clear_reloadable_hooks ⇒ Object
Clear all hooks marked as reloadable from the registry
106 107 108 109 110 111 112 |
# File 'lib/bridgetown-core/hooks.rb', line 106 def self.clear_reloadable_hooks Bridgetown.logger.debug("Clearing reloadable hooks") @registry.each_value do |hooks| hooks.delete_if(&:reloadable) end end |
.prioritized_hooks(hooks) ⇒ Object
Sort registered hooks according to priority and load order
40 41 42 43 |
# File 'lib/bridgetown-core/hooks.rb', line 40 def self.prioritized_hooks(hooks) grouped_hooks = hooks.group_by(&:priority) grouped_hooks.keys.sort.reverse.map { |priority| grouped_hooks[priority] }.flatten end |
.priority_value(priority) ⇒ Object
31 32 33 34 35 |
# File 'lib/bridgetown-core/hooks.rb', line 31 def self.priority_value(priority) return priority if priority.is_a?(Integer) PRIORITY_MAP[priority] || DEFAULT_PRIORITY end |
.register(owners, event, priority: DEFAULT_PRIORITY, reloadable: true) {|obj| ... } ⇒ Object
Register one or more hooks which may be triggered later for a particular event
56 57 58 59 60 |
# File 'lib/bridgetown-core/hooks.rb', line 56 def self.register(owners, event, priority: DEFAULT_PRIORITY, reloadable: true, &block) Array(owners).each do |owner| register_one(owner, event, priority: priority, reloadable: reloadable, &block) end end |
.register_one(owner, event, priority: DEFAULT_PRIORITY, reloadable: true) {|obj| ... } ⇒ Proc
Register a hook which may be triggered later for a particular event
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/bridgetown-core/hooks.rb', line 74 def self.register_one(owner, event, priority: DEFAULT_PRIORITY, reloadable: true, &block) @registry[owner] ||= [] raise Uncallable, "Hooks must respond to :call" unless block.respond_to? :call @registry[owner] << HookRegistration.new( owner: owner, event: event, priority: priority_value(priority), reloadable: reloadable, block: block ) if ENV["BRIDGETOWN_LOG_LEVEL"] == "debug" if Bridgetown.respond_to?(:logger) Bridgetown.logger.debug("Registering hook:", @registry[owner].last.to_s) else p "Registering hook:", @registry[owner].last.to_s end end block end |
.remove_hook(owner, block) ⇒ Object
Delete a previously-registered hook
101 102 103 |
# File 'lib/bridgetown-core/hooks.rb', line 101 def self.remove_hook(owner, block) @registry[owner].delete_if { |item| item.block == block } end |
.trigger(owner, event, *args) ⇒ Object
Trigger all registered hooks for a particular owner and event. Any arguments after the initial two will be directly passed along to the hooks.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/bridgetown-core/hooks.rb', line 119 def self.trigger(owner, event, *args) # rubocop:disable Metrics/CyclomaticComplexity # proceed only if there are hooks to call hooks = @registry[owner]&.select { |item| item.event == event } return if hooks.nil? || hooks.empty? prioritized_hooks(hooks).each do |hook| if ENV["BRIDGETOWN_LOG_LEVEL"] == "debug" hook_info = args[0].respond_to?(:relative_path) ? args[0].relative_path : hook.block Bridgetown.logger.debug("Triggering hook:", "#{owner}:#{event} for #{hook_info}") end hook.block.call(*args) end true end |