diff --git a/app/controllers/manifest_json_controller.rb b/app/controllers/metadata_controller.rb similarity index 74% rename from app/controllers/manifest_json_controller.rb rename to app/controllers/metadata_controller.rb index 8c7b6bc42..f5b8beccc 100644 --- a/app/controllers/manifest_json_controller.rb +++ b/app/controllers/metadata_controller.rb @@ -1,8 +1,8 @@ -class ManifestJsonController < ApplicationController +class MetadataController < ApplicationController layout false skip_before_filter :preload_json, :check_xhr, :redirect_to_login_if_required - def index + def manifest manifest = { short_name: SiteSetting.title, display: 'standalone', @@ -14,4 +14,8 @@ class ManifestJsonController < ApplicationController render json: manifest.to_json end + + def opensearch + render file: "#{Rails.root}/app/views/metadata/opensearch.xml" + end end diff --git a/app/controllers/site_controller.rb b/app/controllers/site_controller.rb index 6597e7e76..f73a568f0 100644 --- a/app/controllers/site_controller.rb +++ b/app/controllers/site_controller.rb @@ -1,8 +1,8 @@ require_dependency 'site_serializer' class SiteController < ApplicationController - - skip_before_filter :preload_json + layout false + skip_before_filter :preload_json, :check_xhr def site render json: Site.json_for(guardian) @@ -23,5 +23,4 @@ class SiteController < ApplicationController def emoji render json: custom_emoji end - end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 16b86ab26..5a4ec12e5 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -157,6 +157,20 @@ module ApplicationHelper result.join("\n") end + def render_sitelinks_search_tag + json = { + '@context': 'http://schema.org', + '@type': 'WebSite', + url: Discourse.base_url, + potentialAction: { + '@type': 'SearchAction', + target: "#{Discourse.base_url}/search?q={search_term_string}", + 'query-input': 'required name=search_term_string', + } + } + content_tag(:script, MultiJson.dump(json).html_safe, type: 'application/ld+json'.freeze) + end + def application_logo_url @application_logo_url ||= (mobile_view? && SiteSetting.mobile_logo_url) || SiteSetting.logo_url end diff --git a/app/views/layouts/_head.html.erb b/app/views/layouts/_head.html.erb index 0843f7133..6a5ab0ee6 100644 --- a/app/views/layouts/_head.html.erb +++ b/app/views/layouts/_head.html.erb @@ -12,3 +12,5 @@ <%= canonical_link_tag %> +<%= render_sitelinks_search_tag %> + diff --git a/app/views/metadata/opensearch.xml.erb b/app/views/metadata/opensearch.xml.erb new file mode 100644 index 000000000..ff47bada5 --- /dev/null +++ b/app/views/metadata/opensearch.xml.erb @@ -0,0 +1,12 @@ + +<%= SiteSetting.title %> Search +Search for posts on <%= SiteSetting.title %> +discourse forum +<% if SiteSetting.favicon_url =~ /\.ico$/ -%> + <%= UrlHelper.absolute SiteSetting.favicon_url %> +<%- else -%> + <%= UrlHelper.absolute SiteSetting.favicon_url %> +<%- end %> + + + diff --git a/config/routes.rb b/config/routes.rb index 2c36cd1a6..69a57eff7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -603,7 +603,8 @@ Discourse::Application.routes.draw do get "favicon/proxied" => "static#favicon", format: false get "robots.txt" => "robots_txt#index" - get "manifest.json" => "manifest_json#index", as: :manifest + get "manifest.json" => "metadata#manifest", as: :manifest + get "opensearch" => "metadata#opensearch", format: :xml Discourse.filters.each do |filter| root to: "list##{filter}", constraints: HomePageConstraint.new("#{filter}"), :as => "list_#{filter}" diff --git a/spec/controllers/manifest_json_controller_spec.rb b/spec/controllers/manifest_json_controller_spec.rb deleted file mode 100644 index d0fd39e83..000000000 --- a/spec/controllers/manifest_json_controller_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'rails_helper' - -RSpec.describe ManifestJsonController do - context 'index' do - it 'returns the right output' do - title = 'MyApp' - SiteSetting.title = title - get :index - expect(response.body).to include(title) - end - end -end diff --git a/spec/controllers/metadata_controller_spec.rb b/spec/controllers/metadata_controller_spec.rb new file mode 100644 index 000000000..681cbe072 --- /dev/null +++ b/spec/controllers/metadata_controller_spec.rb @@ -0,0 +1,28 @@ +require 'rails_helper' + +RSpec.describe MetadataController do + describe 'manifest.json' do + it 'returns the right output' do + title = 'MyApp' + SiteSetting.title = title + get :manifest + expect(response.body).to include(title) + expect(response.content_type).to eq('application/json') + end + end + + describe 'opensearch.xml' do + it 'returns the right output' do + title = 'MyApp' + favicon_path = '/uploads/something/23432.png' + SiteSetting.title = title + SiteSetting.favicon_url = favicon_path + get :opensearch, format: :xml + expect(response.body).to include(title) + expect(response.body).to include("/search?q={searchTerms}") + expect(response.body).to include('image/png') + expect(response.body).to include(favicon_path) + expect(response.content_type).to eq('application/xml') + end + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 30921a6e3..354cb630d 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -78,6 +78,13 @@ Spork.prefork do SiteSetting.defaults[k] = v end + # Monkey patch for NoMethodError: undefined method `cache' for nil:NilClass + # https://github.com/rspec/rspec-rails/issues/1532#issuecomment-174679485 + # fixed in Rspec 3.4.1 + RSpec::Rails::ViewRendering::EmptyTemplatePathSetDecorator.class_eval do + alias_method :find_all_anywhere, :find_all + end + require_dependency 'site_settings/local_process_provider' SiteSetting.provider = SiteSettings::LocalProcessProvider.new end