FEATURE: wider search with more context

This commit is contained in:
Sam 2014-09-01 17:04:40 +10:00
parent 7ef056810c
commit 69e418facf
8 changed files with 49 additions and 29 deletions

View File

@ -21,7 +21,7 @@ Discourse.Search = {
if (!opts) opts = {}; if (!opts) opts = {};
// Only include the data we have // Only include the data we have
var data = { term: term }; var data = { term: term, include_blurbs: 'true' };
if (opts.typeFilter) data.type_filter = opts.typeFilter; if (opts.typeFilter) data.type_filter = opts.typeFilter;
if (opts.searchForId) data.search_for_id = true; if (opts.searchForId) data.search_for_id = true;

View File

@ -1,3 +1,10 @@
<a href='{{unbound url}}'> <a class='search-link' href='{{unbound url}}'>
<span class='topic'>
{{unbound title}} {{unbound title}}
</span>
{{#unless Discourse.Mobile.mobileView}}
<span class='blurb'>
{{{unbound blurb}}}
</span>
{{/unless}}
</a> </a>

View File

@ -65,3 +65,13 @@ and (max-width : 570px) {
} }
} }
} }
.search-link .blurb {
color: scale-color($primary, $lightness: 45%);
display: block;
font-size: 11px;
}
.d-dropdown#search-dropdown {
width: 540px;
}

View File

@ -1025,7 +1025,7 @@ en:
granted_badge: "You earned %{link}" granted_badge: "You earned %{link}"
search: search:
within_post: "#%{post_number} by %{username}: %{excerpt}" within_post: "#%{post_number} by %{username}"
types: types:
category: 'Categories' category: 'Categories'
topic: 'Results' topic: 'Results'

View File

@ -279,17 +279,24 @@ class Search
end end
def aggregate_search def aggregate_search
cols = ['topics.id', 'topics.title', 'topics.slug'] cols = ['topics.id', 'topics.title', 'topics.slug', 'cooked']
topics = posts_query(@limit, aggregate_search: true) topics = posts_query(@limit, aggregate_search: true)
.group(*cols) .group(*cols)
.pluck('min(posts.post_number)',*cols) .pluck('min(posts.post_number)',*cols)
topics.each do |t| topics.each do |t|
post_number, topic_id, title, slug, cooked = t
cooked = SearchObserver::HtmlScrubber.scrub(cooked).squish
blurb = SearchResult.blurb(cooked, @term)
@results.add_result(SearchResult.new(type: :topic, @results.add_result(SearchResult.new(type: :topic,
topic_id: t[1], topic_id: topic_id,
id: t[1], id: topic_id,
title: t[2], title: title,
url: "/t/#{t[3]}/#{t[1]}/#{t[0]}")) url: "/t/#{slug}/#{topic_id}/#{post_number}",
blurb: blurb))
end end
end end

View File

@ -1,3 +1,5 @@
require 'sanitize'
class Search class Search
class SearchResult class SearchResult
@ -55,24 +57,23 @@ class Search
SearchResult.new(type: :topic, topic_id: t.id, id: t.id, title: options[:custom_title] || t.title, url: t.relative_url, blurb: options[:custom_blurb]) SearchResult.new(type: :topic, topic_id: t.id, id: t.id, title: options[:custom_title] || t.title, url: t.relative_url, blurb: options[:custom_blurb])
end end
def self.blurb(raw, term)
blurb = TextHelper.excerpt(raw, term.split(/\s+/)[0], radius: 100)
blurb = TextHelper.truncate(raw, length: 200) if blurb.blank?
Sanitize.clean(blurb)
end
def self.from_post(p, context, term, include_blurbs=false) def self.from_post(p, context, term, include_blurbs=false)
custom_title = custom_title =
if context && context.id == p.topic_id if context && context.id == p.topic_id
# TODO: rewrite this
# 1. convert markdown to text
# 2. grab full words
excerpt = TextHelper.excerpt(p.raw, term.split(/\s+/)[0], radius: 30)
excerpt = TextHelper.truncate(p.raw, length: 50) if excerpt.blank?
I18n.t("search.within_post", I18n.t("search.within_post",
post_number: p.post_number, post_number: p.post_number,
username: p.user && p.user.username, username: p.user && p.user.username
excerpt: excerpt
) )
end end
if include_blurbs if include_blurbs
#add a blurb from the post to the search results #add a blurb from the post to the search results
custom_blurb = TextHelper.excerpt(p.raw, term.split(/\s+/)[0], radius: 100) custom_blurb = blurb(p.raw, term)
custom_blurb = TextHelper.truncate(p.raw, length: 200) if custom_blurb.blank?
end end
if p.post_number == 1 if p.post_number == 1
# we want the topic link when it's the OP # we want the topic link when it's the OP

View File

@ -34,17 +34,12 @@ describe Search do
@post = Fabricate(:post, topic: @topic, raw: 'this <b>fun test</b> <img src="bla" title="my image">') @post = Fabricate(:post, topic: @topic, raw: 'this <b>fun test</b> <img src="bla" title="my image">')
@indexed = @post.post_search_data.search_data @indexed = @post.post_search_data.search_data
end end
it "should include body in index" do
@indexed.should =~ /fun/
end
it "should include title in index" do
@indexed.should =~ /sam/
end
it "should include category in index" do
@indexed.should =~ /america/
end
it "should pick up on title updates" do it "should index correctly" do
@indexed.should =~ /fun/
@indexed.should =~ /sam/
@indexed.should =~ /america/
@topic.title = "harpi is the new title" @topic.title = "harpi is the new title"
@topic.save! @topic.save!
@post.post_search_data.reload @post.post_search_data.reload
@ -186,8 +181,8 @@ describe Search do
it 'returns the post' do it 'returns the post' do
result.should be_present result.should be_present
result[:title].should == topic.title result[:title].should == topic.title
result[:url].should == topic.relative_url + "/2" result[:url].should == topic.relative_url + "/2"
result[:blurb].should == "this reply has no quotes"
end end
end end