Commit f8fcdd69eb8771706a0e916ce027732cfde6a35c

Authored by AntonioTerceiro
1 parent 1089c991

ActionItem48: filtering search: user can select to search in the current filter …

…or the whole site, /and/ in specific assets (articles, comments, people  etc)


git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@1612 3f533792-8f58-4932-b0fe-aaf55b0a4547
app/controllers/application.rb
... ... @@ -103,10 +103,12 @@ class ApplicationController < ActionController::Base
103 103 end
104 104  
105 105 def load_category
106   - path = params[:category_path].join('/')
107   - @category = environment.categories.find_by_path(path)
108   - if @category.nil?
109   - render_not_found(path)
  106 + unless params[:category_path].blank?
  107 + path = params[:category_path].join('/')
  108 + @category = environment.categories.find_by_path(path)
  109 + if @category.nil?
  110 + render_not_found(path)
  111 + end
110 112 end
111 113 end
112 114  
... ...
app/controllers/public/search_controller.rb
... ... @@ -2,6 +2,10 @@ class SearchController < ApplicationController
2 2  
3 3 helper TagsHelper
4 4  
  5 + before_filter :load_category
  6 + before_filter :prepare_filter
  7 + before_filter :check_search_whole_site
  8 +
5 9 protected
6 10  
7 11 def search(finder, query)
... ... @@ -10,40 +14,43 @@ class SearchController < ApplicationController
10 14 end
11 15 end
12 16  
  17 + def prepare_filter
  18 + @finder = @category || @environment
  19 + end
  20 +
  21 + def check_search_whole_site
  22 + if params[:search_whole_site] == 'yes'
  23 + redirect_to params.merge(:category_path => [], :search_whole_site => nil)
  24 + end
  25 + end
  26 +
13 27 public
14 28  
15 29 include SearchHelper
16 30  
17 31 ######################################################
18 32  
  33 + SEARCH_IN = [
  34 + [ :articles, _('Articles') ],
  35 + [ :comments, _('Comments') ],
  36 + [ :enterprises, _('Enterprises') ],
  37 + [ :people, _('People') ],
  38 + [ :communities, _('Communities') ],
  39 + [ :products, _('Products') ]
  40 + ]
  41 +
19 42 def index
20 43 @query = params[:query] || ''
21 44 @filtered_query = remove_stop_words(@query)
22 45  
23   - @finder ||= @environment
24   -
25 46 @results = {}
26 47 @names = {}
27   - [
28   - [ :articles, _('Articles') ],
29   - [ :comments, _('Comments') ],
30   - [ :enterprises, _('Enterprises') ],
31   - [ :people, _('People') ],
32   - [ :communities, _('Communities') ],
33   - [ :products, _('Products') ]
34   - ].each do |key, description|
  48 + SEARCH_IN.each do |key, description|
35 49 @results[key] = search(@finder.send(key), @filtered_query) if params[:find_in].nil? || params[:find_in].empty? || params[:find_in].include?(key.to_s)
36 50 @names[key] = description
37 51 end
38 52 end
39 53  
40   - before_filter :load_category, :only => :filter
41   - def filter
42   - @finder = @category
43   - index
44   - render :action => 'index'
45   - end
46   -
47 54 #######################################################
48 55  
49 56 def tags
... ... @@ -61,6 +68,7 @@ class SearchController < ApplicationController
61 68 #######################################################
62 69  
63 70 def popup
  71 + @search_in = SEARCH_IN
64 72 render :action => 'popup', :layout => false
65 73 end
66 74  
... ...
app/views/layouts/application.rhtml
... ... @@ -99,7 +99,7 @@
99 99 <%= render :file => 'shared/user_menu' %>
100 100 <%=
101 101 lightbox_link_to '<span class="icon-menu-search"></span>'+ _('Search'),
102   - { :controller => 'search', :action => 'popup' }, :id => 'open_search'
  102 + { :controller => 'search', :action => 'popup', :category_path => (@category ? @category.explode_path : []) }, :id => 'open_search'
103 103 %>
104 104 </div><!-- id='user_box' -->
105 105  
... ...
app/views/search/index.rhtml
1   -<h2> <%= _('Search results for "%s"') % @query %> </h2>
  1 +<h2> <%= @category ? (_('Search results for "%{query}" in %{category}') % { :query => @query, :category => @category.full_name}) : (_('Search results for "%s"') % @query) %> </h2>
