From c7866f1eff3ad081395a67c61cafcdcca2a1a355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Verg=C3=A9s?= Date: Mon, 2 Dec 2024 14:57:04 +0100 Subject: [PATCH] add an organization memoizer for helpers --- Gemfile.lock | 2 +- .../proposal_l_cell_override.rb | 5 +-- .../decidim_awesome/needs_awesome_config.rb | 2 - lib/decidim/decidim_awesome/awesome.rb | 2 + .../decidim_awesome/awesome_helpers.rb | 44 ++++++++++++++----- lib/decidim/decidim_awesome/engine.rb | 6 +-- .../decidim_awesome/organization_memoizer.rb | 21 +++++++++ 7 files changed, 60 insertions(+), 22 deletions(-) create mode 100644 lib/decidim/decidim_awesome/organization_memoizer.rb diff --git a/Gemfile.lock b/Gemfile.lock index 2fbf84c6d..548d72b9c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -749,7 +749,7 @@ GEM uber (0.1.0) unicode-display_width (2.6.0) uniform_notifier (1.16.0) - uri (0.13.1) + uri (1.0.2) valid_email2 (4.0.6) activemodel (>= 3.2) mail (~> 2.5) diff --git a/app/cells/concerns/decidim/decidim_awesome/proposal_l_cell_override.rb b/app/cells/concerns/decidim/decidim_awesome/proposal_l_cell_override.rb index 6566a4c1c..3dfcd5291 100644 --- a/app/cells/concerns/decidim/decidim_awesome/proposal_l_cell_override.rb +++ b/app/cells/concerns/decidim/decidim_awesome/proposal_l_cell_override.rb @@ -11,12 +11,11 @@ module ProposalLCellOverride alias_method :decidim_original_cache_hash, :cache_hash def metadata_cell - awesome_voting_manifest_for(resource&.component)&.proposal_metadata_cell.presence || "decidim/proposals/proposal_metadata" + @metadata_cell ||= awesome_voting_manifest_for(resource&.component)&.proposal_metadata_cell.presence || "decidim/proposals/proposal_metadata" end def cache_hash - extra_hash = model.extra_fields&.reload&.vote_weight_totals - "#{decidim_original_cache_hash}#{Decidim.cache_key_separator}#{extra_hash}" + @cache_hash ||= "#{decidim_original_cache_hash}#{Decidim.cache_key_separator}#{model.extra_fields&.reload&.vote_weight_totals}" end end end diff --git a/app/controllers/concerns/decidim/decidim_awesome/needs_awesome_config.rb b/app/controllers/concerns/decidim/decidim_awesome/needs_awesome_config.rb index d61f2177b..59bd0df2e 100644 --- a/app/controllers/concerns/decidim/decidim_awesome/needs_awesome_config.rb +++ b/app/controllers/concerns/decidim/decidim_awesome/needs_awesome_config.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "decidim/decidim_awesome/awesome_helpers" - module Decidim module DecidimAwesome module NeedsAwesomeConfig diff --git a/lib/decidim/decidim_awesome/awesome.rb b/lib/decidim/decidim_awesome/awesome.rb index 224df298f..5d66fdacd 100644 --- a/lib/decidim/decidim_awesome/awesome.rb +++ b/lib/decidim/decidim_awesome/awesome.rb @@ -4,6 +4,8 @@ module Decidim module DecidimAwesome include ActiveSupport::Configurable + autoload :AwesomeHelpers, "decidim/decidim_awesome/awesome_helpers" + autoload :OrganizationMemoizer, "decidim/decidim_awesome/organization_memoizer" autoload :Config, "decidim/decidim_awesome/config" autoload :SystemChecker, "decidim/decidim_awesome/system_checker" autoload :ContextAnalyzers, "decidim/decidim_awesome/context_analyzers" diff --git a/lib/decidim/decidim_awesome/awesome_helpers.rb b/lib/decidim/decidim_awesome/awesome_helpers.rb index 74936e3fd..bb885244b 100644 --- a/lib/decidim/decidim_awesome/awesome_helpers.rb +++ b/lib/decidim/decidim_awesome/awesome_helpers.rb @@ -6,6 +6,8 @@ module Decidim # add a global helper with awesome configuration module DecidimAwesome module AwesomeHelpers + include OrganizationMemoizer + # Returns the normalized config for an Organization and the current url def awesome_config_instance return @awesome_config_instance if @awesome_config_instance @@ -20,11 +22,15 @@ def awesome_config_instance end def awesome_config - @awesome_config ||= awesome_config_instance.config + memoize("awesome_config") do + awesome_config_instance.config + end end def javascript_config_vars - awesome_config.slice(:allow_images_in_proposals, :allow_images_in_editors, :allow_videos_in_editors, :auto_save_forms).to_json.html_safe + memoize("javascript_config_vars") do + awesome_config.slice(:allow_images_in_proposals, :allow_images_in_editors, :allow_videos_in_editors, :auto_save_forms).to_json.html_safe + end end def show_public_intergram? @@ -35,11 +41,15 @@ def show_public_intergram? end def unfiltered_awesome_config - @unfiltered_awesome_config ||= awesome_config_instance.unfiltered_config + memoize("unfiltered_awesome_config") do + awesome_config_instance.unfiltered_config + end end def organization_awesome_config - @organization_awesome_config ||= awesome_config_instance.organization_config + memoize("organization_awesome_config") do + awesome_config_instance.organization_config + end end def awesome_version @@ -48,33 +58,43 @@ def awesome_version # Collects all CSS that is applied in the current URL context def awesome_scoped_styles - @awesome_scoped_styles ||= awesome_config_instance.collect_sub_configs_values("scoped_style") + memoize("awesome_scoped_styles") do + awesome_config_instance.collect_sub_configs_values("scoped_style") + end end # Collects all CSS that is applied in the current URL context def awesome_scoped_admin_styles - @awesome_scoped_admin_styles ||= awesome_config_instance.collect_sub_configs_values("scoped_admin_style") + memoize("awesome_scoped_admin_styles") do + awesome_config_instance.collect_sub_configs_values("scoped_admin_style") + end end # Collects all proposal custom fields that is applied in the current URL context def awesome_scoped_admins - @awesome_scoped_admins ||= awesome_config_instance.collect_sub_configs_values("scoped_admin") + memoize("awesome_scoped_admins") do + awesome_config_instance.collect_sub_configs_values("scoped_admin") + end end # Collects all proposal custom fields that is applied in the current URL context def awesome_proposal_custom_fields - @awesome_proposal_custom_fields ||= awesome_config_instance.collect_sub_configs_values("proposal_custom_field") + memoize("awesome_proposal_custom_fields") do + awesome_config_instance.collect_sub_configs_values("proposal_custom_field") + end end def awesome_proposal_private_custom_fields - @awesome_proposal_private_custom_fields ||= awesome_config_instance.collect_sub_configs_values("proposal_private_custom_field") + memoize("awesome_proposal_private_custom_fields") do + awesome_config_instance.collect_sub_configs_values("proposal_private_custom_field") + end end # this will check if the current component has been configured to use a custom voting manifest def awesome_voting_manifest_for(component) - return nil unless component.settings.respond_to? :awesome_voting_manifest - - DecidimAwesome.voting_registry.find(component.settings.awesome_voting_manifest) + memoize("awesome_voting_manifest_for_#{component.id}") do + DecidimAwesome.voting_registry.find(component.settings.try(:awesome_voting_manifest)) + end end # Retrives all the "admins_available_authorizations" for the user along with other possible authorizations diff --git a/lib/decidim/decidim_awesome/engine.rb b/lib/decidim/decidim_awesome/engine.rb index d5346bee2..d7339a1be 100644 --- a/lib/decidim/decidim_awesome/engine.rb +++ b/lib/decidim/decidim_awesome/engine.rb @@ -25,11 +25,9 @@ class Engine < ::Rails::Engine config.to_prepare do # activate Decidim LayoutHelper for the overriden views ActiveSupport.on_load :action_controller do - helper Decidim::LayoutHelper if respond_to?(:helper) + helper Decidim::DecidimAwesome::AwesomeHelpers end - # Include additional helpers globally - ActiveSupport.on_load(:action_view) { include Decidim::DecidimAwesome::AwesomeHelpers } - # Also for cells + # # Also for cells Decidim::ViewModel.include(Decidim::DecidimAwesome::AwesomeHelpers) # Override EtiquetteValidator diff --git a/lib/decidim/decidim_awesome/organization_memoizer.rb b/lib/decidim/decidim_awesome/organization_memoizer.rb new file mode 100644 index 000000000..c238df106 --- /dev/null +++ b/lib/decidim/decidim_awesome/organization_memoizer.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Decidim + # add a global helper with awesome configuration + module DecidimAwesome + module OrganizationMemoizer + def self.memoize(key) + @memoized ||= {} + @memoized[key] ||= yield + end + + # memoize a piece of code in the class instead of the instance (helper are initialized for each view) + # only works if request.env["decidim.current_organization"] is defined + def memoize(key, &) + return yield unless request.env["decidim.current_organization"]&.id + + OrganizationMemoizer.memoize("#{request.env["decidim.current_organization"].id}-#{key}", &) + end + end + end +end