diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 846ffc2c5fc..e625b8e2c2b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -717,12 +717,21 @@ class ApplicationController < ActionController::Base layout = 'application' if layout == 'no_ember' end - category_topic_ids = Category.pluck(:topic_id).compact + if !SiteSetting.login_required? || current_user + key = "page_not_found_topics" + if @topics_partial = $redis.get(key) + @topics_partial = @topics_partial.html_safe + else + category_topic_ids = Category.pluck(:topic_id).compact + @top_viewed = TopicQuery.new(nil, except_topic_ids: category_topic_ids).list_top_for("monthly").topics.first(10) + @recent = Topic.includes(:category).where.not(id: category_topic_ids).recent(10) + @topics_partial = render_to_string partial: '/exceptions/not_found_topics' + $redis.setex(key, 10.minutes, @topics_partial) + end + end + @container_class = "wrap not-found-container" - @top_viewed = TopicQuery.new(nil, except_topic_ids: category_topic_ids).list_top_for("monthly").topics.first(10) - @recent = Topic.includes(:category).where.not(id: category_topic_ids).recent(10) - @slug = params[:slug].class == String ? params[:slug] : '' - @slug = (params[:id].class == String ? params[:id] : '') if @slug.blank? + @slug = params[:slug].presence || params[:id].presence || "" @slug.tr!('-', ' ') @hide_search = true if SiteSetting.login_required render_to_string status: status, layout: layout, formats: [:html], template: '/exceptions/not_found' diff --git a/app/views/exceptions/_not_found_topics.html.erb b/app/views/exceptions/_not_found_topics.html.erb new file mode 100644 index 00000000000..59cf088c33e --- /dev/null +++ b/app/views/exceptions/_not_found_topics.html.erb @@ -0,0 +1,20 @@ +
+ +
+

<%= t 'page_not_found.recent_topics' %>

+ <% @recent.each do |t| %> +
+ <%= link_to t.title, t.relative_url %><%= category_badge(t.category) %> +
+ <% end %> + " class="btn btn-default"><%= t 'page_not_found.see_more' %>… +
+
diff --git a/app/views/exceptions/not_found.html.erb b/app/views/exceptions/not_found.html.erb index e787e78dcd2..a1173a8feb1 100644 --- a/app/views/exceptions/not_found.html.erb +++ b/app/views/exceptions/not_found.html.erb @@ -2,28 +2,7 @@ <%= build_plugin_html 'server:not-found-before-topics' %> -<% unless SiteSetting.login_required? && current_user.nil? %> -
- -
-

<%= t 'page_not_found.recent_topics' %>

- <% @recent.each do |t| %> -
- <%= link_to t.title, t.relative_url %><%= category_badge(t.category) %> -
- <% end %> - " class="btn btn-default"><%= t 'page_not_found.see_more' %>… -
-
-<% end %> +<%= @topics_partial %> <%- unless @hide_search%>
diff --git a/spec/requests/application_controller_spec.rb b/spec/requests/application_controller_spec.rb index 0e9f2510ca5..d2d63ab0102 100644 --- a/spec/requests/application_controller_spec.rb +++ b/spec/requests/application_controller_spec.rb @@ -143,6 +143,21 @@ RSpec.describe ApplicationController do expect(response.status).to eq(404) expect(response.body).to_not include('google.com/search') end + + it 'should cache results' do + $redis.del("page_not_found_topics") + + topic1 = Fabricate(:topic) + get '/t/nope-nope/99999999' + expect(response.status).to eq(404) + expect(response.body).to include(topic1.title) + + topic2 = Fabricate(:topic) + get '/t/nope-nope/99999999' + expect(response.status).to eq(404) + expect(response.body).to include(topic1.title) + expect(response.body).to_not include(topic2.title) + end end end