2 2  
3 3 <% @results.each do |name,results| %>
4 4 <% if !results.nil? and !results.empty? %>
... ...
app/views/search/popup.rhtml
1 1 <h2><%= _('Search %s') % @environment.name %></h2>
2 2  
3   -<% form_tag(:action => 'index') do%>
  3 +<% form_tag({:action => 'index', :category_path => (@category ? @category.explode_path : [])}, :method => 'get') do%>
4 4  
5 5 <div id='search-field' style='text-align: center;'>
6 6 <%= text_field_tag('query', '', :size => 50) %>
7 7 <%= submit_button(:search, _('Search')) %>
8 8 </div>
9 9  
10   - <h3><%= _('Search options') %></h3>
  10 + <% if @category %>
  11 + <h3><%= _('Search in:') %></h3>
  12 + <ul>
  13 + <li>
  14 + <%= radio_button_tag :search_whole_site, 'no', true %>
  15 + <span><%= _('Only in %{category}') % { :category => @category.full_name } %></span>
  16 + </li>
  17 + <li>
  18 + <%= radio_button_tag :search_whole_site, 'yes' %>
  19 + <span><%= _('Whole site') %></span>
  20 + </li>
  21 + </ul>
  22 + <% end %>
  23 +
  24 + <h3><%= _('Search for:') %></h3>
  25 +
  26 + <ul>
  27 + <% @search_in.each do |thing, name| %>
  28 + <li>
  29 + <%= check_box_tag 'find_in[]', thing.to_s, true %>
  30 + <span><%= name %></span>
  31 + </li>
  32 + <% end %>
  33 + </ul>
11 34  
12 35  
13 36 <% button_bar do %>
... ...
lib/noosfero.rb
... ... @@ -9,13 +9,6 @@ module Noosfero
9 9 Regexp.new(pattern)
10 10 end
11 11  
12   - def self.pattern_for_controllers_from_design_blocks
13   - items = Dir.glob(File.join(RAILS_ROOT, 'app', 'design_blocks', '*', 'controllers', '*_controller.rb')).map do |item|
14   - item.gsub(/^.*\/([^\/]+)_controller.rb$/, '\1')
15   - end.join('|')
16   - Regexp.new(items.blank? ? '' : ('(' + items + ')'))
17   - end
18   -
19 12 class << self
20 13 attr_accessor :locales
21 14 attr_accessor :default_locale
... ...
test/functional/search_controller_test.rb
... ... @@ -63,7 +63,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
63 63 art2 = person.articles.build(:name => 'another article to be found')
64 64 art2.save!
65 65  
66   - get :filter, :category_path => [ 'my-category' ], :query => 'article found', :find_in => [ 'articles' ]
  66 + get :index, :category_path => [ 'my-category' ], :query => 'article found', :find_in => [ 'articles' ]
67 67  
68 68 assert_includes assigns(:results)[:articles], art1
69 69 assert_not_includes assigns(:results)[:articles], art2
... ... @@ -95,7 +95,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
95 95 art2 = person.articles.build(:name => 'another article to be found')
96 96 art2.save!
97 97 comment2 = art2.comments.build(:title => 'comment to be found', :body => 'hfyfyh', :author => person); comment2.save!
98   - get 'filter', :category_path => ['my-category'], :query => 'found', :find_in => [ 'comments' ]
  98 + get :index, :category_path => ['my-category'], :query => 'found', :find_in => [ 'comments' ]
99 99  
100 100 assert_includes assigns(:results)[:comments], comment1
101 101 assert_not_includes assigns(:results)[:comments], comment2
... ... @@ -116,7 +116,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
116 116 # not in category
117 117 ent2 = Enterprise.create!(:name => 'testing enterprise 2', :identifier => 'test2')
118 118  
119   - get :filter, :category_path => [ 'my-category' ], :query => 'testing', :find_in => [ 'enterprises' ]
  119 + get :index, :category_path => [ 'my-category' ], :query => 'testing', :find_in => [ 'enterprises' ]
120 120  
121 121 assert_includes assigns(:results)[:enterprises], ent1
122 122 assert_not_includes assigns(:results)[:enterprises], ent2
... ... @@ -135,7 +135,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
135 135 c = Category.create!(:name => 'my category', :environment => Environment.default)
136 136 p1 = create_user('people_1').person; p1.name = 'a beautiful person'; p1.categories << c; p1.save!
137 137 p2 = create_user('people_2').person; p2.name = 'another beautiful person'; p2.save!
138   - get :filter, :category_path => [ 'my-category' ], :query => 'beautiful', :find_in => [ 'people' ]
  138 + get :index, :category_path => [ 'my-category' ], :query => 'beautiful', :find_in => [ 'people' ]
