lib/nanoc/base/plugin_registry.rb in nanoc-3.4.3 vs lib/nanoc/base/plugin_registry.rb in nanoc-3.5.0b1

- old
+ new

@@ -12,27 +12,47 @@ # A module that contains class methods for plugins. It provides functions # for setting identifiers, registering plugins and finding plugins. Plugin # classes should extend this module. module PluginMethods - # Sets the identifiers for this plugin. + # @overload identifiers(*identifiers) # - # @param [Array<Symbol>] identifiers A list of identifiers to assign to - # this plugin. + # Sets the identifiers for this plugin. # - # @return [void] + # @param [Array<Symbol>] identifiers A list of identifiers to assign to + # this plugin. + # + # @return [void] + # + # @overload identifiers + # + # @return [Array<Symbol>] The identifiers for this plugin def identifiers(*identifiers) - register(self, *identifiers) + if identifiers.empty? + Nanoc::PluginRegistry.instance.identifiers_of(self.superclass, self) + else + register(self, *identifiers) + end end - # Sets the identifier for this plugin. + # @overload identifier(identifier) # - # @param [Symbol] identifier An identifier to assign to this plugin. + # Sets the identifier for this plugin. # - # @return [void] - def identifier(identifier) - register(self, identifier) + # @param [Symbol] identifier An identifier to assign to this plugin. + # + # @return [void] + # + # @overload identifier + # + # @return [Symbol] The first identifier for this plugin + def identifier(identifier=nil) + if identifier + self.identifiers(identifier) + else + Nanoc::PluginRegistry.instance.identifiers_of(self.superclass, self).first + end end # Registers the given class as a plugin with the given identifier. # # @param [Class, String] class_or_name The class to register, or a @@ -79,11 +99,12 @@ # Creates a new plugin registry. This should usually not be necessary; it # is recommended to use the shared instance (obtained from # {Nanoc::PluginRegistry.instance}). def initialize - @map = {} + @identifiers_to_classes = {} + @classes_to_identifiers = {} end # Registers the given class as a plugin. # # @param [Class] superclass The superclass of the plugin. For example: @@ -97,39 +118,52 @@ # @param [Symbol] identifiers One or more symbols identifying the class. # For example: `:haml`, :`erb`. # # @return [void] def register(superclass, class_or_name, *identifiers) - @map[superclass] ||= {} + @identifiers_to_classes[superclass] ||= {} + @classes_to_identifiers[superclass] ||= {} identifiers.each do |identifier| - @map[superclass][identifier.to_sym] = class_or_name + @identifiers_to_classes[superclass][identifier.to_sym] = class_or_name + (@classes_to_identifiers[superclass][name_for_class(class_or_name)] ||= []) << identifier.to_sym end end + # @param [Class] superclass The superclass of the plugin. For example: + # {Nanoc::Filter}, {Nanoc::Extra::VCS}. + # + # @param [Class, String] class_or_name The class to get the identifiers for. + # This can also be a string containing the name of the class. + # + # @return [Array<Symbol>] An array of identifiers for the given class + def identifiers_of(superclass, klass) + (@classes_to_identifiers[superclass] || {})[name_for_class(klass)] || [] + end + # Finds the plugin that is a subclass of the given class and has the given # name. # # @param [Class] klass The class of the plugin to return # # @param [Symbol] name The name of the plugin to return # # @return [Class, nil] The plugin with the given name def find(klass, name) - @map[klass] ||= {} - resolve(@map[klass][name.to_sym], klass) + @identifiers_to_classes[klass] ||= {} + resolve(@identifiers_to_classes[klass][name.to_sym], klass) end # Returns all plugins of the given class. # # @param [Class] klass The class of the plugin to return # # @return [Enumerable<Class>] A collection of class plugins def find_all(klass) - @map[klass] ||= {} + @identifiers_to_classes[klass] ||= {} res = {} - @map[klass].each_pair { |k,v| res[k] = resolve(v, k) } + @identifiers_to_classes[klass].each_pair { |k,v| res[k] = resolve(v, k) } res end # Returns a list of all plugins. The returned list of plugins is an array # with array elements in the following format: @@ -137,11 +171,11 @@ # { :class => ..., :superclass => ..., :identifiers => ... } # # @return [Array<Hash>] A list of all plugins in the format described def all plugins = [] - @map.each_pair do |superclass, submap| + @identifiers_to_classes.each_pair do |superclass, submap| submap.each_pair do |identifier, klass| # Find existing plugin existing_plugin = plugins.find do |p| p[:class] == klass && p[:superclass] == superclass end @@ -179,10 +213,14 @@ else class_or_name end end memoize :resolve - + + def name_for_class(klass) + klass.to_s.sub(/^(::)?/, '::') + end + end # @deprecated Use {Nanoc::PluginRegistry.instance} instead Plugin = PluginRegistry.instance