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