FEATURE: Use the same structure as core topic-list-item and add topic excerpts to docs index (#140)
* FEATURE: Optionally show topic excerpts in docs index This commit adds a new docs_show_topic_excerpts site setting which, when enabled and used in conjunction either with the always_include_topic_excerpts site setting or the serialize_topic_excerpts theme modifier. For the theme modifier, this commit also fixes an issue with the Docs::Query class. Since we were re-initializing Guardian within the class (rather than using the guardian passed down from the controller), we did not have the request information needed to determine theme_id, which meant that the theme modifier had no effect. We now pass down guardian from the controller instead. In general guardian is almost always better than a user object, since we can always just call guardian.user. Adds a simple system spec as well. --- We now check both the serialize_topic_excerpts theme modifier and the always_include_topic_excerpts site setting server-side within Docs::Query, and use that on the client to determine whether or not to show the excerpts for docs. This is because if someone sets one of those values it's logical to think it will apply everywhere there is a topic list. Also include a system spec to test whether the theme modifier works to show the excerpts. --------- Co-authored-by: Martin Brennan <martin@discourse.org>
This commit is contained in:
parent
ed77e768e6
commit
06f6d00ba1
|
@ -18,7 +18,7 @@ module Docs
|
|||
page: params[:page],
|
||||
}
|
||||
|
||||
query = Docs::Query.new(current_user, filters).list
|
||||
query = Docs::Query.new(guardian, filters).list
|
||||
|
||||
if filters[:topic].present?
|
||||
begin
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import Component from "@ember/component";
|
||||
import { RUNTIME_OPTIONS } from "discourse-common/lib/raw-handlebars-helpers";
|
||||
import { findRawTemplate } from "discourse-common/lib/raw-templates";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
|
||||
export default Component.extend({
|
||||
tagName: "tr",
|
||||
classNameBindings: [":topic-list-item"],
|
||||
|
||||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
this.renderTopicListItem();
|
||||
},
|
||||
|
||||
renderTopicListItem() {
|
||||
const template = findRawTemplate("docs-topic-list-item");
|
||||
if (template) {
|
||||
this.set(
|
||||
"topicListItemContents",
|
||||
htmlSafe(template(this, RUNTIME_OPTIONS))
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
|
@ -48,6 +48,7 @@ export default Controller.extend({
|
|||
categories: readOnly("model.categories"),
|
||||
topics: alias("model.topics.topic_list.topics"),
|
||||
tags: readOnly("model.tags"),
|
||||
showExcerpts: readOnly("model.meta.show_topic_excerpts"),
|
||||
tagGroups: readOnly("model.tag_groups"),
|
||||
topicCount: alias("model.topic_count"),
|
||||
emptyResults: equal("topicCount", 0),
|
||||
|
@ -68,6 +69,7 @@ export default Controller.extend({
|
|||
},
|
||||
});
|
||||
},
|
||||
|
||||
@discourseComputed("categories", "categorySort", "categoryFilter")
|
||||
sortedCategories(categories, categorySort, filter) {
|
||||
let { type, direction } = categorySort;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{{this.topicListItemContents}}
|
|
@ -28,7 +28,11 @@
|
|||
|
||||
<tbody class="topic-list-body">
|
||||
{{#each topics as |topic|}}
|
||||
{{raw "docs-topic-list-item" topic=topic urlPath=urlPath}}
|
||||
{{docs-topic-list-item
|
||||
topic=topic
|
||||
urlPath=urlPath
|
||||
showExcerpt=showExcerpts
|
||||
}}
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -36,7 +36,9 @@
|
|||
{{#if categories}}
|
||||
<div class="docs-items docs-categories">
|
||||
<section class="item-controls">
|
||||
<h3>{{i18n "docs.categories"}}</h3>
|
||||
<h3>
|
||||
{{i18n "docs.categories"}}
|
||||
</h3>
|
||||
<div class="item-controls-buttons">
|
||||
<DButton
|
||||
class={{if
|
||||
|
@ -87,7 +89,9 @@
|
|||
{{#if (and tags shouldShowTags)}}
|
||||
<div class="docs-items docs-tags">
|
||||
<section class="item-controls">
|
||||
<h3>{{i18n "docs.tags"}}</h3>
|
||||
<h3>
|
||||
{{i18n "docs.tags"}}
|
||||
</h3>
|
||||
<div class="item-controls-buttons">
|
||||
<DButton
|
||||
class={{if
|
||||
|
@ -142,7 +146,9 @@
|
|||
{{#if (and tagGroups shouldShowTagsByGroup)}}
|
||||
<div class="docs-items docs-tags">
|
||||
<section class="item-controls">
|
||||
<h3>{{i18n "docs.tags"}}</h3>
|
||||
<h3>
|
||||
{{i18n "docs.tags"}}
|
||||
</h3>
|
||||
<div class="item-controls-buttons">
|
||||
<DButton
|
||||
class={{if
|
||||
|
@ -232,6 +238,7 @@
|
|||
{{#unless emptyResults}}
|
||||
<DocsTopicList
|
||||
@topics={{topics}}
|
||||
@showExcerpts={{showExcerpts}}
|
||||
@ascending={{ascending}}
|
||||
@order={{orderColumn}}
|
||||
@sortBy={{action "sortBy"}}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<tr class="topic-list-item">
|
||||
<td class="main-link topic-list-data">
|
||||
{{~raw-plugin-outlet name="topic-list-before-columns"}}
|
||||
|
||||
<td class="main-link topic-list-data">
|
||||
{{~raw-plugin-outlet name="topic-list-before-link"}}
|
||||
<span class="link-top-line">
|
||||
{{~raw "topic-status" topic=topic}}
|
||||
{{~raw "docs-topic-link" topic=topic urlPath=urlPath}}
|
||||
|
@ -8,8 +10,10 @@
|
|||
{{category-link topic.category}}
|
||||
{{discourse-tags topic mode="list"}}
|
||||
</span>
|
||||
</td>
|
||||
<td class="topic-list-data">
|
||||
{{!-- {{#if showExcerpt}} --}}
|
||||
{{~raw "list/topic-excerpt" topic=topic}}
|
||||
{{!-- {{/if}} --}}
|
||||
</td>
|
||||
<td class="topic-list-data">
|
||||
{{format-date topic.bumped_at format="tiny" noTitle="true"}}
|
||||
</td>
|
||||
</tr>
|
||||
</td>
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
module Docs
|
||||
class Query
|
||||
def initialize(user = nil, filters = {})
|
||||
@user = user
|
||||
def initialize(guardian, filters = {})
|
||||
@guardian = guardian
|
||||
@filters = filters
|
||||
@limit = 30
|
||||
end
|
||||
|
@ -19,7 +19,7 @@ module Docs
|
|||
def list
|
||||
# query for topics matching selected categories & tags
|
||||
opts = { no_definitions: true, limit: false }
|
||||
tq = TopicQuery.new(@user, opts)
|
||||
tq = TopicQuery.new(@guardian.user, opts)
|
||||
results = tq.list_docs_topics
|
||||
results =
|
||||
results.left_outer_joins(SiteSetting.show_tags_by_group ? { tags: :tag_groups } : :tags)
|
||||
|
@ -155,7 +155,7 @@ module Docs
|
|||
# assemble the object
|
||||
topic_query = tq.create_list(:docs, { unordered: true }, results)
|
||||
|
||||
topic_list = TopicListSerializer.new(topic_query, scope: Guardian.new(@user)).as_json
|
||||
topic_list = TopicListSerializer.new(topic_query, scope: @guardian).as_json
|
||||
|
||||
if end_of_list.nil?
|
||||
topic_list["load_more_url"] = load_more_url
|
||||
|
@ -169,6 +169,9 @@ module Docs
|
|||
:categories => categories,
|
||||
:topics => topic_list,
|
||||
:topic_count => results_length,
|
||||
:meta => {
|
||||
show_topic_excerpts: show_topic_excerpts,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -200,7 +203,7 @@ module Docs
|
|||
tags_object << { id: tag[0], count: tag[1], active: active || false }
|
||||
end
|
||||
|
||||
allowed_tags = DiscourseTagging.filter_allowed_tags(Guardian.new(@user)).map(&:name)
|
||||
allowed_tags = DiscourseTagging.filter_allowed_tags(@guardian).map(&:name)
|
||||
|
||||
tags_object = tags_object.select { |tag| allowed_tags.include?(tag[:id]) }
|
||||
|
||||
|
@ -235,5 +238,10 @@ module Docs
|
|||
|
||||
"/#{GlobalSetting.docs_path}.json?#{filters.join("&")}"
|
||||
end
|
||||
|
||||
def show_topic_excerpts
|
||||
SiteSetting.always_include_topic_excerpts ||
|
||||
ThemeModifierHelper.new(request: @guardian.request).serialize_topic_excerpts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe "Discourse Docs | Index", type: :system do
|
||||
fab!(:current_user) { Fabricate(:user) }
|
||||
fab!(:category) { Fabricate(:category) }
|
||||
fab!(:topic_1) { Fabricate(:topic, category: category) }
|
||||
fab!(:topic_2) { Fabricate(:topic, category: category) }
|
||||
fab!(:post_1) { Fabricate(:post, topic: topic_1) }
|
||||
fab!(:post_2) { Fabricate(:post, topic: topic_2) }
|
||||
|
||||
before do
|
||||
SiteSetting.docs_enabled = true
|
||||
SiteSetting.docs_categories = category.id.to_s
|
||||
sign_in(current_user)
|
||||
end
|
||||
|
||||
it "does not error when showing the index" do
|
||||
visit("/docs")
|
||||
expect(page).to have_css(".docs-topic-link", text: topic_1.title)
|
||||
expect(page).to have_css(".docs-topic-link", text: topic_2.title)
|
||||
end
|
||||
|
||||
describe "topic excerpts" do
|
||||
before do
|
||||
topic_1.update_excerpt(post_1.excerpt_for_topic)
|
||||
topic_2.update_excerpt(post_2.excerpt_for_topic)
|
||||
end
|
||||
|
||||
it "does not show the topic excerpts by default" do
|
||||
visit("/docs")
|
||||
expect(page).to have_no_css(".topic-excerpt")
|
||||
end
|
||||
|
||||
context "when docs_show_topic_excerpts is true" do
|
||||
before { SiteSetting.always_include_topic_excerpts = true }
|
||||
|
||||
it "shows the excerpts" do
|
||||
visit("/docs")
|
||||
expect(page).to have_css(".topic-excerpt", text: topic_1.excerpt)
|
||||
expect(page).to have_css(".topic-excerpt", text: topic_2.excerpt)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the theme modifier serialize_topic_excerpts is true" do
|
||||
before do
|
||||
ThemeModifierSet.find_by(theme_id: Theme.first.id).update!(serialize_topic_excerpts: true)
|
||||
Theme.clear_cache!
|
||||
end
|
||||
|
||||
it "shows the excerpts" do
|
||||
visit("/docs")
|
||||
expect(page).to have_css(".topic-excerpt", text: topic_1.excerpt)
|
||||
expect(page).to have_css(".topic-excerpt", text: topic_2.excerpt)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue