mirror of
https://github.com/discourse/discourse.git
synced 2025-01-18 18:12:46 +08:00
FEATURE: ability to register custom filters for posts (#12938)
Allow plugins to extend TopicView to filter posts
This commit is contained in:
parent
f337d59ed9
commit
a4bd1806d9
|
@ -208,6 +208,14 @@ class Plugin::Instance
|
|||
Search.advanced_filter(trigger, &block)
|
||||
end
|
||||
|
||||
# Allows to define TopicView posts filters. Example usage:
|
||||
# TopicView.advanced_filter do |posts, opts|
|
||||
# posts.where(wiki: true)
|
||||
# end
|
||||
def register_topic_view_posts_filter(trigger, &block)
|
||||
TopicView.add_custom_filter(trigger, &block)
|
||||
end
|
||||
|
||||
# Allow to eager load additional tables in Search. Useful to avoid N+1 performance problems.
|
||||
# Example usage:
|
||||
# register_search_topic_eager_load do |opts|
|
||||
|
|
|
@ -51,6 +51,15 @@ class TopicView
|
|||
wpcf.flatten.uniq
|
||||
end
|
||||
|
||||
def self.add_custom_filter(key, &blk)
|
||||
@custom_filters ||= {}
|
||||
@custom_filters[key] = blk
|
||||
end
|
||||
|
||||
def self.custom_filters
|
||||
@custom_filters || {}
|
||||
end
|
||||
|
||||
def initialize(topic_or_topic_id, user = nil, options = {})
|
||||
@topic = find_topic(topic_or_topic_id)
|
||||
@user = user
|
||||
|
@ -772,6 +781,10 @@ class TopicView
|
|||
@contains_gaps = true
|
||||
end
|
||||
|
||||
if @filter.present? && @filter != 'summary' && TopicView.custom_filters[@filter].present?
|
||||
@filtered_posts = TopicView.custom_filters[@filter].call(@filtered_posts, self)
|
||||
end
|
||||
|
||||
if @best.present?
|
||||
@filtered_posts = @filtered_posts.where('posts.post_type = ?', Post.types[:regular])
|
||||
@contains_gaps = true
|
||||
|
|
|
@ -55,6 +55,29 @@ describe TopicView do
|
|||
end
|
||||
end
|
||||
|
||||
context 'custom filters' do
|
||||
fab!(:p0) { Fabricate(:post, topic: topic) }
|
||||
fab!(:p1) { Fabricate(:post, topic: topic, wiki: true) }
|
||||
|
||||
it 'allows to register custom filters' do
|
||||
tv = TopicView.new(topic.id, evil_trout, { filter: 'wiki' })
|
||||
expect(tv.filter_posts({ filter: "wiki" })).to eq([p0, p1])
|
||||
|
||||
TopicView.add_custom_filter("wiki") do |posts, topic_view|
|
||||
posts.where(wiki: true)
|
||||
end
|
||||
|
||||
tv = TopicView.new(topic.id, evil_trout, { filter: 'wiki' })
|
||||
expect(tv.filter_posts).to eq([p1])
|
||||
|
||||
tv = TopicView.new(topic.id, evil_trout, { filter: 'whatever' })
|
||||
expect(tv.filter_posts).to eq([p0, p1])
|
||||
|
||||
ensure
|
||||
TopicView.instance_variable_set(:@custom_filters, [])
|
||||
end
|
||||
end
|
||||
|
||||
context "setup_filtered_posts" do
|
||||
describe "filters posts with ignored users" do
|
||||
fab!(:ignored_user) { Fabricate(:ignored_user, user: evil_trout, ignored_user: user) }
|
||||
|
|
|
@ -2436,6 +2436,29 @@ RSpec.describe TopicsController do
|
|||
expect(body["post_ids"]).to eq([post2.id])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'custom filters' do
|
||||
fab!(:post2) { Fabricate(:post, topic: topic, percent_rank: 0.2) }
|
||||
fab!(:post3) { Fabricate(:post, topic: topic, percent_rank: 0.5) }
|
||||
it 'should return the right posts' do
|
||||
TopicView.add_custom_filter("percent") do |posts, topic_view|
|
||||
posts.where(percent_rank: 0.5)
|
||||
end
|
||||
|
||||
get "/t/#{topic.id}.json", params: {
|
||||
post_number: post.post_number,
|
||||
filter: 'percent'
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
body = response.parsed_body
|
||||
|
||||
expect(body["post_stream"]["posts"].map { |p| p["id"] }).to eq([post3.id])
|
||||
ensure
|
||||
TopicView.instance_variable_set(:@custom_filters, [])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user