FEATURE: Allow to modify topic-backed static pages (#15324)
A plugin API that allows customizing existing topic-backed static pages, like: faq, tos, privacy (see: StaticController) The block passed to this method has to return a SiteSetting name that contains a topic id. ``` add_topic_static_page("faq") do |controller| current_user&.locale == "pl" ? "polish_faq_topic_id" : "faq_topic_id" end ``` You can also add new pages in a plugin, but remember to add a route, for example: ``` get "contact" => "static#show", id: "contact" ```
This commit is contained in:
parent
ad4faf637c
commit
2a4df93b8e
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class StaticController < ApplicationController
|
||||
|
||||
skip_before_action :check_xhr, :redirect_to_login_if_required
|
||||
skip_before_action :verify_authenticity_token, only: [:brotli_asset, :cdn_asset, :enter, :favicon, :service_worker_asset]
|
||||
skip_before_action :preload_json, only: [:brotli_asset, :cdn_asset, :enter, :favicon, :service_worker_asset]
|
||||
|
@ -11,24 +10,26 @@ class StaticController < ApplicationController
|
|||
|
||||
PAGES_WITH_EMAIL_PARAM = ['login', 'password_reset', 'signup']
|
||||
MODAL_PAGES = ['password_reset', 'signup']
|
||||
DEFAULT_PAGES = {
|
||||
"faq" => { redirect: "faq_url", topic_id: "guidelines_topic_id" },
|
||||
"tos" => { redirect: "tos_url", topic_id: "tos_topic_id" },
|
||||
"privacy" => { redirect: "privacy_policy_url", topic_id: "privacy_topic_id" },
|
||||
}
|
||||
CUSTOM_PAGES = {} # Add via `#add_topic_static_page` in plugin API
|
||||
|
||||
def show
|
||||
return redirect_to(path '/') if current_user && (params[:id] == 'login' || params[:id] == 'signup')
|
||||
|
||||
if SiteSetting.login_required? && current_user.nil? && ['faq', 'guidelines'].include?(params[:id])
|
||||
return redirect_to path('/login')
|
||||
end
|
||||
|
||||
map = {
|
||||
"faq" => { redirect: "faq_url", topic_id: "guidelines_topic_id" },
|
||||
"tos" => { redirect: "tos_url", topic_id: "tos_topic_id" },
|
||||
"privacy" => { redirect: "privacy_policy_url", topic_id: "privacy_topic_id" }
|
||||
}
|
||||
|
||||
map = DEFAULT_PAGES.deep_merge(CUSTOM_PAGES)
|
||||
@page = params[:id]
|
||||
|
||||
if map.has_key?(@page)
|
||||
site_setting_key = map[@page][:redirect]
|
||||
url = SiteSetting.get(site_setting_key)
|
||||
url = SiteSetting.get(site_setting_key) if site_setting_key
|
||||
return redirect_to(url) if url.present?
|
||||
end
|
||||
|
||||
|
@ -39,8 +40,12 @@ class StaticController < ApplicationController
|
|||
@page = @page.gsub(/[^a-z0-9\_\-]/, '')
|
||||
|
||||
if map.has_key?(@page)
|
||||
@topic = Topic.find_by_id(SiteSetting.get(map[@page][:topic_id]))
|
||||
topic_id = map[@page][:topic_id]
|
||||
topic_id = instance_exec(&topic_id) if topic_id.is_a?(Proc)
|
||||
|
||||
@topic = Topic.find_by_id(SiteSetting.get(topic_id))
|
||||
raise Discourse::NotFound unless @topic
|
||||
|
||||
title_prefix = if I18n.exists?("js.#{@page}")
|
||||
I18n.t("js.#{@page}")
|
||||
else
|
||||
|
@ -48,17 +53,16 @@ class StaticController < ApplicationController
|
|||
end
|
||||
@title = "#{title_prefix} - #{SiteSetting.title}"
|
||||
@body = @topic.posts.first.cooked
|
||||
@faq_overriden = !SiteSetting.faq_url.blank?
|
||||
@faq_overridden = !SiteSetting.faq_url.blank?
|
||||
|
||||
render :show, layout: !request.xhr?, formats: [:html]
|
||||
return
|
||||
end
|
||||
|
||||
unless @title.present?
|
||||
@title = if SiteSetting.short_site_description.present?
|
||||
"#{SiteSetting.title} - #{SiteSetting.short_site_description}"
|
||||
else
|
||||
SiteSetting.title
|
||||
end
|
||||
@title = SiteSetting.title
|
||||
|
||||
if SiteSetting.short_site_description.present?
|
||||
@title << " - #{SiteSetting.short_site_description}"
|
||||
end
|
||||
|
||||
if I18n.exists?("static.#{@page}")
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<ul class='nav-pills' role='navigation' itemscope itemtype='http://schema.org/SiteNavigationElement'>
|
||||
<% unless SiteSetting.login_required? && current_user.nil? %>
|
||||
<li class="nav-item-about"><%= link_to t('js.about.simple_title'), about_index_path %></a></li>
|
||||
<% if @faq_overriden %>
|
||||
<% if @faq_overridden %>
|
||||
<li class='nav-item-guidelines'><a class='<%= @page == 'faq' ? 'active' : '' %>' href='<%= guidelines_path %>'><%= t 'js.guidelines' %></a></li>
|
||||
<li class='nav-item-faq'><a href='<%= faq_path %>'><%= t 'js.faq' %></a></li>
|
||||
<% else %>
|
||||
|
|
|
@ -994,6 +994,22 @@ class Plugin::Instance
|
|||
DiscoursePluginRegistry.register_notification_consolidation_plan(plan, self)
|
||||
end
|
||||
|
||||
# Allows customizing existing topic-backed static pages, like:
|
||||
# faq, tos, privacy (see: StaticController) The block passed to this
|
||||
# method has to return a SiteSetting name that contains a topic id.
|
||||
#
|
||||
# add_topic_static_page("faq") do |controller|
|
||||
# current_user&.locale == "pl" ? "polish_faq_topic_id" : "faq_topic_id"
|
||||
# end
|
||||
#
|
||||
# You can also add new pages in a plugin, but remember to add a route,
|
||||
# for example:
|
||||
#
|
||||
# get "contact" => "static#show", id: "contact"
|
||||
def add_topic_static_page(page, options = {}, &blk)
|
||||
StaticController::CUSTOM_PAGES[page] = blk ? { topic_id: blk } : options
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def self.js_path
|
||||
|
|
|
@ -277,6 +277,52 @@ describe StaticController do
|
|||
expect(response.body).to include("<title>FAQ - Discourse</title>")
|
||||
end
|
||||
end
|
||||
|
||||
context "plugin api extensions" do
|
||||
after do
|
||||
Rails.application.reload_routes!
|
||||
StaticController::CUSTOM_PAGES.clear
|
||||
end
|
||||
|
||||
it "adds new topic-backed pages" do
|
||||
routes = Proc.new do
|
||||
get "contact" => "static#show", id: "contact"
|
||||
end
|
||||
Discourse::Application.routes.send(:eval_block, routes)
|
||||
|
||||
topic_id = Fabricate(:post, cooked: "contact info").topic_id
|
||||
SiteSetting.setting(:contact_topic_id, topic_id)
|
||||
|
||||
Plugin::Instance.new.add_topic_static_page("contact", topic_id: "contact_topic_id")
|
||||
|
||||
get "/contact"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.body).to include("contact info")
|
||||
end
|
||||
|
||||
it "replaces existing topic-backed pages" do
|
||||
topic_id = Fabricate(:post, cooked: "Regular FAQ").topic_id
|
||||
SiteSetting.setting(:faq_topic_id, topic_id)
|
||||
polish_topic_id = Fabricate(:post, cooked: "Polish FAQ").topic_id
|
||||
SiteSetting.setting(:polish_faq_topic_id, polish_topic_id)
|
||||
|
||||
Plugin::Instance.new.add_topic_static_page("faq") do
|
||||
current_user&.locale == "pl" ? "polish_faq_topic_id" : "faq_topic_id"
|
||||
end
|
||||
|
||||
get "/faq"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.body).to include("Regular FAQ")
|
||||
|
||||
sign_in(Fabricate(:user, locale: "pl"))
|
||||
get "/faq"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.body).to include("Polish FAQ")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#enter' do
|
||||
|
|
Loading…
Reference in New Issue