139 139 assert_includes assigns(:results)[:people], p1
140 140 assert_not_includes assigns(:results)[:people], p2
141 141 end
... ... @@ -154,7 +154,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
154 154 c1 = Community.create!(:name => 'a beautiful community', :identifier => 'bea_comm', :environment => Environment.default)
155 155 c2 = Community.create!(:name => 'another beautiful community', :identifier => 'an_bea_comm', :environment => Environment.default)
156 156 c1.categories << c; c1.save!
157   - get :filter, :category_path => [ 'my-category' ], :query => 'beautiful', :find_in => [ 'communities' ]
  157 + get :index, :category_path => [ 'my-category' ], :query => 'beautiful', :find_in => [ 'communities' ]
158 158 assert_includes assigns(:results)[:communities], c1
159 159 assert_not_includes assigns(:results)[:communities], c2
160 160 end
... ... @@ -174,7 +174,7 @@ class SearchControllerTest &lt; Test::Unit::TestCase
174 174 ent2 = Enterprise.create!(:name => 'teste2', :identifier => 'teste2')
175 175 prod1 = ent1.products.create!(:name => 'a beautiful product')
176 176 prod2 = ent2.products.create!(:name => 'another beautiful product')
177   - get 'filter', :category_path => ['my-category'], :query => 'beautiful', :find_in => ['products']
  177 + get :index, :category_path => ['my-category'], :query => 'beautiful', :find_in => ['products']
178 178 assert_includes assigns(:results)[:products], prod1
179 179 assert_not_includes assigns(:results)[:products], prod2
180 180 end
... ... @@ -206,4 +206,59 @@ class SearchControllerTest &lt; Test::Unit::TestCase
206 206 end
207 207 end
208 208  
  209 + should 'present options of where to search' do
  210 + get :popup
  211 + names = {
  212 + :articles => 'Articles',
  213 + :comments => 'Comments',
  214 + :people => 'People',
  215 + :enterprises => 'Enterprises',
  216 + :communities => 'Communities',
  217 + :products => 'Products',
  218 + }
  219 + names.each do |thing,description|
  220 + assert_tag :tag => 'input', :attributes => { :type => 'checkbox', :name => "find_in[]", :value => thing.to_s, :checked => 'checked' }
  221 + assert_tag :tag => 'span', :content => description
  222 + end
  223 + end
  224 +
  225 + should 'not display option to choose where to search when not inside filter' do
  226 + get :popup
  227 + assert_no_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'search_whole_site', :value => 'yes' }
  228 + end
  229 +
  230 + should 'display option to choose searching in whole site or in current category' do
  231 + parent = Category.create!(:name => 'cat', :environment => Environment.default)
  232 + Category.create!(:name => 'sub', :environment => Environment.default, :parent => parent)
  233 +
  234 + get :popup, :category_path => [ 'cat', 'sub']
  235 + assert_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'search_whole_site', :value => 'yes' }
  236 + assert_tag :tag => 'input', :attributes => { :type => 'radio', :name => 'search_whole_site', :value => 'no', :checked => 'checked' }
  237 + end
  238 +
  239 + should 'search in whole site when told so' do
  240 + parent = Category.create!(:name => 'randomcat', :environment => Environment.default)
  241 + Category.create!(:name => 'randomchild', :environment => Environment.default, :parent => parent)
  242 +
  243 + get :index, :category_path => [ 'randomcat', 'randomchild' ], :query => 'some random query', :search_whole_site => 'yes'
  244 +
  245 + # search_whole_site must be removed to precent a infinite redirect loop
  246 + assert_redirected_to :action => 'index', :category_path => [], :query => 'some random query', :search_whole_site => nil
  247 + end
  248 +
  249 + should 'submit form to root when not inside a filter' do
  250 + get :popup
  251 + assert_tag :tag => 'form', :attributes => { :action => '/search' }
  252 + end
  253 +
  254 + should 'submit form to category path when inside a filter' do
  255 + get :popup, :category_path => Category.create!(:name => 'mycat', :environment => Environment.default).explode_path
  256 + assert_tag :tag => 'form', :attributes => { :action => '/search/index/mycat' }
  257 + end
  258 +
  259 + should 'use GET method to search' do
  260 + get :popup
  261 + assert_tag :tag => 'form' , :attributes => { :method => 'get' }
  262 + end
  263 +
209 264 end
... ...