Commit 35b00cd49c00adfcf89f703806b5656f6d4ef93f
1 parent
131516d4
Exists in
master
and in
22 other branches
[search-improvements] Add search query suggestions infra-structure
Showing
6 changed files
with
53 additions
and
6 deletions
Show diff stats
app/controllers/application_controller.rb
@@ -169,6 +169,11 @@ class ApplicationController < ActionController::Base | @@ -169,6 +169,11 @@ class ApplicationController < ActionController::Base | ||
169 | fallback_find_by_contents(asset, scope, query, paginate_options, options) | 169 | fallback_find_by_contents(asset, scope, query, paginate_options, options) |
170 | end | 170 | end |
171 | 171 | ||
172 | + def find_suggestions(asset, query, options={}) | ||
173 | + plugins.dispatch_first(:find_suggestions, asset, query, options) || | ||
174 | + fallback_find_suggestions(asset, query, options) | ||
175 | + end | ||
176 | + | ||
172 | private | 177 | private |
173 | 178 | ||
174 | def fallback_find_by_contents(asset, scope, query, paginate_options, options) | 179 | def fallback_find_by_contents(asset, scope, query, paginate_options, options) |
@@ -177,4 +182,7 @@ class ApplicationController < ActionController::Base | @@ -177,4 +182,7 @@ class ApplicationController < ActionController::Base | ||
177 | {:results => scope.paginate(paginate_options)} | 182 | {:results => scope.paginate(paginate_options)} |
178 | end | 183 | end |
179 | 184 | ||
185 | + def fallback_find_suggestions(asset, query, options) | ||
186 | + #TODO Implement fallback suggestions solution | ||
187 | + end | ||
180 | end | 188 | end |
app/controllers/public/search_controller.rb
@@ -4,11 +4,11 @@ class SearchController < PublicController | @@ -4,11 +4,11 @@ class SearchController < PublicController | ||
4 | include SearchHelper | 4 | include SearchHelper |
5 | include ActionView::Helpers::NumberHelper | 5 | include ActionView::Helpers::NumberHelper |
6 | 6 | ||
7 | - before_filter :redirect_asset_param, :except => :assets | ||
8 | - before_filter :load_category | ||
9 | - before_filter :load_search_assets | ||
10 | - before_filter :load_query | ||
11 | - before_filter :load_filter | 7 | + before_filter :redirect_asset_param, :except => [:assets, :suggestions] |
8 | + before_filter :load_category, :except => :suggestions | ||
9 | + before_filter :load_search_assets, :except => :suggestions | ||
10 | + before_filter :load_query, :except => :suggestions | ||
11 | + before_filter :load_filter, :except => :suggestions | ||
12 | 12 | ||
13 | # Backwards compatibility with old URLs | 13 | # Backwards compatibility with old URLs |
14 | def redirect_asset_param | 14 | def redirect_asset_param |
@@ -143,6 +143,10 @@ class SearchController < PublicController | @@ -143,6 +143,10 @@ class SearchController < PublicController | ||
143 | render :partial => 'events/events' | 143 | render :partial => 'events/events' |
144 | end | 144 | end |
145 | 145 | ||
146 | + def suggestions | ||
147 | + render :text => find_suggestions(params[:term], environment, params[:asset]).to_json | ||
148 | + end | ||
149 | + | ||
146 | ####################################################### | 150 | ####################################################### |
147 | protected | 151 | protected |
148 | 152 |
app/helpers/application_helper.rb
@@ -1402,4 +1402,8 @@ module ApplicationHelper | @@ -1402,4 +1402,8 @@ module ApplicationHelper | ||
1402 | content_tag('ul', article.versions.map {|v| link_to("r#{v.version}", @page.url.merge(:version => v.version))}) | 1402 | content_tag('ul', article.versions.map {|v| link_to("r#{v.version}", @page.url.merge(:version => v.version))}) |
1403 | end | 1403 | end |
1404 | 1404 | ||
1405 | + def search_input_with_suggestions(name, asset, default, options = {}) | ||
1406 | + text_field_tag name, default, options.merge({:id => 'search-input', 'data-asset' => asset}) | ||
1407 | + end | ||
1408 | + | ||
1405 | end | 1409 | end |
app/views/search/_search_form.html.erb
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | 8 | ||
9 | <div class="search-field"> | 9 | <div class="search-field"> |
10 | <span class="formfield"> | 10 | <span class="formfield"> |
11 | - <%= text_field_tag 'query', @query, :id => 'search-input', :size => 50 %> | 11 | + <%= search_input_with_suggestions('query', @asset, @query, {:size => 50}) %> |
12 | <%= javascript_tag "jQuery('#search-input').attr('title', \"#{hint}\").hint()" if defined?(hint) %> | 12 | <%= javascript_tag "jQuery('#search-input').attr('title', \"#{hint}\").hint()" if defined?(hint) %> |
13 | </span> | 13 | </span> |
14 | 14 |
lib/noosfero/plugin.rb
@@ -507,6 +507,17 @@ class Noosfero::Plugin | @@ -507,6 +507,17 @@ class Noosfero::Plugin | ||
507 | def find_by_contents(asset, scope, query, paginate_options={}, options={}) | 507 | def find_by_contents(asset, scope, query, paginate_options={}, options={}) |
508 | end | 508 | end |
509 | 509 | ||
510 | + # -> Suggests terms based on asset and query | ||
511 | + # returns = [a, b, c, ...] | ||
512 | + def find_suggestions(query, context, asset, options={:limit => 5}) | ||
513 | + context.search_terms. | ||
514 | + where(:asset => asset). | ||
515 | + where("search_terms.term like ?", "#{query}%"). | ||
516 | + where('search_terms.score > 0'). | ||
517 | + order('search_terms.score DESC'). | ||
518 | + limit(options[:limit]).map(&:term) | ||
519 | + end | ||
520 | + | ||
510 | # -> Adds aditional fields for change_password | 521 | # -> Adds aditional fields for change_password |
511 | # returns = [{:field => 'field1', :name => 'field 1 name', :model => 'person'}, {...}] | 522 | # returns = [{:field => 'field1', :name => 'field 1 name', :model => 'person'}, {...}] |
512 | def change_password_fields | 523 | def change_password_fields |
public/javascripts/application.js
@@ -1101,4 +1101,24 @@ jQuery(document).ready(function(){ | @@ -1101,4 +1101,24 @@ jQuery(document).ready(function(){ | ||
1101 | jQuery("#article_has_terms_of_use").click(function(){ | 1101 | jQuery("#article_has_terms_of_use").click(function(){ |
1102 | showHideTermsOfUse(); | 1102 | showHideTermsOfUse(); |
1103 | }); | 1103 | }); |
1104 | + | ||
1105 | + // Suggestions on search inputs | ||
1106 | + (function($) { | ||
1107 | + var suggestions_cache = {}; | ||
1108 | + $("#search-input").autocomplete({ | ||
1109 | + minLength: 2, | ||
1110 | + source: function(request, response) { | ||
1111 | + var term = request.term; | ||
1112 | + if (term in suggestions_cache) { | ||
1113 | + response(suggestions_cache[term]); | ||
1114 | + return; | ||
1115 | + } | ||
1116 | + request["asset"] = $("#search-input").data("asset"); | ||
1117 | + $.getJSON("/search/suggestions", request, function(data, status, xhr) { | ||
1118 | + suggestions_cache[term] = data; | ||
1119 | + response(data); | ||
1120 | + }); | ||
1121 | + } | ||
1122 | + }); | ||
1123 | + })(jQuery); | ||
1104 | }); | 1124 | }); |