FEATURE: add local onebox handler for /docs urls (#145)
This commit is contained in:
parent
8180b9cfb7
commit
025bf46f8d
|
@ -47,7 +47,7 @@ module Docs
|
|||
end
|
||||
|
||||
def get_topic(topic, current_user)
|
||||
return nil unless topic_in_docs(topic.category_id, topic.tags)
|
||||
return nil unless Docs.topic_in_docs(topic.category_id, topic.tags)
|
||||
|
||||
topic_view = TopicView.new(topic.id, current_user)
|
||||
guardian = Guardian.new(current_user)
|
||||
|
@ -73,13 +73,5 @@ module Docs
|
|||
end
|
||||
title
|
||||
end
|
||||
|
||||
def topic_in_docs(category, tags)
|
||||
category_match = Docs::Query.categories.include?(category.to_s)
|
||||
tags = tags.pluck(:name)
|
||||
tag_match = Docs::Query.tags.any? { |tag| tags.include?(tag) }
|
||||
|
||||
category_match || tag_match
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,4 +11,21 @@ module ::Docs
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.onebox_template
|
||||
@onebox_template ||=
|
||||
begin
|
||||
path =
|
||||
"#{Rails.root}/plugins/discourse-docs/lib/onebox/templates/discourse_docs_list.mustache"
|
||||
File.read(path)
|
||||
end
|
||||
end
|
||||
|
||||
def self.topic_in_docs(category, tags)
|
||||
category_match = Docs::Query.categories.include?(category.to_s)
|
||||
tags = tags.pluck(:name)
|
||||
tag_match = Docs::Query.tags.any? { |tag| tags.include?(tag) }
|
||||
|
||||
category_match || tag_match
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<aside class="onebox docs-onebox">
|
||||
<article class="onebox-body docs-onebox-body">
|
||||
<h3>
|
||||
<a href="{{url}}">{{{name}}}</a>
|
||||
</h3>
|
||||
</article>
|
||||
</aside>
|
48
plugin.rb
48
plugin.rb
|
@ -50,6 +50,54 @@ after_initialize do
|
|||
end
|
||||
end
|
||||
|
||||
if Oneboxer.respond_to?(:register_local_handler)
|
||||
Oneboxer.register_local_handler("docs/docs") do |url, route|
|
||||
uri = URI(url)
|
||||
query = URI.decode_www_form(uri.query).to_h if uri.query
|
||||
|
||||
if query && query["topic"]
|
||||
topic = Topic.includes(:tags).find_by(id: query["topic"])
|
||||
if Docs.topic_in_docs(topic.category_id, topic.tags) && Guardian.new.can_see_topic?(topic)
|
||||
first_post = topic.ordered_posts.first
|
||||
args = {
|
||||
topic_id: topic.id,
|
||||
post_number: first_post.post_number,
|
||||
avatar: PrettyText.avatar_img(first_post.user.avatar_template_url, "tiny"),
|
||||
original_url: url,
|
||||
title: PrettyText.unescape_emoji(CGI.escapeHTML(topic.title)),
|
||||
category_html: CategoryBadge.html_for(topic.category),
|
||||
quote:
|
||||
PrettyText.unescape_emoji(
|
||||
first_post.excerpt(SiteSetting.post_onebox_maxlength, keep_svg: true),
|
||||
),
|
||||
}
|
||||
|
||||
template = Oneboxer.template("discourse_topic_onebox")
|
||||
Mustache.render(template, args)
|
||||
end
|
||||
else
|
||||
args = { url: url, name: I18n.t("js.docs.title") }
|
||||
Mustache.render(Docs.onebox_template, args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if InlineOneboxer.respond_to?(:register_local_handler)
|
||||
InlineOneboxer.register_local_handler("docs/docs") do |url, route|
|
||||
uri = URI(url)
|
||||
query = URI.decode_www_form(uri.query).to_h if uri.query
|
||||
|
||||
if query && query["topic"]
|
||||
topic = Topic.includes(:tags).find_by(id: query["topic"])
|
||||
if Docs.topic_in_docs(topic.category_id, topic.tags) && Guardian.new.can_see_topic?(topic)
|
||||
{ url: url, title: topic.title }
|
||||
end
|
||||
else
|
||||
{ url: url, title: I18n.t("js.docs.title") }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
add_to_class(:topic_query, :list_docs_topics) { default_results(@options) }
|
||||
|
||||
on(:robots_info) do |robots_info|
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
describe Docs do
|
||||
fab!(:category) { Fabricate(:category) }
|
||||
fab!(:topic) { Fabricate(:topic, category: category) }
|
||||
fab!(:post) { Fabricate(:post, topic: topic) }
|
||||
fab!(:non_docs_category) { Fabricate(:category) }
|
||||
fab!(:non_docs_topic) { Fabricate(:topic, category: non_docs_category) }
|
||||
fab!(:non_docs_post) { Fabricate(:post, topic: non_docs_topic) }
|
||||
|
||||
before do
|
||||
SiteSetting.docs_enabled = true
|
||||
SiteSetting.docs_categories = category.id.to_s
|
||||
GlobalSetting.stubs(:docs_path).returns("docs")
|
||||
end
|
||||
|
||||
describe "docs oneboxes" do
|
||||
let(:docs_list_url) { "#{Discourse.base_url}/#{GlobalSetting.docs_path}" }
|
||||
let(:docs_topic_url) { "#{Discourse.base_url}/#{GlobalSetting.docs_path}?topic=#{topic.id}" }
|
||||
let(:non_docs_topic_url) do
|
||||
"#{Discourse.base_url}/#{GlobalSetting.docs_path}?topic=#{non_docs_topic.id}"
|
||||
end
|
||||
|
||||
context "when inline" do
|
||||
it "renders docs list" do
|
||||
results = InlineOneboxer.new([docs_list_url], skip_cache: true).process
|
||||
expect(results).to be_present
|
||||
expect(results[0][:url]).to eq(docs_list_url)
|
||||
expect(results[0][:title]).to eq(I18n.t("js.docs.title"))
|
||||
end
|
||||
|
||||
it "renders docs topic" do
|
||||
results = InlineOneboxer.new([docs_topic_url], skip_cache: true).process
|
||||
expect(results).to be_present
|
||||
expect(results[0][:url]).to eq(docs_topic_url)
|
||||
expect(results[0][:title]).to eq(topic.title)
|
||||
end
|
||||
|
||||
it "does not render topic if not in docs" do
|
||||
results = InlineOneboxer.new([non_docs_topic_url], skip_cache: true).process
|
||||
expect(results).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context "when regular" do
|
||||
it "renders docs list" do
|
||||
onebox = Oneboxer.preview(docs_list_url)
|
||||
expect(onebox).to match_html <<~HTML
|
||||
<aside class="onebox docs-onebox">
|
||||
<article class="onebox-body docs-onebox-body">
|
||||
<h3>
|
||||
<a href="#{docs_list_url}">#{I18n.t("js.docs.title")}</a>
|
||||
</h3>
|
||||
</article>
|
||||
</aside>
|
||||
HTML
|
||||
end
|
||||
|
||||
it "renders docs topic" do
|
||||
onebox = Oneboxer.preview(docs_topic_url)
|
||||
expect(onebox).to include(%{data-topic="#{topic.id}">})
|
||||
expect(onebox).to include(PrettyText.avatar_img(post.user.avatar_template_url, "tiny"))
|
||||
expect(onebox).to include(%{<a href="#{docs_topic_url}">#{topic.title}</a>})
|
||||
expect(onebox).to include(post.excerpt)
|
||||
end
|
||||
|
||||
it "does not onebox topic if not in docs" do
|
||||
onebox = Oneboxer.preview(non_docs_topic_url)
|
||||
expect(onebox).to eq(%{<a href='#{non_docs_topic_url}'>#{non_docs_topic_url}</a>})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue