From 6b10d9d428b6b3073e18434917712a2de8fd9c06 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Mon, 12 May 2014 00:00:53 -0700 Subject: [PATCH] Add the ability to set a priority order for sitemap resource list manipulators. This allows us to do things like forcing :directory_indexes to always run last, alleviating the problem of the sitemap output differing depending on when you activate your extensions. --- middleman-core/lib/middleman-core/extension.rb | 10 ++++++++-- .../extensions/directory_indexes.rb | 4 ++++ .../lib/middleman-core/sitemap/store.rb | 18 ++++++++++++++---- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index f4248657..cff75105 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -81,6 +81,12 @@ module Middleman # @return [Symbol] the name this extension is registered under. This is the symbol used to activate the extension. class_attribute :ext_name, instance_reader: false, instance_writer: false + # @!attribute resource_list_manipulator_priority + # @!scope class + # @return [Numeric] the priority for this extension's `manipulate_resource_list` method, if it has one. + # @see Middleman::Sitemap::Store#register_resource_list_manipulator + class_attribute :resource_list_manipulator_priority, instance_reader: false, instance_writer: false + class << self # @api private # @return [Middleman::Configuration::ConfigurationManager] The defined options for this extension. @@ -150,7 +156,7 @@ module Middleman # @return [void] def activated_extension(instance) name = instance.class.ext_name - return unless @_extension_activation_callbacks && @_extension_activation_callbacks.has_key?(name) + return unless @_extension_activation_callbacks && @_extension_activation_callbacks.key?(name) @_extension_activation_callbacks[name].each do |block| block.arity == 1 ? block.call(instance) : block.call end @@ -276,7 +282,7 @@ module Middleman # rubocop:disable IfUnlessModifier if ext.respond_to?(:manipulate_resource_list) - ext.app.sitemap.register_resource_list_manipulator(ext.class.ext_name, ext) + ext.app.sitemap.register_resource_list_manipulator(ext.class.ext_name, ext, ext.class.resource_list_manipulator_priority) end end end diff --git a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb index 5c14f723..68e9f958 100644 --- a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb +++ b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb @@ -1,5 +1,9 @@ # Directory Indexes extension class Middleman::Extensions::DirectoryIndexes < ::Middleman::Extension + # This should run after most other sitemap manipulators so that it + # gets a chance to modify any new resources that get added. + self.resource_list_manipulator_priority = 100 + # Update the main sitemap resource list # @return [void] def manipulate_resource_list(resources) diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 816d94d5..992cae00 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -62,9 +62,19 @@ module Middleman # # @param [Symbol] name Name of the manipulator for debugging # @param [#manipulate_resource_list] manipulator Resource list manipulator + # @param [Numeric] priority Sets the order of this resource list manipulator relative to the rest. By default this is 50, and manipulators run in the order they are registered, but if a priority is provided then this will run ahead of or behind other manipulators. # @return [void] - def register_resource_list_manipulator(name, manipulator, *) - @resource_list_manipulators << [name, manipulator] + def register_resource_list_manipulator(name, manipulator, priority=50) + # The third argument used to be a boolean - handle those who still pass one + priority = 50 unless priority.is_a? Numeric + @resource_list_manipulators << [name, manipulator, priority] + # The index trick is used so that the sort is stable - manipulators with the same priority + # will always be ordered in the same order as they were registered. + n = 0 + @resource_list_manipulators = @resource_list_manipulators.sort_by do |m| + n += 1 + [m[2], n] + end rebuild_resource_list!(:registered_new) end @@ -212,8 +222,8 @@ module Middleman @app.logger.debug '== Rebuilding resource list' - @resources = @resource_list_manipulators.reduce([]) do |result, (_, inst)| - newres = inst.manipulate_resource_list(result) + @resources = @resource_list_manipulators.reduce([]) do |result, (_, manipulator, _)| + newres = manipulator.manipulate_resource_list(result) # Reset lookup cache reset_lookup_cache!