diff --git a/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb b/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb
new file mode 100644
index 000000000..61c444559
--- /dev/null
+++ b/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb
@@ -0,0 +1,11 @@
+module PageflowScrolled
+ # @api private
+ module CacheHelper
+ def cache_scrolled_entry(entry: nil, widget_scope: :unknown, &block)
+ condition =
+ widget_scope == :published &&
+ entry.feature_state('scrolled_entry_fragment_caching')
+ cache_if(condition, [entry, :head_and_body, widget_scope], &block)
+ end
+ end
+end
diff --git a/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb b/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb
index cc69b5dc3..403f8e3f6 100644
--- a/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb
+++ b/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb
@@ -7,6 +7,7 @@ module SeedHtmlHelper
include Pageflow::WidgetsHelper
include Pageflow::StructuredDataHelper
include Pageflow::TextDirectionHelper
+ include PageflowScrolled::CacheHelper
include FaviconHelper
include PacksHelper
include WebpackPublicPathHelper
diff --git a/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb b/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb
index 236b38aa9..6b19f34bc 100644
--- a/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb
+++ b/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb
@@ -1,59 +1,61 @@
-
-<%= content_tag(:html, lang: @entry.locale, dir: text_direction(@entry.locale)) do %>
-
- <%= pretty_entry_title(@entry) %>
+<%= cache_scrolled_entry(entry: @entry, widget_scope: @widget_scope) do %>
+
+ <%= content_tag(:html, lang: @entry.locale, dir: text_direction(@entry.locale)) do %>
+
+ <%= pretty_entry_title(@entry) %>
-
-
+
+
- <%= social_share_meta_tags_for(@entry) %>
- <%= meta_tags_for_entry(@entry) %>
- <%= feed_link_tags_for_entry(@entry) unless @skip_feed_link_tags%>
+ <%= social_share_meta_tags_for(@entry) %>
+ <%= meta_tags_for_entry(@entry) %>
+ <%= feed_link_tags_for_entry(@entry) unless @skip_feed_link_tags%>
- <%= scrolled_favicons_for_entry(@entry, entry_mode: @widget_scope) %>
+ <%= scrolled_favicons_for_entry(@entry, entry_mode: @widget_scope) %>
- <%= javascript_include_tag 'pageflow_scrolled/legacy' %>
- <%= scrolled_frontend_stylesheet_packs_tag(@entry, widget_scope: @widget_scope) %>
+ <%= javascript_include_tag 'pageflow_scrolled/legacy' %>
+ <%= scrolled_frontend_stylesheet_packs_tag(@entry, widget_scope: @widget_scope) %>
- <%= scrolled_theme_properties_style_tag(@entry.theme) %>
- <%= scrolled_theme_stylesheet_pack_tags(@entry.theme) %>
+ <%= scrolled_theme_properties_style_tag(@entry.theme) %>
+ <%= scrolled_theme_stylesheet_pack_tags(@entry.theme) %>
- <%= render_widget_head_fragments(@entry, scope: @widget_scope) %>
+ <%= render_widget_head_fragments(@entry, scope: @widget_scope) %>
- <% if Rails.env.development? %>
-
- <% end %>
+
+ <% end %>
- <% ssr_html = @skip_ssr ? '' : render_scrolled_entry(@entry) %>
+ <% ssr_html = @skip_ssr ? '' : render_scrolled_entry(@entry) %>
- <% if !@skip_ssr && (params[:frontend] == 'v2' || @entry.feature_state('frontend_v2')) %>
- <%= generated_media_queries_tags_for(ssr_html) %>
- <% end %>
-
-
- <%= structured_data_for_entry(@entry) unless @skip_structured_data %>
+ <% if !@skip_ssr && (params[:frontend] == 'v2' || @entry.feature_state('frontend_v2')) %>
+ <%= generated_media_queries_tags_for(ssr_html) %>
+ <% end %>
+
+
+ <%= structured_data_for_entry(@entry) unless @skip_structured_data %>
- <%= render 'pageflow_scrolled/entries/global_notices' %>
+ <%= render 'pageflow_scrolled/entries/global_notices' %>
-
- <%= ssr_html %>
+
+ <%= ssr_html %>
-
- <%= render_widgets(@entry, scope: @widget_scope, insert_point: :bottom_of_entry) %>
-
+
+ <%= render_widgets(@entry, scope: @widget_scope, insert_point: :bottom_of_entry) %>
+
- <%= scrolled_webpack_public_path_script_tag %>
- <%= scrolled_frontend_javascript_packs_tag(@entry, widget_scope: @widget_scope) %>
+ <%= scrolled_webpack_public_path_script_tag %>
+ <%= scrolled_frontend_javascript_packs_tag(@entry, widget_scope: @widget_scope) %>
- <%= scrolled_entry_json_seed_script_tag(@entry, @seed_options || {}) %>
-
+ <%= scrolled_entry_json_seed_script_tag(@entry, @seed_options || {}) %>
+
+ <% end %>
<% end %>
diff --git a/entry_types/scrolled/config/locales/new/cache.de.yml b/entry_types/scrolled/config/locales/new/cache.de.yml
new file mode 100644
index 000000000..d14793e2d
--- /dev/null
+++ b/entry_types/scrolled/config/locales/new/cache.de.yml
@@ -0,0 +1,4 @@
+de:
+ pageflow:
+ scrolled_entry_fragment_caching:
+ feature_name: Pageflow-Next-Fragment-Caching
diff --git a/entry_types/scrolled/config/locales/new/cache.en.yml b/entry_types/scrolled/config/locales/new/cache.en.yml
new file mode 100644
index 000000000..f9a27981b
--- /dev/null
+++ b/entry_types/scrolled/config/locales/new/cache.en.yml
@@ -0,0 +1,4 @@
+en:
+ pageflow:
+ scrolled_entry_fragment_caching:
+ feature_name: Pageflow Next Fragment Caching
diff --git a/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb b/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb
index d0057e713..08014b405 100644
--- a/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb
+++ b/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb
@@ -26,6 +26,7 @@ def configure(config)
c.features.register('iframe_embed_content_element')
c.features.register('image_gallery_content_element')
c.features.register('frontend_v2')
+ c.features.register('scrolled_entry_fragment_caching')
c.additional_frontend_seed_data.register(
'frontendVersion',
diff --git a/entry_types/scrolled/spec/helpers/pageflow_scrolled/cache_helper_spec.rb b/entry_types/scrolled/spec/helpers/pageflow_scrolled/cache_helper_spec.rb
new file mode 100644
index 000000000..46b17ddba
--- /dev/null
+++ b/entry_types/scrolled/spec/helpers/pageflow_scrolled/cache_helper_spec.rb
@@ -0,0 +1,66 @@
+require 'spec_helper'
+
+module PageflowScrolled
+ RSpec.describe CacheHelper, type: :helper do
+ describe '#cache_scrolled_entry', :use_clean_rails_memory_store_fragment_caching do
+ it 'caches if feature is enabled and entry is published' do
+ pageflow_configure do |config|
+ config.features.enable_by_default('scrolled_entry_fragment_caching')
+ end
+
+ entry = create(:published_entry)
+
+ result = 'initial value'
+
+ helper.cache_scrolled_entry(entry: entry, widget_scope: :published) { result = 'old value' }
+ helper.cache_scrolled_entry(entry: entry, widget_scope: :published) { result = 'new value' }
+
+ expect(result).to eq('old value')
+ end
+
+ it "doesn't cache if feature is disabled" do
+ entry = create(:published_entry)
+
+ result = 'initial value'
+
+ helper.cache_scrolled_entry(entry: entry, widget_scope: :published) { result = 'old value' }
+ helper.cache_scrolled_entry(entry: entry, widget_scope: :published) { result = 'new value' }
+
+ expect(result).to eq('new value')
+ end
+
+ it "doesn't cache if widget_scope isn't :published" do
+ pageflow_configure do |config|
+ config.features.enable_by_default('scrolled_entry_fragment_caching')
+ end
+ # would typically imply widget scope :published
+ entry = create(:published_entry)
+
+ result = 'initial value'
+
+ helper.cache_scrolled_entry(entry: entry, widget_scope: :editor) { result = 'old value' }
+ helper.cache_scrolled_entry(entry: entry, widget_scope: :editor) { result = 'new value' }
+
+ expect(result).to eq('new value')
+ end
+
+ it 'caches for different values of widget scope' do
+ pageflow_configure do |config|
+ config.features.enable_by_default('scrolled_entry_fragment_caching')
+ end
+ entry = create(:published_entry)
+
+ result = 'initial value'
+ published_result = 'initial value'
+
+ helper.cache_scrolled_entry(entry: entry, widget_scope: :published) { result = 'oldest value', published_result = 'oldest value' }
+ helper.cache_scrolled_entry(entry: entry, widget_scope: :editor) { result = 'old value' }
+ helper.cache_scrolled_entry(entry: entry, widget_scope: :published) { result = 'new value', published_result = 'new value' }
+ helper.cache_scrolled_entry(entry: entry, widget_scope: :editor) { result = 'newest value' }
+
+ expect(result).to eq('newest value')
+ expect(published_result).to eq('oldest value')
+ end
+ end
+ end
+end
diff --git a/entry_types/scrolled/spec/spec_helper.rb b/entry_types/scrolled/spec/spec_helper.rb
index bfda4936e..14c3c6a93 100644
--- a/entry_types/scrolled/spec/spec_helper.rb
+++ b/entry_types/scrolled/spec/spec_helper.rb
@@ -30,4 +30,16 @@
config.expect_with :rspec do |c|
c.syntax = :expect
end
+
+ # Taken from https://gitlab.com/gitlab-org/gitlab-foss
+ config.around(:each, :use_clean_rails_memory_store_fragment_caching) do |example|
+ caching_store = ActionController::Base.cache_store
+ ActionController::Base.cache_store = ActiveSupport::Cache::MemoryStore.new
+ ActionController::Base.perform_caching = true
+
+ example.run
+
+ ActionController::Base.perform_caching = false
+ ActionController::Base.cache_store = caching_store
+ end
end