Module: Bridgetown::Hooks
- Defined in:
- bridgetown-core/lib/bridgetown-core/hooks.rb
Constant Summary collapse
- HookRegistration =
Data.define( :owner, :event, :priority, :reloadable, :block ) do def to_s "#{owner}:#{event} for #{block}" end end
- DEFAULT_PRIORITY =
20- PRIORITY_MAP =
{ low: 10, normal: 20, high: 30, }.freeze
- 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
104 105 106 107 108 109 110 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 104 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
38 39 40 41 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 38 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
29 30 31 32 33 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 29 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
54 55 56 57 58 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 54 def self.register(owners, event, priority: DEFAULT_PRIORITY, reloadable: true, &block) Array(owners).each do |owner| register_one(owner, event, priority:, 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
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 72 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:, event:, priority: priority_value(priority), reloadable:, 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
99 100 101 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 99 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.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 117 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 |