FEATURE: Add onebox metadata (#10)

Currently linking directly to Knowledge Explorer topics shows a generic onebox, which isn't super helpful in some cases.

This commit mimics how the theme creator plugin handles adding metadata to special occurrences. However, to get this to work, how the plugin handles showing topic contents needed to be refactored. Instead of hitting the existing topic route, the plugin implements its own version of this, including adding restrictions for topics that are not in a selected Knowledge Explorer category or tag.
This commit is contained in:
Justin DiRose 2020-10-01 09:32:28 -05:00 committed by GitHub
parent 2c12f977ca
commit 0e1c7c7216
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 111 additions and 37 deletions

7
Gemfile Normal file
View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
source 'https://rubygems.org'
group :development do
gem 'rubocop-discourse'
end

37
Gemfile.lock Normal file
View File

@ -0,0 +1,37 @@
GEM
remote: https://rubygems.org/
specs:
ast (2.4.1)
parallel (1.19.2)
parser (2.7.1.5)
ast (~> 2.4.1)
rainbow (3.0.0)
regexp_parser (1.8.1)
rexml (3.2.4)
rubocop (0.92.0)
parallel (~> 1.10)
parser (>= 2.7.1.5)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.7)
rexml
rubocop-ast (>= 0.5.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.7.1)
parser (>= 2.7.1.5)
rubocop-discourse (2.3.2)
rubocop (>= 0.69.0)
rubocop-rspec (>= 1.39.0)
rubocop-rspec (1.43.2)
rubocop (~> 0.87)
ruby-progressbar (1.10.1)
unicode-display_width (1.7.0)
PLATFORMS
ruby
DEPENDENCIES
rubocop-discourse
BUNDLED WITH
2.1.4

View File

@ -4,8 +4,11 @@ module KnowledgeExplorer
class KnowledgeExplorerController < ApplicationController
requires_plugin 'knowledge-explorer'
skip_before_action :check_xhr, only: [:index]
def index
filters = {
topic: params[:topic],
tags: params[:tags],
category: params[:category],
solved: params[:solved],
@ -16,8 +19,34 @@ module KnowledgeExplorer
}
query = KnowledgeExplorer::Query.new(current_user, filters).list
query["topic"] = get_topic(filters[:topic], current_user) if filters[:topic].present?
respond_to do |format|
format.html do
render :get_topic if filters[:topic].present?
end
format.json do
render json: query
end
end
end
def get_topic(topic_id, current_user)
@topic_view = TopicView.new(topic_id, current_user)
guardian = Guardian.new(current_user)
return unless topic_in_explorer(@topic_view.topic.category_id, @topic_view.topic.tags)
TopicViewSerializer.new(@topic_view, scope: guardian, root: false)
end
def topic_in_explorer(category, tags)
category_match = KnowledgeExplorer::Query.categories.include?(category.to_s)
tag_match = KnowledgeExplorer::Query.tags.any? { |tag| tags.include?(tag) }
category_match || tag_match
end
end
end

View File

@ -0,0 +1,3 @@
<% content_for :head do %>
<%= raw crawlable_meta_data(title: @topic_view.topic.title, description: @topic_view.topic.excerpt) %>
<% end %>

View File

@ -1,6 +1,5 @@
import discourseComputed from "discourse-common/utils/decorators";
import Category from "discourse/models/category";
import Topic from "discourse/models/topic";
import { on } from "discourse-common/utils/decorators";
import KnowledgeExplorer from "discourse/plugins/discourse-knowledge-explorer/discourse/models/knowledge-explorer";
import { getOwner } from "@ember/application";
@ -107,19 +106,11 @@ export default Ember.Controller.extend({
actions: {
setSelectedTopic(topicId) {
this.setProperties({
isTopicLoading: true,
selectedTopic: topicId,
});
this.set("selectedTopic", topicId);
window.scrollTo(0, 0);
KnowledgeExplorer.getTopic(topicId).then((result) => {
this.setProperties({
topic: Topic.create(result),
isTopicLoading: false,
});
});
this.send("refreshModel");
},
onChangeFilterSolved(solvedFilter) {
@ -225,13 +216,15 @@ export default Ember.Controller.extend({
"filterSolved",
"searchTerm",
"ascending",
"orderColumn"
"orderColumn",
"selectedTopic"
);
KnowledgeExplorer.list(params).then((result) => {
result = mergeCategories(result);
this.setProperties({
model: result,
topic: result.topic,
isLoading: false,
});
});

View File

@ -1,10 +1,6 @@
import { ajax } from "discourse/lib/ajax";
import Topic from "discourse/models/topic";
function getTopic(id) {
return ajax(`/t/${id}.json?ke=true`);
}
export default {
list(params) {
let filters = [];
@ -29,17 +25,12 @@ export default {
if (params.page) {
filters.push(`page=${params.page}`);
}
if (params.selectedTopic) {
filters.push(`topic=${params.selectedTopic}`);
}
let promise = ajax(`/docs.json?${filters.join("&")}`);
if (params.selectedTopic) {
promise = promise.then((data) => {
return getTopic(params.selectedTopic).then((topic) => {
data.topic = Topic.create(topic);
return data;
});
});
} else {
promise = promise.then((data) => {
data.topics.topic_list.topics = data.topics.topic_list.topics.map(
(topic) => {
@ -47,9 +38,9 @@ export default {
return topic;
}
);
data.topic = Topic.create(data.topic);
return data;
});
}
return promise;
},
@ -69,6 +60,4 @@ export default {
return promise;
},
getTopic,
};

View File

@ -139,5 +139,21 @@ describe KnowledgeExplorer::KnowledgeExplorerController do
end
end
context 'when getting topic first post contents' do
let!(:non_ke_topic) { Fabricate(:topic) }
it 'should correctly grab the topic' do
get "/docs.json?topic=#{topic.id}"
expect(response.parsed_body['topic']['id']).to eq(topic.id)
end
it 'should get topics matching a selected knowledge explorer tag or category' do
get "/docs.json?topic=#{non_ke_topic.id}"
expect(response.parsed_body['topic']).to be_blank
end
end
end
end