Module: Bridgetown::Hooks
- Defined in:
- bridgetown-core/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
- 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
105 106 107 108 109 110 111 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 105 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
39 40 41 42 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 39 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
30 31 32 33 34 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 30 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
55 56 57 58 59 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 55 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
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 73 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
100 101 102 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 100 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.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'bridgetown-core/lib/bridgetown-core/hooks.rb', line 118 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 |