Commit 7e54e8ab2527fd9c44ade31f8eba54ec8c090fcb
1 parent
afbcb3d1
Exists in
staging
and in
42 other branches
Redesigned search
- Standardized search for all entities type - New category search based on a facet view
Showing
43 changed files
with
1005 additions
and
600 deletions
Show diff stats
app/controllers/public/search_controller.rb
1 | 1 | class SearchController < PublicController |
2 | 2 | |
3 | 3 | MAP_SEARCH_LIMIT = 2000 |
4 | - SINGLE_SEARCH_LIMIT = 20 | |
5 | - MULTIPLE_SEARCH_LIMIT = 6 | |
4 | + LIST_SEARCH_LIMIT = 20 | |
5 | + BLOCKS_SEARCH_LIMIT = 18 | |
6 | + MULTIPLE_SEARCH_LIMIT = 8 | |
6 | 7 | |
7 | 8 | helper TagsHelper |
8 | 9 | include SearchHelper |
10 | + include ActionView::Helpers::NumberHelper | |
9 | 11 | |
10 | 12 | before_filter :load_category |
11 | 13 | before_filter :load_search_assets |
14 | + before_filter :load_query | |
12 | 15 | |
13 | 16 | no_design_blocks |
14 | 17 | |
15 | - def articles | |
16 | - @asset = :articles | |
17 | - @query = params[:query] || '' | |
18 | - @order ||= [@asset] | |
19 | - @results ||= {} | |
20 | - @filter = filter | |
18 | + def facets_browse | |
19 | + @asset = params[:asset] | |
20 | + @asset_class = asset_class(@asset) | |
21 | 21 | |
22 | - pg_options = paginate_options(@asset, limit, params[:per_page]) | |
23 | - if !@query.blank? | |
24 | - ret = asset_class(@asset).find_by_contents(@query, pg_options, solr_options(@asset, params[:facet], params[:order_by])) | |
25 | - @results[@asset] = ret[:results] | |
26 | - @facets = ret[:facets] | |
27 | - else | |
28 | - @results[@asset] = asset_class(@asset).send('paginate', :all, pg_options) | |
29 | - @facets = {} | |
22 | + @facets_only = true | |
23 | + send(@asset) | |
24 | + | |
25 | + @facet = @asset_class.map_facets_for(environment).find { |facet| facet[:id] == params[:facet_id] } | |
26 | + raise 'Facet not found' if @facet.nil? | |
27 | + | |
28 | + render :layout => false | |
29 | + end | |
30 | + | |
31 | + def articles | |
32 | + @filter = params[:filter] ? filter : nil | |
33 | + @filter_title = params[:filter] ? filter_description(@asset, @filter) : nil | |
34 | + if !@empty_query | |
35 | + full_text_search | |
36 | + elsif params[:filter] | |
37 | + @results[@asset] = @environment.articles.more_recent.paginate(paginate_options) | |
30 | 38 | end |
31 | 39 | end |
32 | 40 | |
33 | - alias :contents :articles | |
41 | + def contents | |
42 | + redirect_to params.merge(:action => :articles) | |
43 | + end | |
34 | 44 | |
35 | 45 | def people |
36 | - @asset = :people | |
37 | - @query = params[:query] || '' | |
38 | - @order ||= [@asset] | |
39 | - @results ||= {} | |
40 | - @filter = filter | |
41 | - @title = self.filter_description(params[:action] + '_' + @filter ) | |
42 | - | |
43 | - @results[@asset] = @environment.people.visible.send(@filter) | |
44 | - if !@query.blank? | |
45 | - ret = @results[@asset].find_by_contents(@query, {}, solr_options(@asset, params[:facet], params[:order_by])) | |
46 | - @results[@asset] = ret[:results] | |
47 | - @facets = ret[:facets] | |
46 | + if !@empty_query | |
47 | + full_text_search | |
48 | 48 | else |
49 | + @results[@asset] = @environment.people.visible.send(@filter).paginate(paginate_options) | |
49 | 50 | @facets = {} |
50 | 51 | end |
51 | - @results[@asset] = @results[@asset].compact.paginate(:per_page => limit, :page => params[:page]) | |
52 | 52 | end |
53 | 53 | |
54 | 54 | def products |
55 | - @asset = :products | |
56 | - @query = params[:query] || '' | |
57 | - @order ||= [@asset] | |
58 | - @results ||= {} | |
59 | - | |
60 | - pg_options = paginate_options(@asset, limit, params[:per_page]) | |
61 | - if !@query.blank? | |
62 | - ret = asset_class(@asset).find_by_contents(@query, pg_options, solr_options(@asset, params[:facet], params[:order_by])) | |
63 | - @results[@asset] = ret[:results] | |
64 | - @facets = ret[:facets] | |
65 | - else | |
66 | - @results[@asset] = asset_class(@asset).send('paginate', :all, pg_options) | |
67 | - @facets = {} | |
55 | + if !@empty_query | |
56 | + full_text_search | |
68 | 57 | end |
69 | 58 | end |
70 | 59 | |
71 | 60 | def enterprises |
72 | - @asset = :enterprises | |
73 | - @query = params[:query] || '' | |
74 | - @order ||= [@asset] | |
75 | - @results ||= {} | |
76 | - | |
77 | - pg_options = paginate_options(@asset, limit, params[:per_page]) | |
78 | - if !@query.blank? | |
79 | - ret = asset_class(@asset).find_by_contents(@query, pg_options, solr_options(@asset, params[:facet], params[:order_by])) | |
80 | - @results[@asset] = ret[:results] | |
81 | - @facets = ret[:facets] | |
61 | + if !@empty_query | |
62 | + full_text_search | |
82 | 63 | else |
83 | - @results[@asset] = asset_class(@asset).send('paginate', :all, pg_options) | |
84 | - @facets = {} | |
64 | + @filter_title = _('Enterprises from network') | |
65 | + @results[@asset] = asset_class(@asset).paginate(paginate_options) | |
85 | 66 | end |
86 | 67 | end |
87 | 68 | |
88 | 69 | def communities |
89 | - @asset = :communities | |
90 | - @query = params[:query] || '' | |
91 | - @order ||= [@asset] | |
92 | - @results ||= {} | |
93 | - @filter = filter | |
94 | - @title = self.filter_description(params[:action] + '_' + @filter ) | |
95 | - | |
96 | - @results[@asset] = @environment.communities.visible.send(@filter) | |
97 | - if !@query.blank? | |
98 | - ret = @results[@asset].find_by_contents(@query, {}, solr_options(@asset, params[:facet], params[:order_by])) | |
99 | - @results[@asset] = ret[:results] | |
100 | - @facets = ret[:facets] | |
70 | + if !@empty_query | |
71 | + full_text_search | |
101 | 72 | else |
102 | - @facets = {} | |
73 | + @results[@asset] = @environment.communities.visible.send(@filter).paginate(paginate_options) | |
103 | 74 | end |
104 | - @results[@asset] = @results[@asset].compact.paginate(:per_page => limit, :page => params[:page]) | |
105 | 75 | end |
106 | 76 | |
107 | 77 | def events |
108 | - @asset = :events | |
109 | - params[:asset] |= [@asset] | |
110 | - @query = params[:query] || '' | |
111 | - @order ||= [@asset] | |
112 | - @results ||= {} | |
113 | 78 | @category_id = @category ? @category.id : nil |
114 | 79 | |
115 | 80 | if params[:year] || params[:month] |
... | ... | @@ -129,9 +94,7 @@ class SearchController < PublicController |
129 | 94 | @results[@asset] = Event.send('find', :all) |
130 | 95 | end |
131 | 96 | else |
132 | - pg_options = paginate_options(@asset, limit, params[:per_page]) | |
133 | - solr_options = solr_options(@asset, params[:facet], params[:per_page]) | |
134 | - @results[@asset] = Event.find_by_contents(@query, pg_options, solr_options)[:results] | |
97 | + full_text_search | |
135 | 98 | end |
136 | 99 | |
137 | 100 | @selected_day = nil |
... | ... | @@ -157,6 +120,7 @@ class SearchController < PublicController |
157 | 120 | @results = {} |
158 | 121 | @order = [] |
159 | 122 | @names = {} |
123 | + @results_only = true | |
160 | 124 | |
161 | 125 | @enabled_searchs.select { |key,description| @searching[key] }.each do |key, description| |
162 | 126 | send(key) |
... | ... | @@ -186,19 +150,17 @@ class SearchController < PublicController |
186 | 150 | @names = {} |
187 | 151 | limit = MULTIPLE_SEARCH_LIMIT |
188 | 152 | [ |
189 | - [ :people, _('People'), recent('people', limit) ], | |
190 | - [ :enterprises, __('Enterprises'), recent('enterprises', limit) ], | |
191 | - [ :products, _('Products'), recent('products', limit) ], | |
192 | - [ :events, _('Upcoming events'), upcoming_events({:per_page => limit}) ], | |
193 | - [ :communities, __('Communities'), recent('communities', limit) ], | |
194 | - [ :most_commented_articles, _('Most commented articles'), most_commented_articles(limit) ], | |
195 | - [ :articles, _('Articles'), recent('text_articles', limit) ] | |
196 | - ].each do |key, name, list| | |
197 | - @order << key | |
198 | - @results[key] = list | |
199 | - @names[key] = name | |
153 | + [ :people, _('People'), :recent_people ], | |
154 | + [ :enterprises, _('Enterprises'), :recent_enterprises ], | |
155 | + [ :products, _('Products'), :recent_products ], | |
156 | + [ :events, _('Upcoming events'), :upcoming_events ], | |
157 | + [ :communities, _('Communities'), :recent_communities ], | |
158 | + [ :articles, _('Contents'), :recent_articles ] | |
159 | + ].each do |asset, name, filter| | |
160 | + @order << asset | |
161 | + @results[asset] = @category.send(filter, limit) | |
162 | + @names[asset] = name | |
200 | 163 | end |
201 | - @facets = {} | |
202 | 164 | end |
203 | 165 | |
204 | 166 | def tags |
... | ... | @@ -218,50 +180,33 @@ class SearchController < PublicController |
218 | 180 | |
219 | 181 | def events_by_day |
220 | 182 | @selected_day = build_date(params[:year], params[:month], params[:day]) |
221 | - if params[:category_id] and Category.exists?(params[:category_id]) | |
222 | - @events_of_the_day = environment.events.by_day(@selected_day).in_category(Category.find(params[:category_id])) | |
223 | - else | |
224 | - @events_of_the_day = environment.events.by_day(@selected_day) | |
225 | - end | |
183 | + @events_of_the_day = environment.events.by_day(@selected_day) | |
226 | 184 | render :partial => 'events/events_by_day' |
227 | 185 | end |
228 | 186 | |
229 | 187 | ####################################################### |
230 | 188 | protected |
231 | 189 | |
232 | - def recent(asset, limit = nil) | |
233 | - options = {:page => 1, :per_page => limit, :order => 'created_at DESC, id DESC'} | |
234 | - | |
235 | - if asset == :events | |
236 | - finder_method = 'find' | |
237 | - options.delete(:page) | |
238 | - options.delete(:per_page) | |
239 | - else | |
240 | - finder_method = 'paginate' | |
241 | - end | |
242 | - | |
243 | - asset_class(asset).send(finder_method, :all, category_options_for_find(asset_class(asset), {:order => "#{asset_table(asset)}.name"}.merge(options))) | |
244 | - end | |
245 | - | |
246 | - def most_commented_articles(limit=10, options={}) | |
247 | - options = {:page => 1, :per_page => limit, :order => 'comments_count DESC'}.merge(options) | |
248 | - Article.paginate(:all, category_options_for_find(Article, options)) | |
249 | - end | |
250 | - | |
251 | - def upcoming_events(options = {}) | |
252 | - options.delete(:page) | |
253 | - options.delete(:per_page) | |
190 | + def load_query | |
191 | + @asset = params[:action].to_sym | |
192 | + @order ||= [@asset] | |
193 | + @results ||= {} | |
194 | + @filter = filter | |
195 | + @filter_title = filter_description(@asset, @filter) | |
254 | 196 | |
255 | - Event.find(:all, {:include => :categories, :conditions => [ 'categories.id = ? and start_date >= ?', category_id, Date.today ], :order => 'start_date' }.merge(options)) | |
197 | + @query = params[:query] || '' | |
198 | + @empty_query = @category.nil? && @query.blank? | |
256 | 199 | end |
257 | 200 | |
258 | - def current_events(year, month, options={}) | |
259 | - options.delete(:page) | |
260 | - options.delete(:per_page) | |
261 | - | |
262 | - range = Event.date_range(year, month) | |
263 | - | |
264 | - Event.find(:all, {:include => :categories, :conditions => { 'categories.id' => category_id, :start_date => range }}.merge(options)) | |
201 | + def load_category | |
202 | + unless params[:category_path].blank? | |
203 | + path = params[:category_path].join('/') | |
204 | + @category = environment.categories.find_by_path(path) | |
205 | + if @category.nil? | |
206 | + render_not_found(path) | |
207 | + end | |
208 | + @category_id = @category.id | |
209 | + end | |
265 | 210 | end |
266 | 211 | |
267 | 212 | FILTERS = %w( |
... | ... | @@ -277,112 +222,83 @@ class SearchController < PublicController |
277 | 222 | end |
278 | 223 | end |
279 | 224 | |
280 | - def filter_description(str) | |
225 | + def filter_description(asset, filter) | |
281 | 226 | { |
282 | - 'contents_more_recent' => _('More recent contents'), | |
283 | - 'contents_more_popular' => _('More popular contents'), | |
284 | - 'people_more_recent' => _('More recent people'), | |
285 | - 'people_more_active' => _('More active people'), | |
286 | - 'people_more_popular' => _('More popular people'), | |
287 | - 'communities_more_recent' => _('More recent communities'), | |
288 | - 'communities_more_active' => _('More active communities'), | |
289 | - 'communities_more_popular' => _('More popular communities'), | |
290 | - }[str] || str | |
291 | - end | |
292 | - | |
293 | - attr_reader :category | |
294 | - attr_reader :category_id | |
295 | - | |
296 | - def load_category | |
297 | - unless params[:category_path].blank? | |
298 | - path = params[:category_path].join('/') | |
299 | - @category = environment.categories.find_by_path(path) | |
300 | - if @category.nil? | |
301 | - render_not_found(path) | |
302 | - end | |
303 | - @category_id = @category.id | |
304 | - end | |
227 | + 'articles_more_recent' => _('More recent contents from network'), | |
228 | + 'articles_more_popular' => _('More popular contents from network'), | |
229 | + 'people_more_recent' => _('More recent people from network'), | |
230 | + 'people_more_active' => _('More active people from network'), | |
231 | + 'people_more_popular' => _('More popular people from network'), | |
232 | + 'communities_more_recent' => _('More recent communities from network'), | |
233 | + 'communities_more_active' => _('More active communities from network'), | |
234 | + 'communities_more_popular' => _('More popular communities from network'), | |
235 | + }[asset.to_s + '_' + filter] | |
305 | 236 | end |
306 | 237 | |
307 | 238 | def load_search_assets |
308 | 239 | @enabled_searchs = [ |
309 | - [ :articles, N_('Articles') ], | |
310 | - [ :enterprises, N_('Enterprises') ], | |
311 | - [ :people, N_('People') ], | |
312 | - [ :communities, N_('Communities') ], | |
313 | - [ :products, N_('Products') ], | |
314 | - [ :events, N_('Events') ] | |
240 | + [ :articles, _('Contents') ], | |
241 | + [ :enterprises, _('Enterprises') ], | |
242 | + [ :people, _('People') ], | |
243 | + [ :communities, _('Communities') ], | |
244 | + [ :products, _('Products and Services') ], | |
245 | + [ :events, _('Events') ] | |
315 | 246 | ].select {|key, name| !environment.enabled?('disable_asset_' + key.to_s) } |
316 | 247 | |
317 | 248 | @searching = {} |
249 | + @titles = {} | |
318 | 250 | @enabled_searchs.each do |key, name| |
251 | + @titles[key] = name | |
319 | 252 | @searching[key] = params[:action] == 'index' || params[:action] == key.to_s |
320 | 253 | end |
321 | 254 | end |
322 | 255 | |
323 | - def paginate_options(asset, limit, page) | |
324 | - result = { :per_page => limit, :page => page } | |
325 | - end | |
326 | - | |
327 | - def solr_options(asset, facet, solr_order) | |
328 | - result = {} | |
329 | - | |
330 | - if asset_class(asset).methods.include?('facets') | |
331 | - result.merge!(:facets => {:zeros => false, :sort => :count, :fields => asset_class(asset).facets.keys, | |
332 | - :browse => facet ? facet.map{ |k,v| k.to_s+':"'+v.to_s+'"'} : ''}) | |
333 | - end | |
334 | - | |
335 | - if solr_order | |
336 | - result[:order_by] = solr_order | |
337 | - end | |
338 | - | |
339 | - result | |
340 | - end | |
341 | - | |
342 | 256 | def limit |
343 | - searching = @searching.values.select{|v|v} | |
257 | + searching = @searching.values.select{ |v| v } | |
344 | 258 | if params[:display] == 'map' |
345 | 259 | MAP_SEARCH_LIMIT |
260 | + elsif searching.size <= 1 | |
261 | + if [:people, :communities].include? @asset | |
262 | + BLOCKS_SEARCH_LIMIT | |
263 | + elsif @asset == :enterprises and @empty_query | |
264 | + BLOCKS_SEARCH_LIMIT | |
265 | + else | |
266 | + LIST_SEARCH_LIMIT | |
267 | + end | |
346 | 268 | else |
347 | - (searching.size <= 1) ? SINGLE_SEARCH_LIMIT : MULTIPLE_SEARCH_LIMIT | |
269 | + MULTIPLE_SEARCH_LIMIT | |
348 | 270 | end |
349 | 271 | end |
350 | 272 | |
351 | - def category_options_for_find(klass, options={}, date_range = nil) | |
352 | - if defined? options[:product_category] | |
353 | - prod_cat = options.delete(:product_category) | |
354 | - end | |
355 | - | |
356 | - case klass.name | |
357 | - when 'Comment' | |
358 | - {:joins => 'inner join articles_categories on articles_categories.article_id = comments.article_id', :conditions => ['articles_categories.category_id = (?)', category_id]}.merge!(options) | |
359 | - when 'Product' | |
360 | - if prod_cat | |
361 | - {:joins => 'inner join categories_profiles on products.enterprise_id = categories_profiles.profile_id inner join product_categorizations on (product_categorizations.product_id = products.id)', :conditions => ['categories_profiles.category_id = (?) and product_categorizations.category_id = (?)', category_id, prod_cat.id]}.merge!(options) | |
362 | - else | |
363 | - {:joins => 'inner join categories_profiles on products.enterprise_id = categories_profiles.profile_id', :conditions => ['categories_profiles.category_id = (?)', category_id]}.merge!(options) | |
364 | - end | |
365 | - when 'Article', 'TextArticle' | |
366 | - {:joins => 'inner join articles_categories on (articles_categories.article_id = articles.id)', :conditions => ['articles_categories.category_id = (?)', category_id]}.merge!(options) | |
367 | - when 'Event' | |
368 | - conditions = | |
369 | - if date_range | |
370 | - ['articles_categories.category_id = (:category_id) and (start_date BETWEEN :start_day AND :end_day OR end_date BETWEEN :start_day AND :end_day)', {:category_id => category_id, :start_day => date_range.first, :end_day => date_range.last} ] | |
371 | - else | |
372 | - ['articles_categories.category_id = (?) ', category_id ] | |
373 | - end | |
374 | - {:joins => 'inner join articles_categories on (articles_categories.article_id = articles.id)', :conditions => conditions}.merge!(options) | |
375 | - when 'Enterprise' | |
376 | - if prod_cat | |
377 | - {:joins => 'inner join categories_profiles on (categories_profiles.profile_id = profiles.id) inner join products on (products.enterprise_id = profiles.id) inner join product_categorizations on (product_categorizations.product_id = products.id)', :conditions => ['categories_profiles.category_id = (?) and product_categorizations.category_id = (?)', category_id, prod_cat.id]}.merge!(options) | |
378 | - else | |
379 | - {:joins => 'inner join categories_profiles on (categories_profiles.profile_id = profiles.id)', :conditions => ['categories_profiles.category_id = (?)', category_id]}.merge!(options) | |
380 | - end | |
381 | - when 'Person', 'Community' | |
382 | - {:joins => 'inner join categories_profiles on (categories_profiles.profile_id = profiles.id)', :conditions => ['categories_profiles.category_id = (?)', category_id]}.merge!(options) | |
383 | - else | |
384 | - raise "unreconized class #{klass.name}" | |
273 | + def paginate_options(page = params[:page]) | |
274 | + { :per_page => limit, :page => page } | |
275 | + end | |
276 | + | |
277 | + def full_text_search(paginate_options = nil) | |
278 | + paginate_options ||= paginate_options(params[:page]) | |
279 | + solr_options = solr_options(@asset, params[:facet], params[:order_by]) | |
280 | + | |
281 | + ret = asset_class(@asset).find_by_contents(@query, paginate_options, solr_options) | |
282 | + @results[@asset] = ret[:results] | |
283 | + @facets = ret[:facets] | |
284 | + @all_facets = ret[:all_facets] | |
285 | + end | |
286 | + | |
287 | + def solr_options(asset, facets_selected, solr_order = nil) | |
288 | + result = {} | |
289 | + | |
290 | + asset_class = asset_class(asset) | |
291 | + if !@results_only and asset_class.methods.include?('facets') | |
292 | + result.merge! asset_class.facets_find_options(facets_selected) | |
293 | + result[:all_facets] = true | |
294 | + result[:limit] = 0 if @facets_only | |
295 | + result[:facets][:browse] << asset_class.facet_category_query.call(@category) if @category | |
296 | + puts result[:facets][:browse] | |
385 | 297 | end |
298 | + | |
299 | + result[:order] = solr_order if solr_order | |
300 | + | |
301 | + result | |
386 | 302 | end |
387 | 303 | |
388 | 304 | def asset_class(asset) | ... | ... |
app/helpers/display_helper.rb
... | ... | @@ -8,14 +8,24 @@ module DisplayHelper |
8 | 8 | opts |
9 | 9 | end |
10 | 10 | |
11 | + def price_span(price, options = {}) | |
12 | + content_tag 'span', | |
13 | + number_to_currency(price, :unit => environment.currency_unit, :delimiter => environment.currency_delimiter, :separator => environment.currency_separator), | |
14 | + options | |
15 | + end | |
16 | + | |
11 | 17 | def product_path(product) |
12 | 18 | product.enterprise.enabled? ? product.enterprise.public_profile_url.merge(:controller => 'manage_products', :action => 'show', :id => product) : product.enterprise.url |
13 | 19 | end |
14 | 20 | |
15 | - def link_to_category(category, full = true) | |
21 | + def link_to_tag(tag, html_options = {}) | |
22 | + link_to tag.name, {:controller => 'search', :action => 'tag', :tag => tag.name}, html_options | |
23 | + end | |
24 | + | |
25 | + def link_to_category(category, full = true, html_options = {}) | |
16 | 26 | return _('Uncategorized product') unless category |
17 | 27 | name = full ? category.full_name(' → ') : category.name |
18 | - link_to name, Noosfero.url_options.merge({:controller => 'search', :action => 'category_index', :category_path => category.path.split('/'),:host => category.environment.default_hostname }) | |
28 | + link_to name, Noosfero.url_options.merge({:controller => 'search', :action => 'category_index', :category_path => category.path.split('/'),:host => category.environment.default_hostname }), html_options | |
19 | 29 | end |
20 | 30 | |
21 | 31 | def link_to_product_category(category) | ... | ... |
app/helpers/search_helper.rb
... | ... | @@ -9,54 +9,31 @@ module SearchHelper |
9 | 9 | (n * 100.0).round |
10 | 10 | end |
11 | 11 | |
12 | - def display_results(use_map = true) | |
13 | - | |
14 | - unless use_map && GoogleMaps.enabled?(environment.default_hostname) | |
15 | - return render(:partial => 'display_results') | |
12 | + def display_results(use_map = false) | |
13 | + if params[:display] == 'map' && use_map && GoogleMaps.enabled?(environment.default_hostname) | |
14 | + partial = 'google_maps' | |
15 | + klass = 'map' | |
16 | + else | |
17 | + partial = 'display_results' | |
18 | + klass = 'list' | |
16 | 19 | end |
17 | 20 | |
18 | - data = | |
19 | - if params[:display] == 'map' | |
20 | - { | |
21 | - :partial => 'google_maps', | |
22 | - :toggle => button(:search, _('Display in list'), params.merge(:display => 'list'), :class => "map-toggle-button" ), | |
23 | - :class => 'map' , | |
24 | - } | |
25 | - else | |
26 | - { | |
27 | - :partial => 'display_results', | |
28 | - :toggle => button(:search, _('Display in map'), params.merge(:display => 'map'), :class => "map-toggle-button" ), | |
29 | - :class => 'list' , | |
30 | - } | |
31 | - end | |
32 | - | |
33 | - content_tag('div', data[:toggle] + (render :partial => data[:partial]), :class => "map-or-list-search-results #{data[:class]}") | |
21 | + content_tag('div', render(:partial => partial), :class => "map-or-list-search-results #{klass}") | |
34 | 22 | end |
35 | 23 | |
36 | - def product_categories_menu(asset, product_category, object_ids = nil) | |
37 | - cats = ProductCategory.menu_categories(@product_category, environment) | |
38 | - cats += cats.select { |c| c.children_count > 0 }.map(&:children).flatten | |
39 | - product_categories_ids = cats.map(&:id) | |
40 | - | |
41 | - counts = @noosfero_finder.product_categories_count(asset, product_categories_ids, object_ids) | |
42 | - | |
43 | - product_categories_menu = ProductCategory.menu_categories(product_category, environment).map do |cat| | |
44 | - hits = counts[cat.id] | |
45 | - childs = [] | |
46 | - if hits | |
47 | - if cat.children_count > 0 | |
48 | - childs = cat.children.map do |child| | |
49 | - child_hits = counts[child.id] | |
50 | - [child, child_hits] | |
51 | - end.select{|child, child_hits| child_hits } | |
52 | - else | |
53 | - childs = [] | |
54 | - end | |
55 | - end | |
56 | - [cat, hits, childs] | |
57 | - end.select{|cat, hits| hits } | |
24 | + def display_map_list_button | |
25 | + button(:search, params[:display] == 'map' ? _('Display in list') : _('Display in map'), | |
26 | + params.merge(:display => (params[:display] == 'map' ? 'list' : 'map')), | |
27 | + :class => "map-toggle-button" ) | |
28 | + end | |
58 | 29 | |
59 | - render(:partial => 'product_categories_menu', :object => product_categories_menu) | |
30 | + def city_with_state(city) | |
31 | + s = city.parent | |
32 | + if city and city.kind_of?(City) and s and s.kind_of?(State) and s.acronym | |
33 | + city.name + ', ' + s.acronym | |
34 | + else | |
35 | + city.name | |
36 | + end | |
60 | 37 | end |
61 | 38 | |
62 | 39 | def facets_menu(asset, _facets) |
... | ... | @@ -148,15 +125,15 @@ module SearchHelper |
148 | 125 | |
149 | 126 | def order_by(asset) |
150 | 127 | options = { |
151 | - :products => [[_('Best match'), ''], [_('Name'), 'name_sort asc'], [_('Lower price'), 'price asc'], [_('Higher price'), 'price desc']], | |
152 | - :events => [[_('Best match'), ''], [_('Name'), 'name_sort asc']], | |
153 | - :articles => [[_('Best match'), ''], [_('Name'), 'name_sort asc'], [_('Most recent'), 'updated_at desc']], | |
154 | - :enterprises => [[_('Best match'), ''], [_('Name'), 'name_sort asc']], | |
155 | - :people => [[_('Best match'), ''], [_('Name'), 'name_sort asc']], | |
156 | - :communities => [[_('Best match'), ''], [_('Name'), 'name_sort asc']], | |
128 | + :products => [[_('Relevance'), ''], [_('Name'), 'name_or_category_sort asc'], [_('Lower price'), 'price_sort asc'], [_('Higher price'), 'price_sort desc']], | |
129 | + :events => [[_('Relevance'), ''], [_('Name'), 'name_sort asc']], | |
130 | + :articles => [[_('Relevance'), ''], [_('Name'), 'name_sort asc'], [_('Most recent'), 'updated_at desc']], | |
131 | + :enterprises => [[_('Relevance'), ''], [_('Name'), 'name_sort asc']], | |
132 | + :people => [[_('Relevance'), ''], [_('Name'), 'name_sort asc']], | |
133 | + :communities => [[_('Relevance'), ''], [_('Name'), 'name_sort asc']], | |
157 | 134 | } |
158 | 135 | |
159 | - content_tag('div', _('Order by ') + | |
136 | + content_tag('div', _('Sort results by ') + | |
160 | 137 | select_tag(asset.to_s + '[order]', options_for_select(options[asset], params[:order_by]), |
161 | 138 | {:onchange => "window.location=jQuery.param.querystring(window.location.href, { 'order_by' : this.options[this.selectedIndex].value})"}), |
162 | 139 | :class => "search-ordering") |
... | ... | @@ -178,4 +155,5 @@ module SearchHelper |
178 | 155 | '' |
179 | 156 | end |
180 | 157 | end |
158 | + | |
181 | 159 | end | ... | ... |
app/models/article.rb
... | ... | @@ -139,11 +139,18 @@ class Article < ActiveRecord::Base |
139 | 139 | {:conditions => [ 'parent_id is null and profile_id = ?', profile.id ]} |
140 | 140 | } |
141 | 141 | |
142 | + named_scope :more_recent, | |
143 | + :conditions => [ "advertise = ? AND published = ? AND profiles.visible = ? AND profiles.public_profile = ? AND | |
144 | + ((articles.type != ?) OR articles.type is NULL)", | |
145 | + true, true, true, true, 'RssFeed' | |
146 | + ], | |
147 | + :order => 'articles.published_at desc, articles.id desc' | |
148 | + | |
142 | 149 | # retrieves the latest +limit+ articles, sorted from the most recent to the |
143 | 150 | # oldest. |
144 | 151 | # |
145 | 152 | # Only includes articles where advertise == true |
146 | - def self.recent(limit, extra_conditions = {}) | |
153 | + def self.recent(limit = nil, extra_conditions = {}) | |
147 | 154 | # FIXME this method is a horrible hack |
148 | 155 | options = { :limit => limit, |
149 | 156 | :conditions => [ |
... | ... | @@ -558,17 +565,53 @@ class Article < ActiveRecord::Base |
558 | 565 | end |
559 | 566 | |
560 | 567 | private |
568 | + | |
569 | + def self.f_type_proc(klass) | |
570 | + klass.constantize | |
571 | + h = { | |
572 | + 'UploadedFile' => _("Uploaded File"), | |
573 | + 'TextArticle' => _("Text"), | |
574 | + 'Folder' => _("Folder"), | |
575 | + 'Event' => _("Event"), | |
576 | + 'EnterpriseHomepage' => ("Homepage"), | |
577 | + 'Gallery' => ("Gallery"), | |
578 | + 'Blog' => ("Blog"), | |
579 | + 'Forum' => ("Forum") | |
580 | + } | |
581 | + h[klass] | |
582 | + end | |
583 | + def self.f_profile_type_proc(klass) | |
584 | + h = { | |
585 | + 'Enterprise' => _("Enterprise"), | |
586 | + 'Community' => _("Community"), | |
587 | + 'Person' => ("Person"), | |
588 | + 'BscPlugin::Bsc' => ("BSC") | |
589 | + } | |
590 | + h[klass] | |
591 | + end | |
592 | + | |
593 | + UploadedFile | |
594 | + TextArticle | |
595 | + TinyMceArticle | |
596 | + TextileArticle | |
597 | + Folder | |
598 | + EnterpriseHomepage | |
599 | + Gallery | |
600 | + Blog | |
601 | + Forum | |
602 | + Event | |
603 | + #excludes RssFeed | |
604 | + | |
561 | 605 | def f_type |
562 | - self.class.short_description | |
606 | + case self.class.to_s | |
607 | + when 'TinyMceArticle', 'TextileArticle' | |
608 | + 'TextArticle' | |
609 | + else | |
610 | + self.class.to_s | |
611 | + end | |
563 | 612 | end |
564 | - def f_publish_date | |
565 | - today = Date.today | |
566 | - range = '' | |
567 | - range = _('Last year') if (today-1.year..today).include?(self.published_at) | |
568 | - range = _('Last month') if (today-1.month..today).include?(self.published_at) | |
569 | - range = _('Last week') if (today-1.week..today).include?(self.published_at) | |
570 | - range = _('Last day') if (today-1.day..today).include?(self.published_at) | |
571 | - range | |
613 | + def f_published_at | |
614 | + self.published_at | |
572 | 615 | end |
573 | 616 | def f_profile_type |
574 | 617 | self.profile.class.to_s |
... | ... | @@ -579,16 +622,21 @@ class Article < ActiveRecord::Base |
579 | 622 | public |
580 | 623 | |
581 | 624 | acts_as_faceted :fields => { |
582 | - :f_type => {:label => _('Type')}, | |
583 | - :f_publish_date => {:label => _('Published')}, | |
584 | - :f_profile_type => {:label => _('Type of profile')}, | |
585 | - :f_category => {:label => _('Categories')}}, | |
586 | - :order => [:f_type, :f_publish_date, :f_profile_type, :f_category] | |
587 | - | |
588 | - acts_as_searchable :additional_fields => [ :comment_data, {:name => {:type => :string, :as => :name_sort, :boost => 5.0}} ] + facets.keys.map{|i| {i => :facet}}, | |
625 | + :f_type => {:label => _('Type'), :proc => proc{|klass| f_type_proc(klass)}}, | |
626 | + :f_published_at => {:type => :date, :label => _('Published date'), :queries => {'[* TO NOW-1YEARS/DAY]' => _("Older than one year"), | |
627 | + '[NOW-1YEARS TO NOW/DAY]' => _("Last year"), '[NOW-1MONTHS TO NOW/DAY]' => _("Last month"), '[NOW-7DAYS TO NOW/DAY]' => _("Last week"), '[NOW-1DAYS TO NOW/DAY]' => _("Last day")}, | |
628 | + :queries_order => ['[NOW-1DAYS TO NOW/DAY]', '[NOW-7DAYS TO NOW/DAY]', '[NOW-1MONTHS TO NOW/DAY]', '[NOW-1YEARS TO NOW/DAY]', '[* TO NOW-1YEARS/DAY]']}, | |
629 | + :f_profile_type => {:label => _('Profile'), :proc => proc{|klass| f_profile_type_proc(klass)}}, | |
630 | + :f_category => {:label => _('Categories')}}, | |
631 | + :category_query => proc { |c| "f_category:\"#{c.name}\"" }, | |
632 | + :order => [:f_type, :f_published_at, :f_profile_type, :f_category] | |
633 | + | |
634 | + acts_as_searchable :additional_fields => [ {:name => {:type => :string, :as => :name_sort, :boost => 5.0}} ] + facets_fields_for_solr, | |
635 | + :exclude_fields => [:setting], | |
589 | 636 | :include => [:profile], |
590 | - :facets => facets.keys, | |
591 | - :if => proc{|a| ! ['Feed'].include?(a.type)} | |
637 | + :facets => facets_option_for_solr, | |
638 | + :boost => proc {|a| 10 if a.profile.enabled}, | |
639 | + :if => proc{|a| ! ['RssFeed'].include?(a.class.name)} | |
592 | 640 | |
593 | 641 | private |
594 | 642 | ... | ... |
app/models/category.rb
... | ... | @@ -36,18 +36,38 @@ class Category < ActiveRecord::Base |
36 | 36 | { :conditions => [ "type IN (?) OR type IS NULL", types.reject{ |t| t.blank? } ] } |
37 | 37 | } |
38 | 38 | |
39 | + def recent_people(limit = 10) | |
40 | + self.people.paginate(:order => 'created_at DESC, id DESC', :page => 1, :per_page => limit) | |
41 | + end | |
42 | + | |
43 | + def recent_enterprises(limit = 10) | |
44 | + self.enterprises.paginate(:order => 'created_at DESC, id DESC', :page => 1, :per_page => limit) | |
45 | + end | |
46 | + | |
47 | + def recent_communities(limit = 10) | |
48 | + self.communities.paginate(:order => 'created_at DESC, id DESC', :page => 1, :per_page => limit) | |
49 | + end | |
50 | + | |
51 | + def recent_products(limit = 10) | |
52 | + self.products.paginate(:order => 'created_at DESC, id DESC', :page => 1, :per_page => limit) | |
53 | + end | |
54 | + | |
39 | 55 | def recent_articles(limit = 10) |
40 | 56 | self.articles.recent(limit) |
41 | 57 | end |
42 | 58 | |
43 | 59 | def recent_comments(limit = 10) |
44 | - comments.find(:all, :order => 'created_at DESC, comments.id DESC', :limit => limit) | |
60 | + comments.paginate(:all, :order => 'created_at DESC, comments.id DESC', :page => 1, :per_page => limit) | |
45 | 61 | end |
46 | 62 | |
47 | 63 | def most_commented_articles(limit = 10) |
48 | 64 | self.articles.most_commented(limit) |
49 | 65 | end |
50 | 66 | |
67 | + def upcoming_events(limit = 10) | |
68 | + self.events.find(:all, :conditions => [ 'start_date >= ?', Date.today ], :order => 'start_date') | |
69 | + end | |
70 | + | |
51 | 71 | def display_in_menu? |
52 | 72 | display_in_menu |
53 | 73 | end |
... | ... | @@ -64,10 +84,6 @@ class Category < ActiveRecord::Base |
64 | 84 | results |
65 | 85 | end |
66 | 86 | |
67 | - def root_parent | |
68 | - parent_id.nil? ? self : Category.find_by_id(parent_id).root_parent | |
69 | - end | |
70 | - | |
71 | 87 | def is_leaf_displayable_in_menu? |
72 | 88 | return false if self.display_in_menu == false |
73 | 89 | self.children.find(:all, :conditions => {:display_in_menu => true}).empty? | ... | ... |
app/models/environment.rb
... | ... | @@ -247,8 +247,9 @@ class Environment < ActiveRecord::Base |
247 | 247 | |
248 | 248 | settings_items :enabled_plugins, :type => Array, :default => [] |
249 | 249 | |
250 | - settings_items :search_products_hint, :type => String, :default => '' | |
251 | - settings_items :search_contents_hint, :type => String, :default => '' | |
250 | + settings_items :search_hints, :type => Hash, :default => {} | |
251 | + | |
252 | + settings_items :top_level_category_as_facet_ids, :type => Array, :default => [] | |
252 | 253 | |
253 | 254 | def news_amount_by_folder=(amount) |
254 | 255 | settings[:news_amount_by_folder] = amount.to_i | ... | ... |
app/views/layouts/application-ng.rhtml
... | ... | @@ -66,7 +66,7 @@ |
66 | 66 | </div> |
67 | 67 | </span> |
68 | 68 | <form action="/search" class="search_form" method="get" class="clean"> |
69 | - <input name="query" size="15" title="<%=_('Search...')%>" /> | |
69 | + <input name="query" size="15" title="<%=_('Search...')%>" onfocus="this.form.className='focused';" onblur="this.form.className=''" /> | |
70 | 70 | <div><%=_('Press <strong>Enter</strong> to send the search query.')%></div> |
71 | 71 | <%= javascript_tag 'jQuery("#user form input").hint();' %> |
72 | 72 | </form> | ... | ... |
app/views/search/_article.rhtml
1 | -<li class="article-item <%= icon_for_article(article) %>"> | |
2 | - <strong><%= link_to(article.title, article.url) %></strong> | |
3 | - <div class="article-item-meta"> | |
4 | - <% if article.body %> | |
5 | - <% body_stripped = strip_tags(article.body.to_s) %> | |
6 | - <br /><span class="article-item-body"><%= excerpt(body_stripped, body_stripped.first(3), 200) %></span><br /> | |
7 | - <% end %> | |
8 | - | |
9 | - <br /><span><%= _('Tags: ') + article.tags.join(', ') if !article.tags.empty? %></span> | |
10 | - | |
11 | - <br /><span><%=_('Author: ') %><%= link_to(article.profile.name, profile_path(:profile => article.profile)) %></span> | |
12 | - | |
13 | - <br /> | |
14 | - <% if article.last_changed_by %> | |
15 | - <span class="cat_item_by"><%= _('by %s') % link_to(article.last_changed_by.name, article.last_changed_by.url) %></span> | |
16 | - <% end %> | |
17 | - <span class="cat_item_update"><%= _('Last update: %s.') % show_date(article.updated_at) %></span> | |
1 | +<li class="search-article-item article-item"> | |
2 | + <%= link_to(article.title, article.url, :class => "search-result-title") %> | |
3 | + <div class="search-content-first-column"> | |
4 | + <%= render :partial => 'image', :object => article %> | |
5 | + </div> | |
6 | + <div class="search-content-second-column"> | |
18 | 7 | |
19 | - <br /> | |
20 | 8 | </div> |
9 | + <br class="clear"/> | |
21 | 10 | </li> | ... | ... |
... | ... | @@ -0,0 +1,8 @@ |
1 | +<% article = article_author %> | |
2 | + | |
3 | +<div class="search-article-author"> | |
4 | + <div class="search-article-author-name"> | |
5 | + <span class="search-field-label"><%= _("Author") %></span> | |
6 | + <%= link_to_profile article.profile.name, article.profile.identifier %> | |
7 | + </div> | |
8 | +</div> | ... | ... |
... | ... | @@ -0,0 +1,9 @@ |
1 | +<div class="search-article-categories"> | |
2 | + <span class="search-field-label"><%= _('Categories') %></span> | |
3 | + <span class="search-article-categories-container"> | |
4 | + <% article_categories.each do |category| %> | |
5 | + <%= link_to_category category, false, :class => "search-article-category" %> | |
6 | + <% end %> | |
7 | + <span class="search-field-none"><%= _('None') if article_categories.empty? %></span> | |
8 | + </span> | |
9 | +</div> | ... | ... |
... | ... | @@ -0,0 +1,7 @@ |
1 | +<% article = article_common %> | |
2 | + | |
3 | +<%= render :partial => 'article_author', :object => article %> | |
4 | +<%= render :partial => 'article_description', :object => article %> | |
5 | +<%= render :partial => 'article_tags', :object => article.tags %> | |
6 | +<%= render :partial => 'article_categories', :object => article.categories %> | |
7 | +<%= render :partial => 'article_last_change', :object => article %> | ... | ... |
... | ... | @@ -0,0 +1,11 @@ |
1 | +<% article = article_description %> | |
2 | + | |
3 | +<div class="search-article-description"> | |
4 | + <span class="search-field-label"><%= _("Description") %></span> | |
5 | + <% if !article.body.blank? %> | |
6 | + <% body_stripped = strip_tags(article.body.to_s) %> | |
7 | + <span class="article-item-body"><%= excerpt(body_stripped, body_stripped.first(3), 200) %></span> | |
8 | + <% else %> | |
9 | + <span class="search-field-none"><%= _('None') %></span> | |
10 | + <% end %> | |
11 | +</div> | ... | ... |
... | ... | @@ -0,0 +1,9 @@ |
1 | +<% article = article_last_change %> | |
2 | + | |
3 | +<div class="search-article-author-changes"> | |
4 | + <% if article.last_changed_by && article.last_changed_by != article.profile %> | |
5 | + <span><%= _('by %s') % link_to(article.last_changed_by.name, article.last_changed_by.url) %> <%= _(' at %s.') % show_date(article.updated_at) %></span> | |
6 | + <% else %> | |
7 | + <span><%= _('Last update: %s.') % show_date(article.updated_at) %></span> | |
8 | + <% end %> | |
9 | +</div> | ... | ... |
... | ... | @@ -0,0 +1,9 @@ |
1 | +<div class="search-article-tags"> | |
2 | + <span class="search-field-label"><%= _('Tags') %></span> | |
3 | + <span class="search-article-tags-container"> | |
4 | + <% article_tags.each do |tag| %> | |
5 | + <%= link_to_tag tag, :class => "search-article-tag" %> | |
6 | + <% end %> | |
7 | + <span class="search-field-none"><%= _('None') if article_tags.empty? %></span> | |
8 | + </span> | |
9 | +</div> | ... | ... |
... | ... | @@ -0,0 +1,23 @@ |
1 | +<li class="search-blog article-item"> | |
2 | + <%= link_to blog.title, blog.view_url, :class => 'search-result-title' %> | |
3 | + <div class="search-content-first-column"> | |
4 | + <%= render :partial => 'image', :object => blog %> | |
5 | + </div> | |
6 | + <div class="search-content-second-column"> | |
7 | + <div class="search-blog-items"> | |
8 | + <span class="search-field-label"><%= _("Last posts") %></span> | |
9 | + <% r = blog.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %> | |
10 | + <% r.each do |a| %> | |
11 | + <%= link_to a.title, a.view_url, :class => 'search-blog-sample-item '+icon_for_article(a) %> | |
12 | + <% end %> | |
13 | + <span class="search-field-none"><%= _('None') if r.empty? %></span> | |
14 | + </div> | |
15 | + | |
16 | + <%= render :partial => 'article_author', :object => blog %> | |
17 | + <%= render :partial => 'article_tags', :object => blog.tags %> | |
18 | + <%= render :partial => 'article_categories', :object => blog.categories %> | |
19 | + <%= render :partial => 'article_last_change', :object => blog %> | |
20 | + </div> | |
21 | + | |
22 | + <br class="clear"/> | |
23 | +</li> | ... | ... |
app/views/search/_display_results.rhtml
... | ... | @@ -4,45 +4,31 @@ |
4 | 4 | <% results = @results[name] %> |
5 | 5 | <% if !results.nil? and !results.empty? %> |
6 | 6 | <div class="search-results-<%= name %> search-results-box"> |
7 | - <% if @controller.action_name != 'assets' %> | |
8 | - <% if @results.size != 1 %> | |
9 | - <h3> | |
10 | - <%= @names[name] %> | |
11 | - </h3> | |
12 | - <% end %> | |
13 | - <%# FIXME: don't hardcode an asset like this %> | |
14 | - <% if name == :most_commented_articles %> | |
15 | - <%= link_to( results.respond_to?(:total_entries) ? _('see all (%d)') % results.total_entries : _('see all...'), | |
16 | - params.merge(:action => 'index', | |
17 | - :asset => 'articles' ), | |
18 | - :class => 'see-more' ) if @results.size > 1 %> | |
19 | 7 | |
20 | - <% else %> | |
21 | - <%= link_to( results.respond_to?(:total_entries) ? _('see all (%d)') % results.total_entries : _('see all...'), | |
22 | - params.merge(:action => 'index', | |
23 | - :asset => name ), | |
24 | - :class => 'see-more' ) if @results.size > 1 %> | |
25 | - <% end %> | |
8 | + <% if @results.size > 1 %> | |
9 | + <h3><%= @names[name] %></h3> | |
10 | + <%= link_to(results.respond_to?(:total_entries) ? _('see all (%d)') % results.total_entries : _('see all...'), | |
11 | + params.merge(:action => name), :class => 'see-more' ) %> | |
26 | 12 | <% end %> |
27 | - <% partial = partial_for_class results.first.class %> | |
13 | + | |
14 | + <% partial = partial_for_class(results.first.class.class_name.constantize) %> | |
28 | 15 | <div class="search-results-innerbox search-results-type-<%= partial %> <%= 'common-profile-list-block' if partial == 'profile' %>"> |
29 | 16 | <div class="search-results-innerbox2"><!-- the innerbox2 is a workarround for MSIE --> |
30 | 17 | <ul> |
31 | - <% results.each do |hit| %> | |
32 | - <% next if hit.respond_to?(:visible) && !hit.visible? %> | |
33 | - <%= render :partial => partial_for_class(hit.class), :object => hit %> | |
34 | - <% end %> | |
18 | + <% results.each do |hit| %> | |
19 | + <% next if hit.respond_to?(:visible) && !hit.visible? %> | |
20 | + <%= render :partial => partial_for_class(hit.class), :object => hit %> | |
21 | + <% end %> | |
35 | 22 | </ul> |
36 | 23 | <hr /> |
37 | 24 | </div><!-- end class="search-results-innerbox2" --> |
38 | 25 | </div><!-- end class="search-results-innerbox" --> |
26 | + | |
39 | 27 | </div><!-- end class="search-results-<%= name %>" --> |
40 | 28 | <% else %> |
41 | 29 | <div class="search-results-<%= name %> search-results-empty search-results-box"> |
42 | - <% if @controller.action_name != 'assets' %> | |
43 | - <% if @results.size != 1 %> | |
44 | - <h3><%= @names[name] %></h3> | |
45 | - <% end %> | |
30 | + <% if @results.size > 1 %> | |
31 | + <h3><%= @names[name] %></h3> | |
46 | 32 | <% end %> |
47 | 33 | <div class="search-results-innerbox search-results-type-empty"> |
48 | 34 | <div> <%= _('None') %> </div> |
... | ... | @@ -52,6 +38,6 @@ |
52 | 38 | <% end %> |
53 | 39 | <% end %> |
54 | 40 | |
55 | -<br style="clear:both" /> | |
41 | +<div style="clear:both"></div> | |
56 | 42 | </div><!-- end id="search-results" --> |
57 | 43 | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +<%= render :partial => 'text_article', :object => enterprise_homepage %> | ... | ... |
app/views/search/_event.rhtml
1 | -<li class="<%= icon_for_article(event) %>"> | |
2 | - <strong><%= link_to(event.title, event.url) %></strong> | |
3 | - <div class="item_meta"> | |
4 | - <%= show_period(event.start_date, event.end_date) %> | |
1 | +<li class="search-event-item article-item"> | |
2 | + <%= link_to(event.title, event.url, :class => "search-result-title") %> | |
3 | + <div class="search-content-first-column"> | |
4 | + <%= render :partial => 'image', :object => event %> | |
5 | 5 | </div> |
6 | + <div class="search-content-second-column"> | |
7 | + <% if event.body %> | |
8 | + <% body_stripped = strip_tags(event.body.to_s) %> | |
9 | + <div class="searc-article-event-date"> | |
10 | + <span class="article-item-body"><%= excerpt(body_stripped, body_stripped.first(3), 200) %></span> | |
11 | + </div> | |
12 | + <% end %> | |
13 | + <% if event.start_date %> | |
14 | + <div class="searc-article-event-date"> | |
15 | + <span class="search-field-label"><%= _('Start date') %></span> | |
16 | + <span class="article-item-date"><%= event.start_date %></span> | |
17 | + </div> | |
18 | + <% end %> | |
19 | + <% if event.end_date %> | |
20 | + <div class="searc-article-event-date"> | |
21 | + <span class="search-field-label"><%= _('End date') %></span> | |
22 | + <span class="article-item-date"><%= event.end_date %></span> | |
23 | + </div> | |
24 | + <% end %> | |
25 | + | |
26 | + <%= render :partial => 'article_common', :object => event %> | |
27 | + </div> | |
28 | + <br class="clear"/> | |
6 | 29 | </li> | ... | ... |
app/views/search/_facets_menu.rhtml
1 | -<% more_options = _("+ Options") %> | |
2 | -<% less_options = _("- Options") %> | |
3 | -<% less_options_limit = 7 %> | |
1 | +<% less_options_limit = 8 %> | |
4 | 2 | |
5 | 3 | <div id="facets-menu"> |
6 | - <% if !@facets["facet_fields"].empty? %> | |
7 | - <% @asset_class.each_facet do |facet_id, index| %> | |
8 | - <% facet = @asset_class.facets[facet_id] %> | |
9 | - <% solr_facet = @asset_class.to_solr_facet_fields[facet_id] %> | |
10 | - <% facets_all = @facets["facet_fields"][solr_facet] %> | |
11 | - <% facets_found = params[:facet] ? facets_all.reject {|name, count| params[:facet][facet_id.to_s].to_s == name.to_s } : facets_all %> | |
4 | + <% @asset_class.map_facets_for(environment).each do |facet| %> | |
12 | 5 | |
13 | - <% if facets_found and facets_found.count > 0 %> | |
14 | - <div id="facet-menu-<%= index.to_s %>" class="facet-menu"> | |
15 | - <div class="facet-menu-label"> | |
16 | - <%= facet[:label] %> | |
17 | - </div><br /> | |
6 | + <div id="facet-menu-<%= facet[:id].to_s %>" class="facet-menu"> | |
7 | + <div class="facet-menu-label"> | |
8 | + <%= facet[:label] %> | |
9 | + </div> | |
18 | 10 | |
19 | - <% if facets_found.count > less_options_limit %> | |
20 | - <div class="facet-menu-options facet-menu-more-options" style="display: none"> | |
21 | - <% array = [] %> | |
22 | - <% @asset_class.each_facet_name(solr_facet, facets_found, :sort => :alphabetically) do |name, count| %> | |
23 | - <% array << {:id => name, :name => link_to(name, params.merge({"facet[#{facet_id.to_s}]" => name})) + " (#{count})"} %> | |
24 | - <% end %> | |
11 | + <% results = @asset_class.map_facet_results(facet, params[:facet], @facets, @all_facets, :limit => less_options_limit) %> | |
12 | + <% facet_count = results.total_entries %> | |
25 | 13 | |
26 | - <%= text_field :facet, facet_id %> | |
27 | - <% javascript_tag do %> | |
28 | - jQuery.TokenList($("<%='facet_'+facet_id.to_s%>"), <%=array.to_json%>, {searchDelay: 0, permanentDropdown: true, theme: "facet", dontAdd: true, preventDuplicates: true}); | |
29 | - <% end %> | |
30 | - </div> | |
31 | - <% end %> | |
32 | - | |
33 | - <div class="facet-menu-options facet-menu-less-options"> | |
34 | - <% c = 0; @asset_class.each_facet_name(solr_facet, facets_found, :sort => :count) do |name, count| %> | |
35 | - <%= link_to(name, params.merge({"facet[#{facet_id.to_s}]" => name})) + " (#{count})" %><br /> | |
36 | - <% break if (c += 1) > less_options_limit %> | |
37 | - <% end %> | |
38 | - </div> <br /> | |
14 | + <% if facet_count > 0 %> | |
15 | + <div class="facet-menu-options facet-menu-more-options" style="display: none"> | |
16 | + </div> | |
39 | 17 | |
40 | - <% if facets_found.count > less_options_limit %> | |
41 | - <%= link_to_function more_options, "jQuery('#facet-menu-"+index.to_s+" .facet-menu-options').toggle(200); " + | |
42 | - "jQuery(this).text(jQuery(this).text() == '"+less_options+"' ? '"+more_options+"' : '"+less_options+"');" %> | |
43 | - <br /> | |
18 | + <div class="facet-menu-options facet-menu-less-options"> | |
19 | + <% results.each do |id, label, count| %> | |
20 | + <%= facet_link_html(facet, params, id, label, count) %><br /> | |
44 | 21 | <% end %> |
22 | + </div> <br /> | |
45 | 23 | |
24 | + <% if facet_count > less_options_limit %> | |
25 | + <%= link_to_function _("Options"), | |
26 | + "facet_options_toggle('#{facet[:id].to_s}', '#{url_for(params.merge(:action => 'facets_browse', :facet_id => facet[:id], :asset => @asset, :escape => false))}'); " + | |
27 | + "jQuery(this).toggleClass('facet-less-options')", :class => "facet-options-toggle" %> | |
46 | 28 | <br /> |
47 | - </div> | |
48 | 29 | <% end %> |
30 | + | |
31 | + <% else %> | |
32 | + <span class="facet-any-result-found"><%= _("No filter available") %></span> | |
49 | 33 | <% end %> |
50 | - <% end %> | |
51 | - </div> | |
34 | + </div> | |
35 | + <% end %> | |
36 | +</div> | ... | ... |
app/views/search/_facets_unselect_menu.rhtml
1 | - | |
2 | 1 | <div class="facets-applied"> |
3 | 2 | <% if params[:facet] and params[:facet].count > 0 %> |
4 | - <span class="appliedFilters"><%= _("Applied filters") %> </span> | |
5 | - <% params[:facet].each do |facet_id, name| %> | |
6 | - <%= link_to(name, params.merge(:facet => params[:facet].reject {|k,v| k == facet_id}), :class => 'facet-selected') %> | |
7 | - <% end %> | |
3 | + <span class="facets-applied-label"><%= _("Applied filters") %> </span> | |
4 | + <%= facet_selecteds_html_for(environment, asset_class(@asset), params) %> | |
8 | 5 | <% end %> |
9 | 6 | </div> | ... | ... |
... | ... | @@ -0,0 +1,19 @@ |
1 | +<li class="search-folder-item article-item"> | |
2 | + <%= link_to folder.title, folder.view_url, :class => 'search-result-title' %> | |
3 | + <div class="search-content-first-column"> | |
4 | + <%= render :partial => 'image', :object => folder %> | |
5 | + </div> | |
6 | + <div class="search-content-second-column"> | |
7 | + <div class="search-folder-items"> | |
8 | + <span class="search-field-label"><%= _("Last items") %></span> | |
9 | + <% r = folder.children.last(3) %> | |
10 | + <% r.each do |a| %> | |
11 | + <%= link_to a.title, a.view_url, :class => 'search-folder-sample-item '+icon_for_article(a) %> | |
12 | + <% end %> | |
13 | + <span class="search-field-none"><%= _('None') if r.empty? %></span> | |
14 | + </div> | |
15 | + | |
16 | + <%= render :partial => 'article_common', :object => folder %> | |
17 | + </div> | |
18 | + <br class="clear"/> | |
19 | +</li> | ... | ... |
... | ... | @@ -0,0 +1,20 @@ |
1 | +<li class="search-forum-item article-item"> | |
2 | + <%= link_to forum.title, forum.view_url, :class => 'search-result-title' %> | |
3 | + <div class="search-content-first-column"> | |
4 | + <%= render :partial => 'image', :object => forum %> | |
5 | + </div> | |
6 | + <div class="search-content-second-column"> | |
7 | + <div class="search-forum-items"> | |
8 | + <span class="search-field-label"><%= _("Last topics") %></span> | |
9 | + <% r = forum.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %> | |
10 | + <% r.each do |a| %> | |
11 | + <%= link_to a.title, a.view_url, :class => 'search-forum-sample-item '+icon_for_article(a) %> | |
12 | + <% end %> | |
13 | + <span class="search-field-none"><%= _('None') if r.empty? %></span> | |
14 | + </div> | |
15 | + | |
16 | + <%= render :partial => 'article_common', :object => forum %> | |
17 | + </div> | |
18 | + | |
19 | + <br class="clear"/> | |
20 | +</li> | ... | ... |
... | ... | @@ -0,0 +1,10 @@ |
1 | +<li class="search-gallery article-item"> | |
2 | + <%= link_to gallery.title, gallery.view_url, :class => 'search-result-title' %> | |
3 | + <div class="search-content-first-column"> | |
4 | + <%= render :partial => 'image', :object => gallery %> | |
5 | + </div> | |
6 | + <div class="search-content-second-column"> | |
7 | + <%= render :partial => 'article_common', :object => gallery %> | |
8 | + </div> | |
9 | + <br class="clear"/> | |
10 | +</li> | ... | ... |
... | ... | @@ -0,0 +1,47 @@ |
1 | +<div class="search-image-container"> | |
2 | + | |
3 | + <% if image.is_a? UploadedFile %> | |
4 | + <% extension = image.filename[(image.filename.rindex('.')+1)..-1].downcase %> | |
5 | + <% if ['jpg', 'jpeg', 'gif', 'png', 'tiff', 'svg'].include? extension %> | |
6 | + <%= link_to '', image.view_url, :class => "search-image-pic", :style => 'background-image: url(%s)'% image.public_filename(:thumb) %> | |
7 | + <% if image.width && image.height %> | |
8 | + <% javascript_tag do %> | |
9 | + image = jQuery('script').last().parent().find('.search-image-pic'); | |
10 | + des_width = parseInt(image.css('width')); | |
11 | + des_height = parseInt(image.css('height')); | |
12 | + | |
13 | + width = <%= image.width %>; | |
14 | + height = <%= image.height %>; | |
15 | + scale_factor = width > height ? des_width/width : des_height/height; | |
16 | + | |
17 | + image.css({'width' : scale_factor*width +'px', 'height' : scale_factor*height+'px'}); | |
18 | + <% end %> | |
19 | + <% end %> | |
20 | + <% elsif ['pdf'].include? extension %> | |
21 | + <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-pdf' %> | |
22 | + <% elsif ['doc', 'docx', 'odt', 'rtf', 'txt', 'html', 'htm'].include? extension %> | |
23 | + <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-vnd-oasis-opendocument-text' %> | |
24 | + <% elsif ['xls', 'xlsx', 'ods', 'csv', 'tsv', 'tab'].include? extension %> | |
25 | + <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-vnd-oasis-opendocument-spreadsheet' %> | |
26 | + <% end %> | |
27 | + <% elsif image.is_a? Gallery %> | |
28 | + <div class="search-gallery-items"> | |
29 | + <% r = image.children.find(:all, :order => :updated_at, :conditions => ['type = ?', 'UploadedFile']).last(3) %> | |
30 | + <% if r.length > 0 %> | |
31 | + <% r.each do |i| %> | |
32 | + <%= link_to '', i.view_url, :class => "search-image-pic", :style => 'background-image: url(%s)'% i.public_filename(:thumb) %> | |
33 | + <% end %> | |
34 | + <% else %> | |
35 | + <div class="search-no-image"><%= _('No image') %></div> | |
36 | + <% end %> | |
37 | + </div> | |
38 | + <% elsif image.is_a? Product %> | |
39 | + <% if image.image %> | |
40 | + <%= link_to '', product_path(image), :class => "search-image-pic", :style => 'background-image: url(%s)'% image.default_image(:thumb) %> | |
41 | + <% else %> | |
42 | + <div class="search-no-image"><%= _('No image') %></div> | |
43 | + <% end %> | |
44 | + <% else %> | |
45 | + <div class="search-content-type-icon icon-content-<%=image.class.to_s.underscore.dasherize%>"></div> | |
46 | + <% end %> | |
47 | +</div> | ... | ... |
app/views/search/_product.rhtml
1 | 1 | <% extra_content = @plugins.map(:asset_product_extras, product, product.enterprise).collect { |content| instance_eval(&content) } %> |
2 | 2 | <% extra_properties = @plugins.map(:asset_product_properties, product)%> |
3 | 3 | |
4 | -<li class="product-item"> | |
5 | - <div class="product-item-first-column"> | |
6 | - <%= link_to_product product, :class => 'product-pic', :style => 'background-image:url(%s)' % product.default_image(:minor) %> | |
7 | - <%= product.price if product.price %> | |
4 | +<li class="search-product-item"> | |
5 | + <div class="search-product-item-first-column"> | |
6 | + <%= render :partial => 'image', :object => product %> | |
7 | + | |
8 | + <% if product.available %> | |
9 | + <% if product.price && product.price > 0 %> | |
10 | + <% has_discount = product.discount && product.discount > 0 %> | |
11 | + <% if product.price %> | |
12 | + <span class="search-product-price-textid"><%=_("from") if has_discount %></span><%= price_span(product.price, :class => "search-product-price " + (has_discount ? 'with-discount' : '')) %> | |
13 | + <% if has_discount %> | |
14 | + <span class="search-product-price-textid"><%=_("by")%></span><%= price_span(product.price_with_discount, :class => "search-product-price") %> | |
15 | + <% end %> | |
16 | + <% if product.unit %> | |
17 | + <span class="search-product-unit"> <%= _('/') %> <%= product.unit.name %></span> | |
18 | + <% end %> | |
19 | + <% end %> | |
20 | + <div class="search-product-inputs-info"> | |
21 | + <% if product.inputs.count > product.inputs.collect(&:is_from_solidarity_economy).count(nil) %> | |
22 | + <% se_i = t_i = 0 %> | |
23 | + <% product.inputs.each{ |i| t_i += 1; se_i += 1 if i.is_from_solidarity_economy } %> | |
24 | + <% p = case (se_i.to_f/t_i)*100 when 0..24.999 then ["0", _("0%")]; when 25..49.999 then ["25", _("25%")]; when 50..74.999 then ["50", _("50%")]; when 75..100 then ["75", _("100%")]; end %> | |
25 | + <div class="search-product-percentage-from-solidarity-economy search-product-ecosol-percentage-icon-<%=p[0]%>" title="<%=_('Percentage of inputs from solidarity economy')%>"> | |
26 | + <%= p[1] %> | |
27 | + </div> | |
28 | + <% end %> | |
29 | + | |
30 | + <% if product.inputs.count == product.inputs.collect(&:has_price_details?).count(true) %> | |
31 | + <% title = product.inputs.map{ |i| | |
32 | + '<div class="search-product-input-dots-to-price">' + | |
33 | + '<div class="search-product-input-name">' + i.product_category.name + '</div>' + | |
34 | + price_span(i.price_per_unit*i.amount_used, :class => 'search-product-input-price') + | |
35 | + '</div>' }.join('') %> | |
36 | + <%= link_to_function _("Open Price"), '', :title => title, :class => "search-product-price-details" %> | |
37 | + <% end %> | |
38 | + </div> | |
39 | + <% end %> | |
40 | + <% else %> | |
41 | + <span class="product-not-available"><%= _('Not available') %></div> | |
42 | + <% end %> | |
43 | + | |
8 | 44 | </div> |
9 | - <div class="product-item-second-column"> | |
10 | - <span class='product-title-link'><%= link_to_product product %></span> | |
11 | - <div class="product-supplier"> | |
12 | - <span class="product-item-topic"><%= _('SUPPLIER') %> </span><%= link_to_homepage(product.enterprise.name, product.enterprise.identifier) %> | |
45 | + <div class="search-product-item-second-column"> | |
46 | + <%= link_to_product product, :class => 'search-result-title' %> | |
47 | + <div class="search-product-supplier"> | |
48 | + <span class="search-field-label"><%= _('Supplier') %> </span><%= link_to_homepage(product.enterprise.name, product.enterprise.identifier) %> | |
13 | 49 | </div> |
14 | - <div class="product-description"> | |
50 | + <div class="search-product-description"> | |
15 | 51 | <% if product.description %> |
16 | 52 | <% desc_stripped = strip_tags(product.description) %> |
17 | - <span class="product-item-topic"><%= _('DESCRIPTION') %> </span><%= excerpt(desc_stripped, desc_stripped.first(3), 100) %> | |
53 | + <span class="search-field-label"><%= _('Description') %> </span><%= excerpt(desc_stripped, desc_stripped.first(3), 300) %> | |
18 | 54 | <% end %> |
19 | 55 | </div> |
20 | 56 | </div> |
21 | - <div class="product-item-third-column"> | |
22 | - <div class="product-region"> | |
57 | + <div class="search-product-item-third-column"> | |
58 | + <div class="search-product-region"> | |
23 | 59 | <% if product.enterprise.region %> |
24 | - <span class="product-item-topic"><%= _('REGION') %></span> | |
25 | - <br /><%= product.enterprise.region.name %> | |
60 | + <span class="search-field-label"><%= _('City') %></span> | |
61 | + <br /><%= city_with_state(product.enterprise.region) %> | |
26 | 62 | <% end %> |
27 | 63 | </div> |
28 | - <div class="product-qualifiers"> | |
64 | + <div class="search-product-qualifiers"> | |
29 | 65 | <% if product.product_qualifiers.count > 0 %> |
30 | - <span class="product-item-topic"><%= _('QUALIFIERS') %></span> | |
66 | + <span class="search-field-label"><%= _('Qualifiers') %></span> | |
31 | 67 | <% product.product_qualifiers.each do |pq| %> |
32 | 68 | <% if pq.qualifier %> |
33 | - <br /><%= pq.qualifier.name %> | |
69 | + <span class="search-product-qualifier"><%= pq.qualifier.name + (pq.certifier.nil? ? _(";") : '') %></span> | |
34 | 70 | <% end %> |
35 | 71 | <% if pq.certifier %> |
36 | - <br /><%= pq.certifier.name %> | |
72 | + <span class="search-product-certifier"> <%= _('cert. ') + pq.certifier.name + _(";") %></span> | |
37 | 73 | <% end %> |
38 | 74 | <% end %> |
39 | 75 | <% end %> | ... | ... |
app/views/search/_profile.rhtml
1 | -<% if @query.blank? || !profile.enterprise? %> | |
2 | - <%= profile_image_link profile, :portrait %> | |
3 | -<% else %> | |
4 | - <div class="enterprise-result"> | |
5 | - <%= profile_image_link profile, :portrait %> | |
6 | - <span><%= profile.name %></span> | |
7 | - <span><%= _("Region: ") + profile.region.name if profile.region %></span><br /> | |
8 | - <% if !profile.description.blank? %> | |
9 | - <span><%= profile.description %></span><br /> | |
10 | - <% end %> | |
1 | +<li class="search-profile-item"> | |
2 | + <% if @empty_query or @results.size > 1 or !profile.enterprise? %> | |
3 | + <%= profile_image_link profile, :portrait, 'div' %> | |
4 | + <% else %> | |
5 | + <div class="search-enterprise-item"> | |
6 | + <div class="search-enterprise-item-column-left"> | |
7 | + <%= profile_image_link profile, :portrait, 'div' %> | |
8 | + </div> | |
9 | + <div class="search-enterprise-item-column-right"> | |
10 | + <%= link_to_homepage(profile.name, profile.identifier, :class => "search-result-title") %> | |
11 | + <div class="search-enterprise-description"> | |
12 | + <% if profile.description %> | |
13 | + <% body_stripped = strip_tags(profile.description) %> | |
14 | + <% elsif profile.home_page and profile.home_page.body %> | |
15 | + <% body_stripped = strip_tags(profile.home_page.body) %> | |
16 | + <% end %> | |
17 | + <%= excerpt(body_stripped, body_stripped.first(3), 200) if body_stripped %> | |
18 | + </div> | |
19 | + <div class="search-enterprise-region"> | |
20 | + <span class="search-enterprise-region-label"><%= _("City") %></span> | |
21 | + <% if profile.region %> | |
22 | + <span class="search-enterprise-region-name"><%= city_with_state(profile.region) %></span> | |
23 | + <% else %> | |
24 | + <% end %> | |
25 | + </div> | |
26 | + <% if !profile.description.blank? %> | |
27 | + <div><%= profile.description %></div><br /> | |
28 | + <% end %> | |
11 | 29 | |
12 | - <div class="enterprise-categorization"> | |
13 | - <% profile.top_level_categorization.each do |parent, children| %> | |
14 | - <span class="enterprise-categorization-parent"><%= parent.name + ':' %></span> | |
15 | - <span class="enterprise-categorization-children"><%= children.collect(&:name).join(', ') %></span> | |
16 | - <br /> | |
17 | - <% end %> | |
18 | - </div> | |
19 | - </div> | |
20 | -<% end %> | |
30 | + <div class="search-enterprise-categorization"> | |
31 | + <% profile.top_level_categorization.each do |parent, children| %> | |
32 | + <div class="search-enterprise-category-<%=parent.id%> search-enterprise-category"> | |
33 | + <span class="search-enterprise-categorization-parent"><%= parent.name %></span> | |
34 | + <span class="search-enterprise-categorization-children"><%= children.collect(&:name).join(', ') %></span> | |
35 | + </div> | |
36 | + <% end %> | |
37 | + </div> | |
38 | + </div> | |
39 | + <hr class="clearfix" /> | |
40 | + </div> | |
41 | + <% end %> | |
42 | +</li> | ... | ... |
app/views/search/_results_header.rhtml
1 | -<div class="results-header"> | |
2 | - <%= label_total_found(asset, results.total_entries) %> | |
3 | - <% if params[:display] != 'map' %> | |
4 | - <span class="current-page"><%= _("Showing page %s of %s") % [results.current_page, results.total_pages] %></span> | |
5 | - <% end %> | |
1 | +<div class="search-results-header <%= "search-no-results" if @results[@asset].nil? or @results[@asset].length == 0 %>"> | |
2 | + <% if !@empty_query %> | |
3 | + <div class="search-results-header-information"> | |
4 | + <%= label_total_found(asset, results.total_entries) %> | |
5 | + <% if params[:display] != 'map' %> | |
6 | + <span class="current-page"><%= _("Showing page %s of %s") % [results.current_page, results.total_pages] %></span> | |
7 | + <% end %> | |
8 | + </div> | |
6 | 9 | |
7 | - <%= facets_unselect_menu(asset) %> | |
10 | + <div class="search-results-header-facets-order-by"> | |
11 | + <%= facets_unselect_menu(asset) %> | |
12 | + <%= order_by(asset) if params[:display] != 'map' %> | |
13 | + </div> | |
14 | + <% else %> | |
15 | + <div id='search-filter-title'><%= @filter_title if @filter_title %></div> | |
16 | + <% end %> | |
8 | 17 | |
9 | - <%= order_by(asset) if params[:display] != 'map' %> | |
18 | + <div style="clear: both"></div> | |
10 | 19 | </div> | ... | ... |
app/views/search/_search_form.rhtml
... | ... | @@ -3,26 +3,36 @@ |
3 | 3 | |
4 | 4 | <% form_tag( { :controller => 'search', :action => @asset ? @asset : 'index', :asset => nil, :category_path => ( @category ? @category.explode_path : [] ) }, |
5 | 5 | :method => 'get', :class => 'search_form' ) do %> |
6 | - <%= '<h3>%s</h3>' % form_title if defined? form_title %> | |
7 | 6 | |
8 | 7 | <%= hidden_field_tag :display, params[:display] %> |
9 | 8 | |
10 | - <%= hidden_field_tag :asset, params[:asset] %> | |
11 | - | |
12 | 9 | <div class="search-field"> |
13 | 10 | <span class="formfield"> |
14 | - <%= text_field_tag 'query', @query, :id => ( lightbox? ? 'popup-search-input' : '' ), :size => 50 %> | |
15 | - <%= javascript_tag 'setTimeout("$(\"popup-search-input\").focus()", 10 )' if lightbox? %> | |
11 | + <%= text_field_tag 'query', @query, :id => 'search-input', :size => 50 %> | |
12 | + <%= javascript_tag "jQuery('#search-input').attr('title', \"#{hint}\").hint()" if defined?(hint) %> | |
13 | + <%= javascript_tag "jQuery('.search_form').submit(function() { | |
14 | + if (jQuery('#search-input').val().length < 3) { | |
15 | + jQuery('#search-empty-query-error').slideDown(200).delay(2500).slideUp(200); | |
16 | + return false; | |
17 | + } | |
18 | + });" %> | |
16 | 19 | </span> |
17 | - <%= submit_button(:search, _('Search'), :name => :search_whole_site_no) %> | |
18 | - <% if @category %> | |
19 | - <%= submit_button(:search, _('Search in whole site'), :name => :search_whole_site_yes) %> | |
20 | - <% end %> | |
20 | + | |
21 | + <%= submit_button(:search, _('Search')) %> | |
22 | + | |
23 | + <div id="search-empty-query-error"> | |
24 | + <%= _("Type more than 2 characters to start a search") %> | |
25 | + </div> | |
21 | 26 | </div> |
22 | 27 | |
23 | - <% if lightbox?; button_bar do %> | |
24 | - <%= lightbox_close_button _('Close') %> | |
25 | - <% end; end %> | |
28 | + <% if @empty_query %> | |
29 | + <% hint = environment.search_hints[@asset] %> | |
30 | + <% if hint and !hint.blank? %> | |
31 | + <span class="search-hint"><%= hint %></span> | |
32 | + <% end %> | |
33 | + <% end %> | |
34 | + | |
35 | + <div style="clear: both"></div> | |
26 | 36 | |
27 | 37 | <% end %> |
28 | 38 | ... | ... |
... | ... | @@ -0,0 +1,10 @@ |
1 | +<li class="search-text-article-item article-item"> | |
2 | + <%= link_to(text_article.title, text_article.url, :class => "search-result-title") %> | |
3 | + <div class="search-content-first-column"> | |
4 | + <%= render :partial => 'image', :object => text_article %> | |
5 | + </div> | |
6 | + <div class="search-content-second-column"> | |
7 | + <%= render :partial => 'article_common', :object => text_article %> | |
8 | + </div> | |
9 | + <br class="clear"/> | |
10 | +</li> | ... | ... |
... | ... | @@ -0,0 +1,36 @@ |
1 | +<li class="search-uploaded-file-item article-item"> | |
2 | + <%= link_to uploaded_file.filename, uploaded_file.view_url, :class => 'search-result-title' %> | |
3 | + <hr class="clear" /> | |
4 | + | |
5 | + <div class="search-content-first-column"> | |
6 | + <%= render :partial => 'image', :object => uploaded_file %> | |
7 | + </div> | |
8 | + | |
9 | + <div class="search-uploaded-file-second-column"> | |
10 | + <%= render :partial => 'article_author', :object => uploaded_file %> | |
11 | + | |
12 | + <div class="search-uploaded-file-description"> | |
13 | + <% if !uploaded_file.body.blank? %> | |
14 | + <span class="search-field-label"><%= _("Description") %></span> | |
15 | + <% body = strip_tags(uploaded_file.body.to_s) %> | |
16 | + <%= excerpt(body, body.first(3), 200) %> | |
17 | + <% end %> | |
18 | + </div> | |
19 | + | |
20 | + <div class="search-uploaded-file-parent"> | |
21 | + <% if uploaded_file.parent && uploaded_file.parent.published? %> | |
22 | + <% if uploaded_file.parent.gallery? %> | |
23 | + <span class="search-field-label"><%= _("Gallery") %></span> | |
24 | + <% else %> | |
25 | + <span class="search-field-label"><%= _("Folder") %></span> | |
26 | + <% end %> | |
27 | + <%= link_to uploaded_file.parent.name, {:controller => 'content_viewer', :profile => uploaded_file.profile.identifier, :action => 'view_page', :page => [uploaded_file.parent.slug]} %> | |
28 | + <% end %> | |
29 | + </div> | |
30 | + | |
31 | + <%= render :partial => 'article_tags', :object => uploaded_file.tags %> | |
32 | + <%= render :partial => 'article_categories', :object => uploaded_file.categories %> | |
33 | + <%= render :partial => 'article_last_change', :object => uploaded_file %> | |
34 | + </div> | |
35 | + <br style="clear: both"/> | |
36 | +</li> | ... | ... |
app/views/search/articles.rhtml
1 | -<%= search_page_title( _('Articles'), { :query => @query, | |
2 | - :total_results => @total_results } ) %> | |
1 | +<%= search_page_title( @titles[:articles], @category ) %> | |
3 | 2 | |
4 | -<%= search_page_link_to_all( { :asset => params[:asset], | |
5 | - :category => @category }) %> | |
3 | +<div id="search-column-left"> | |
4 | + <% if !@empty_query %> | |
5 | + <%= facets_menu(:articles, @facets) %> | |
6 | + <% end %> | |
7 | +</div> | |
6 | 8 | |
7 | -<%= render :partial => 'search_form', :locals => { :form_title => @query.blank? ? _('Search') : _("Refine your search"), :simple_search => true } %> | |
9 | +<div id="search-column-right"> | |
10 | + <%= render :partial => 'search_form', :locals => { :form_title => _('Search'), :simple_search => true, | |
11 | + :hint => _('Type the title, author or content desired') } %> | |
12 | + <%= render :partial => 'results_header', :locals => { :asset => :articles, :results => @results[:articles] } %> | |
8 | 13 | |
9 | -<% if !@query.blank? %> | |
10 | - <%= facets_menu(:articles, @facets) %> | |
11 | -<% end %> | |
12 | - | |
13 | -<%= render :partial => 'results_header', :locals => { :asset => :articles, :results => @results[:articles] } %> | |
14 | - | |
15 | -<%# FIXME ARMENGUE %> | |
16 | -<%= display_results(false) %> | |
17 | - | |
18 | -<%= pagination_links @results.values.first %> | |
14 | + <% if !@empty_query or @filter %> | |
15 | + <%= display_results %> | |
16 | + <%= pagination_links @results.values.first %> | |
17 | + <% end %> | |
18 | +</div> | |
19 | 19 | |
20 | 20 | <br style="clear:both" /> | ... | ... |
app/views/search/category_index.rhtml
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | <div id="category-image"><%= image_tag(@category.image.public_filename(:thumb), :id => 'category-image') if @category.image %></div> |
4 | 4 | <h1 id="category-name"><%= @category.name %></h1> |
5 | 5 | |
6 | - <%= render :partial => 'display_results' %> | |
6 | + <%= display_results %> | |
7 | 7 | |
8 | 8 | <div id="category-childs"> |
9 | 9 | <h2> <%= _('Sub-categories') %> </h2> | ... | ... |
app/views/search/communities.rhtml
1 | -<%= search_page_title( __('Communities'), { :query => @query, | |
2 | - :total_results => @total_results } ) %> | |
1 | +<%= search_page_title( @titles[:communities], @category ) %> | |
3 | 2 | |
4 | -<%= search_page_link_to_all( { :asset => params[:asset], | |
5 | - :category => @category }) %> | |
6 | -<%= render :partial => 'search_form', :locals => { :form_title => @query.blank? ? _('Search') : _("Refine your search"), :simple_search => true } %> | |
7 | - | |
8 | -<% if logged_in? %> | |
9 | - <% button_bar do %> | |
10 | - <%# FIXME shouldn't the user create the community in the current environment instead of going to its home environment? %> | |
11 | - <%= button(:add, __('New community'), user.url.merge(:controller => 'memberships', :action => 'new_community')) %> | |
3 | +<div id='search-column-left'> | |
4 | + <% if logged_in? %> | |
5 | + <% button_bar do %> | |
6 | + <%# FIXME shouldn't the user create the community in the current environment instead of going to its home environment? %> | |
7 | + <%= button(:add, __('New community'), user.url.merge(:controller => 'memberships', :action => 'new_community')) %> | |
8 | + <% end %> | |
12 | 9 | <% end %> |
13 | -<% end %> | |
14 | 10 | |
15 | -<% if !@query.blank? %> | |
16 | - <%= facets_menu(:communities, @facets) %> | |
17 | -<% end %> | |
18 | -<%= render :partial => 'results_header', :locals => { :asset => :communities, :results => @results[:communities] } %> | |
11 | + <% if !@empty_query %> | |
12 | + <%= facets_menu(:communities, @facets) %> | |
13 | + <% end %> | |
14 | +</div> | |
19 | 15 | |
20 | -<div id='search-results-and-pages'> | |
21 | - <%# FIXME ARMENGUE %> | |
22 | - <%= display_results(false) %> | |
16 | +<div id='search-column-right'> | |
17 | + <%= render :partial => 'search_form', :locals => { :form_title => _('Search'), :simple_search => true, | |
18 | + :hint => _("Type words about the community you're looking for") } %> | |
19 | + <%= render :partial => 'results_header', :locals => { :asset => :communities, :results => @results[:communities] } %> | |
23 | 20 | |
24 | - <% if params[:display] != 'map' %> | |
25 | - <%= pagination_links @results.values.first %> | |
26 | - <% end %> | |
21 | + <%= display_results %> | |
22 | + <%= pagination_links @results.values.first %> | |
27 | 23 | </div> |
28 | 24 | |
29 | 25 | <br style="clear:both" /> | ... | ... |
app/views/search/enterprises.rhtml
1 | -<h1> | |
2 | - <% if !@query.blank? %> | |
3 | - <%=h @category ? (__('Enterprise results for "%{query}" in "%{category}"') % { :query => @query, :category => @category.name}) : (__('Enterprise results for "%s"') % @query) %> | |
4 | - <% else %> | |
5 | - <%=h @category ? (__('Enterprises in "%s"') % @category.name) : __('Enterprises') %> | |
6 | - <% end %> | |
7 | -</h1> | |
8 | - | |
9 | -<%= search_page_link_to_all( { :asset => params[:asset] }) %> | |
1 | +<%= search_page_title( @titles[:enterprises], @category ) %> | |
10 | 2 | |
11 | -<%= render :partial => 'search_form', :locals => { :form_title => _("Refine your search"), :simple_search => true } %> | |
12 | - | |
13 | -<% if logged_in? && environment.enabled?('enterprise_registration') %> | |
14 | - <% button_bar do %> | |
15 | - <%= button(:add, __('New enterprise'), {:controller => 'enterprise_registration'}) %> | |
3 | +<div id="search-column-left"> | |
4 | + <% if logged_in? && environment.enabled?('enterprise_registration') %> | |
5 | + <% button_bar do %> | |
6 | + <%= button(:add, __('New enterprise'), {:controller => 'enterprise_registration'}) %> | |
7 | + <% end %> | |
16 | 8 | <% end %> |
17 | -<% end %> | |
18 | - | |
19 | -<% if @categories_menu %> | |
20 | -<div class="has_cat_list"> | |
21 | -<% end %> | |
22 | 9 | |
23 | -<% cache(:action => 'assets', :asset => 'enterprises', :query => @query) do %> | |
24 | - <% if !@query.blank? %> | |
10 | + <% if !@empty_query %> | |
11 | + <% button_bar do %> | |
12 | + <%= display_map_list_button %> | |
13 | + <% end %> | |
25 | 14 | <%= facets_menu(:enterprises, @facets) %> |
26 | 15 | <% end %> |
27 | -<% end %> | |
16 | +</div> | |
28 | 17 | |
29 | -<%= render :partial => 'results_header', :locals => { :asset => :enterprises, :results => @results[:enterprises] } %> | |
18 | +<div id="search-column-right"> | |
19 | + <%= render :partial => 'search_form', :locals => { :form_title => _('Search'), :simple_search => true, | |
20 | + :hint => _("Type words about the enterprise you're looking for") } %> | |
21 | + <%= render :partial => 'results_header', :locals => { :asset => :enterprises, :results => @results[:enterprises] } %> | |
30 | 22 | |
31 | -<%= display_results %> | |
32 | - | |
33 | -<% if @categories_menu %> | |
34 | -</div><!-- class="has_cat_list" --> | |
35 | -<% end %> | |
36 | - | |
37 | -<% if params[:display] != 'map' %> | |
38 | - <%= pagination_links @results[:enterprises] %> | |
39 | -<% end %> | |
23 | + <%= display_results(true) %> | |
24 | + <% if params[:display] != 'map' %> | |
25 | + <%= pagination_links @results[:enterprises] %> | |
26 | + <% end %> | |
27 | +</div> | |
40 | 28 | |
41 | 29 | <br style="clear:both" /> | ... | ... |
app/views/search/events.rhtml
... | ... | @@ -0,0 +1,8 @@ |
1 | +<% results = @asset_class.map_facet_results(@facet, params[:facet], @facets, @all_facets) %> | |
2 | + | |
3 | +<% array = [] %> | |
4 | +<% @asset_class.facet_result_sort(@facet, results, :alphabetically).each do |id, label, count| %> | |
5 | + <% array << {:id => id, :name => facet_link_html(@facet, params.merge(:controller => 'search', :action => @asset), id, label, count)} %> | |
6 | +<% end %> | |
7 | + | |
8 | +<%= facet_javascript('facet-input-'+@facet[:id].to_s, @facet, array) %> | ... | ... |
app/views/search/index.rhtml
1 | 1 | <div id="search-page"> |
2 | 2 | |
3 | -<%= search_page_title(_('Search Results'), :query => CGI.escapeHTML(@query), | |
4 | - :total_results => @total_results) %> | |
3 | +<%= search_page_title(_('Search Results'), @category) %> | |
5 | 4 | |
6 | 5 | <%= render :partial => 'search_form', :locals => { :form_title => _("Refine your search"), :simple_search => true } %> |
7 | 6 | ... | ... |
app/views/search/people.rhtml
1 | -<%= search_page_title( _('People'), { :query => @query, | |
2 | - :total_results => @total_results } ) %> | |
1 | +<%= search_page_title( @titles[:people], @category ) %> | |
3 | 2 | |
4 | -<%= search_page_link_to_all( { :asset => params[:asset], | |
5 | - :category => @category }) %> | |
3 | +<div id='search-column-left'> | |
4 | + <% if !@empty_query %> | |
5 | + <%= facets_menu(:people, @facets) %> | |
6 | + <% end %> | |
7 | +</div> | |
6 | 8 | |
7 | -<%= render :partial => 'search_form', :locals => { :form_title => @query.blank? ? _('Search') : _("Refine your search"), :simple_search => true } %> | |
9 | +<div id='search-column-right'> | |
10 | + <%= render :partial => 'search_form', :locals => { :form_title => _('Search'), :simple_search => true, | |
11 | + :hint => _("Type words about the person you're looking for") } %> | |
12 | + <%= render :partial => 'results_header', :locals => { :asset => :people, :results => @results[:people] } %> | |
8 | 13 | |
9 | -<% if !@query.blank? %> | |
10 | - <%= facets_menu(:people, @facets) %> | |
11 | -<% end %> | |
12 | - | |
13 | -<%= render :partial => 'results_header', :locals => { :asset => :people, :results => @results[:people] } %> | |
14 | - | |
15 | -<%# FIXME ARMENGUE %> | |
16 | -<%= display_results(false) %> | |
17 | - | |
18 | -<% if params[:display] != 'map' %> | |
19 | - <%= pagination_links @results.values.first %> | |
20 | -<% end %> | |
14 | + <%= display_results %> | |
15 | + <% if params[:display] != 'map' %> | |
16 | + <%= pagination_links @results.values.first %> | |
17 | + <% end %> | |
18 | +</div> | |
21 | 19 | |
22 | 20 | <br style="clear:both" /> | ... | ... |
app/views/search/products.rhtml
1 | -<%= search_page_title( _('Products and Services'), { :query => @query, | |
2 | - :total_results => @total_results } ) %> | |
3 | - | |
4 | -<%= search_page_link_to_all( { :asset => params[:asset], | |
5 | - :category => @category }) %> | |
6 | - | |
7 | -<%= render :partial => 'search_form', :locals => { :form_title => _("Refine your search"), :simple_search => true } %> | |
8 | - | |
9 | -<% if @categories_menu %> | |
10 | -<div class="has_cat_list"> | |
11 | -<% end %> | |
12 | - | |
13 | -<% cache(:action => 'assets', :asset => 'products', :query => @query) do %> | |
14 | - <% if !@query.blank? %> | |
15 | - <%= facets_menu(:products, @facets) %> | |
1 | +<%= search_page_title( @titles[:products], @category ) %> | |
2 | + | |
3 | +<div id="search-column-left"> | |
4 | + <% if !@empty_query %> | |
5 | + <% button_bar do %> | |
6 | + <%= display_map_list_button %> | |
7 | + <% end %> | |
8 | + <%= facets_menu(:products, @facets) %> | |
16 | 9 | <% end %> |
17 | -<% end %> | |
18 | - | |
19 | -<%= render :partial => 'results_header', :locals => { :asset => :products, :results => @results[:products] } %> | |
20 | - | |
21 | -<%= display_results %> | |
22 | - | |
23 | -<% if @categories_menu %> | |
24 | -</div><!-- class="has_cat_list" --> | |
25 | -<% end %> | |
10 | +</div> | |
11 | + | |
12 | +<div id="search-column-right"> | |
13 | + <%= render :partial => 'search_form', :locals => { :form_title => _("Search"), :simple_search => true, | |
14 | + :hint => _('Type the product, service, city or qualifier desired') } %> | |
15 | + <%= render :partial => 'results_header', :locals => { :asset => :products, :results => @results[:products] } %> | |
16 | + | |
17 | + <% if !@empty_query %> | |
18 | + <%= display_results(true) %> | |
19 | + <% if params[:display] != 'map' %> | |
20 | + <%= pagination_links @results[:products] %> | |
21 | + <% end %> | |
22 | + <% end %> | |
23 | +</div> | |
26 | 24 | |
27 | -<% if params[:display] != 'map' %> | |
28 | - <%= pagination_links @results[:products] %> | |
29 | -<% end %> | |
30 | 25 | |
31 | 26 | <br style="clear:both" /> | ... | ... |
lib/acts_as_faceted.rb
... | ... | @@ -6,47 +6,180 @@ module ActsAsFaceted |
6 | 6 | module ActsMethods |
7 | 7 | # Example: |
8 | 8 | # |
9 | - # acts_as_faceted :fields => { | |
10 | - # :f_category => {:label => _('Related products')}, | |
11 | - # :f_region => {:label => _('Region')}, | |
12 | - # :f_qualifier => {:label => _('Qualifiers')}}, | |
13 | - # :order => [:f_category, :f_region, :f_qualifier] | |
9 | + #acts_as_faceted :fields => { | |
10 | + # :f_type => {:label => _('Type'), :proc => proc{|klass| f_type_proc(klass)}}, | |
11 | + # :f_published_at => {:type => :date, :label => _('Published date'), :queries => {'[* TO NOW-1YEARS/DAY]' => _("Older than one year"), | |
12 | + # '[NOW-1YEARS TO NOW/DAY]' => _("Last year"), '[NOW-1MONTHS TO NOW/DAY]' => _("Last month"), '[NOW-7DAYS TO NOW/DAY]' => _("Last week"), '[NOW-1DAYS TO NOW/DAY]' => _("Last day")}}, | |
13 | + # :f_profile_type => {:label => _('Author'), :proc => proc{|klass| f_profile_type_proc(klass)}}, | |
14 | + # :f_category => {:label => _('Categories')}}, | |
15 | + # :order => [:f_type, :f_published_at, :f_profile_type, :f_category] | |
16 | + # | |
17 | + #acts_as_searchable :additional_fields => [ {:name => {:type => :string, :as => :name_sort, :boost => 5.0}} ] + facets_fields_for_solr, | |
18 | + # :exclude_fields => [:setting], | |
19 | + # :include => [:profile], | |
20 | + # :facets => facets_option_for_solr, | |
21 | + # :if => proc{|a| ! ['RssFeed'].include?(a.class.name)} | |
14 | 22 | def acts_as_faceted(options) |
15 | 23 | extend ClassMethods |
24 | + extend ActsAsSolr::CommonMethods | |
16 | 25 | |
17 | 26 | cattr_accessor :facets |
18 | 27 | cattr_accessor :facets_order |
19 | - cattr_accessor :solr_facet_fields | |
20 | - cattr_accessor :to_solr_facet_fields | |
28 | + cattr_accessor :to_solr_fields_names | |
29 | + cattr_accessor :facets_results_containers | |
30 | + cattr_accessor :solr_fields_names | |
31 | + cattr_accessor :facets_option_for_solr | |
32 | + cattr_accessor :facets_fields_for_solr | |
33 | + cattr_accessor :facet_category_query | |
21 | 34 | |
22 | 35 | self.facets = options[:fields] |
23 | 36 | self.facets_order = options[:order] || facets |
37 | + self.facets_results_containers = {:fields => 'facet_fields', :queries => 'facet_queries', :ranges => 'facet_ranges'} | |
38 | + self.facets_option_for_solr = Hash[facets.select{ |id,data| ! data.has_key?(:queries) }].keys | |
39 | + self.facets_fields_for_solr = facets.map{ |id,data| {id => data[:type] || :facet} } | |
40 | + self.solr_fields_names = facets.map{ |id,data| id.to_s + '_' + get_solr_field_type(data[:type] || :facet) } | |
41 | + self.facet_category_query = options[:category_query] | |
24 | 42 | |
25 | 43 | # A hash to retrieve the field key for the solr facet string returned |
26 | - # "field_name_facet" => :field_name | |
27 | - self.solr_facet_fields = Hash[facets.keys.map{|f| f.to_s+'_facet'}.zip(facets.keys)] | |
28 | 44 | # :field_name => "field_name_facet" |
29 | - self.to_solr_facet_fields = Hash[facets.keys.zip(facets.keys.map{|f| f.to_s+'_facet'})] | |
45 | + self.to_solr_fields_names = Hash[facets.keys.zip(solr_fields_names)] | |
46 | + | |
47 | + def facet_by_id(id) | |
48 | + {:id => id}.merge(facets[id]) if facets[id] | |
49 | + end | |
50 | + | |
51 | + def map_facets_for(environment) | |
52 | + list = facets_order ? facets_order : facets.keys | |
53 | + list.map do |id| | |
54 | + facet = facet_by_id(id) | |
55 | + next if facet[:type_if] and !facet[:type_if].call(self.new) | |
30 | 56 | |
31 | - def each_facet | |
32 | - if facets_order | |
33 | - facets_order.each_with_index { |f, i| yield [f, i] } | |
57 | + if facet[:multi] | |
58 | + facet[:label].call(environment).map do |label_id, label| | |
59 | + facet.merge({:id => facet[:id].to_s+'_'+label_id.to_s, :solr_field => facet[:id], :label_id => label_id, :label => label}) | |
60 | + end | |
61 | + else | |
62 | + facet.merge(:id => facet[:id].to_s, :solr_field => facet[:id]) | |
63 | + end | |
64 | + end.compact.flatten | |
65 | + end | |
66 | + | |
67 | + def map_facet_results(facet, facet_params, facets_data, unfiltered_facets_data = {}, options = {}) | |
68 | + facets_data ||= {} | |
69 | + solr_facet = to_solr_fields_names[facet[:solr_field]] | |
70 | + | |
71 | + if unfiltered_facets_data | |
72 | + facets_data = unfiltered_facets_data.mash do |container, value| | |
73 | + [container, value.mash do |field, value| | |
74 | + facets_data[container] = {} if facets_data[container].nil? or facets_data[container] == [] | |
75 | + f = Hash[Array(facets_data[container][field])] | |
76 | + zeros = [] | |
77 | + [field, Array(value).map do |id, count| | |
78 | + count = f[id] | |
79 | + if count.nil? | |
80 | + zeros.push [id, 0] | |
81 | + nil | |
82 | + else | |
83 | + [id, count] | |
84 | + end | |
85 | + end.compact + zeros] | |
86 | + end] | |
87 | + end | |
88 | + end | |
89 | + | |
90 | + if facet[:queries] | |
91 | + container = facets_data[facets_results_containers[:queries]] | |
92 | + facet_data = (container.nil? or container.empty?) ? [] : container.select{ |k,v| k.starts_with? solr_facet } | |
34 | 93 | else |
35 | - facets.each_with_index { |f, i| yield [f. i] } | |
94 | + container = facets_data[facets_results_containers[:fields]] | |
95 | + facet_data = (container.nil? or container.empty?) ? [] : container[solr_facet] || [] | |
36 | 96 | end |
97 | + | |
98 | + facet_count = facet_data.length | |
99 | + | |
100 | + if facet[:queries] | |
101 | + result = facet_data.map do |id, count| | |
102 | + q = id[id.index(':')+1,id.length] | |
103 | + label = facet_result_name(facet, q) | |
104 | + [q, label, count] if count > 0 | |
105 | + end.compact | |
106 | + result = facet[:queries_order].map{ |id| result.detect{ |rid, label, count| rid == id } }.compact if facet[:queries_order] | |
107 | + elsif facet[:proc] | |
108 | + if facet[:label_id] | |
109 | + result = facet_data.map do |id, count| | |
110 | + name = facet_result_name(facet, id) | |
111 | + [id, name, count] if name | |
112 | + end.compact | |
113 | + # FIXME limit is NOT improving performance in this case :( | |
114 | + facet_count = result.length | |
115 | + result = result.first(options[:limit]) if options[:limit] | |
116 | + else | |
117 | + facet_data = facet_data.first(options[:limit]) if options[:limit] | |
118 | + result = facet_data.map { |id, count| [id, facet_result_name(facet, id), count] } | |
119 | + end | |
120 | + else | |
121 | + facet_data = facet_data.first(options[:limit]) if options[:limit] | |
122 | + result = facet_data.map { |id, count| [id, facet_result_name(facet, id), count] } | |
123 | + end | |
124 | + | |
125 | + sorted = facet_result_sort(facet, result, options[:sort]) | |
126 | + | |
127 | + # length can't be used if limit option is given; | |
128 | + # total_entries comes to help | |
129 | + sorted.class.send(:define_method, :total_entries, proc { facet_count }) | |
130 | + | |
131 | + sorted | |
37 | 132 | end |
38 | 133 | |
39 | - def each_facet_name(solr_facet, data, options = {}) | |
40 | - facet = facets[solr_facet_fields[solr_facet]] | |
134 | + def facet_result_sort(facet, facets_data, sort_by = nil) | |
135 | + if facet[:queries_order] | |
136 | + facets_data | |
137 | + elsif sort_by == :alphabetically | |
138 | + facets_data.sort{ |a,b| a[1] <=> b[1] } | |
139 | + elsif sort_by == :count | |
140 | + facets_data.sort{ |a,b| -1*(a[2] <=> b[2]) } | |
141 | + else | |
142 | + facets_data | |
143 | + end | |
144 | + end | |
41 | 145 | |
42 | - if options[:sort] == :alphabetically | |
43 | - result = data.sort{ |a,b| -1*(a[0] <=> b[0]) } | |
44 | - result.each { |name, count| yield [name, count] } | |
146 | + def facet_result_name(facet, data) | |
147 | + if facet[:queries] | |
148 | + gettext(facet[:queries][data]) | |
149 | + elsif facet[:proc] | |
150 | + if facet[:multi] | |
151 | + facet[:label_id] ||= 0 | |
152 | + facet[:proc].call(facet, data) | |
153 | + else | |
154 | + gettext(facet[:proc].call(data)) | |
155 | + end | |
45 | 156 | else |
46 | - result = options[:sort] == :count ? data.sort{ |a,b| -1*(a[1] <=> b[1]) } : data | |
47 | - result.each { |name, count| yield [name, count] } | |
157 | + data | |
48 | 158 | end |
49 | 159 | end |
160 | + | |
161 | + def facets_find_options(facets_selected = {}, options = {}) | |
162 | + browses = [] | |
163 | + facets_selected ||= {} | |
164 | + facets_selected.map do |id, value| | |
165 | + if value.kind_of?(Hash) | |
166 | + value.map do |label_id, value| | |
167 | + value.to_a.each do |value| | |
168 | + browses << id.to_s + ':' + (facets[id.to_sym][:queries] ? value : '"'+value.to_s+'"') | |
169 | + end | |
170 | + end | |
171 | + else | |
172 | + browses << id.to_s + ':' + (facets[id.to_sym][:queries] ? value : '"'+value.to_s+'"') | |
173 | + end | |
174 | + end.flatten | |
175 | + | |
176 | + {:facets => {:zeros => false, :sort => :count, | |
177 | + :fields => facets_option_for_solr, | |
178 | + :browse => browses, | |
179 | + :query => facets.map { |f, options| options[:queries].keys.map { |q| f.to_s + ':' + q } if options[:queries]}.compact.flatten, | |
180 | + } | |
181 | + } | |
182 | + end | |
50 | 183 | end |
51 | 184 | end |
52 | 185 | |
... | ... | @@ -54,3 +187,30 @@ end |
54 | 187 | |
55 | 188 | ActiveRecord::Base.extend ActsAsFaceted::ActsMethods |
56 | 189 | |
190 | +# from https://github.com/rubyworks/facets/blob/master/lib/core/facets/enumerable/graph.rb | |
191 | +module Enumerable | |
192 | + def graph(&yld) | |
193 | + if yld | |
194 | + h = {} | |
195 | + each do |*kv| | |
196 | + r = yld[*kv] | |
197 | + case r | |
198 | + when Hash | |
199 | + nk, nv = *r.to_a[0] | |
200 | + when Range | |
201 | + nk, nv = r.first, r.last | |
202 | + else | |
203 | + nk, nv = *r | |
204 | + end | |
205 | + h[nk] = nv | |
206 | + end | |
207 | + h | |
208 | + else | |
209 | + Enumerator.new(self,:graph) | |
210 | + end | |
211 | + end | |
212 | + | |
213 | + # Alias for #graph, which stands for "map hash". | |
214 | + alias_method :mash, :graph | |
215 | +end | |
216 | + | ... | ... |
lib/acts_as_searchable.rb
... | ... | @@ -4,16 +4,18 @@ module ActsAsSearchable |
4 | 4 | ACTS_AS_SEARCHABLE_ENABLED = true unless defined? ACTS_AS_SEARCHABLE_ENABLED |
5 | 5 | |
6 | 6 | def acts_as_searchable(options = {}) |
7 | - if ACTS_AS_SEARCHABLE_ENABLED | |
8 | - if (!options[:fields]) | |
9 | - options[:additional_fields] |= [{:schema_name => :string}] | |
10 | - else | |
11 | - options[:fields] << {:schema_name => :string} | |
12 | - end | |
13 | - acts_as_solr options | |
14 | - extend FindByContents | |
15 | - send :include, InstanceMethods | |
7 | + return if !ACTS_AS_SEARCHABLE_ENABLED | |
8 | + | |
9 | + if (!options[:fields]) | |
10 | + options[:additional_fields] |= [{:schema_name => :string}] | |
11 | + else | |
12 | + options[:fields] << {:schema_name => :string} | |
16 | 13 | end |
14 | + acts_as_solr options | |
15 | + extend FindByContents | |
16 | + send :include, InstanceMethods | |
17 | + | |
18 | + handle_asynchronously :solr_save | |
17 | 19 | end |
18 | 20 | |
19 | 21 | module InstanceMethods |
... | ... | @@ -31,14 +33,20 @@ module ActsAsSearchable |
31 | 33 | def find_by_contents(query, pg_options = {}, options = {}, db_options = {}) |
32 | 34 | pg_options[:page] ||= 1 |
33 | 35 | pg_options[:per_page] ||= 20 |
34 | - options[:limit] = pg_options[:per_page].to_i*pg_options[:page].to_i | |
35 | - options[:scores] = true; | |
36 | - | |
36 | + options[:limit] ||= pg_options[:per_page].to_i*pg_options[:page].to_i | |
37 | + options[:scores] ||= true; | |
38 | + all_facets_enabled = options.delete(:all_facets) | |
37 | 39 | query = !schema_name.empty? ? "+schema_name:\"#{schema_name}\" AND #{query}" : query |
40 | + results = [] | |
41 | + facets = all_facets = {} | |
42 | + | |
38 | 43 | solr_result = find_by_solr(query, options) |
39 | - if solr_result.nil? | |
40 | - results = facets = [] | |
41 | - else | |
44 | + if all_facets_enabled | |
45 | + options[:facets][:browse] = nil | |
46 | + all_facets = find_by_solr(query, options.merge(:limit => 0)).facets | |
47 | + end | |
48 | + | |
49 | + if !solr_result.nil? | |
42 | 50 | facets = options.include?(:facets) ? solr_result.facets : [] |
43 | 51 | |
44 | 52 | if db_options.empty? |
... | ... | @@ -61,7 +69,7 @@ module ActsAsSearchable |
61 | 69 | results = results.paginate(pg_options.merge(:total_entries => solr_result.total)) |
62 | 70 | end |
63 | 71 | |
64 | - {:results => results, :facets => facets} | |
72 | + {:results => results, :facets => facets, :all_facets => all_facets} | |
65 | 73 | end |
66 | 74 | end |
67 | 75 | end | ... | ... |
public/designs/themes/base/style.css
1 | 1 | /* ==> button.css <== */ |
2 | 2 | |
3 | - | |
4 | 3 | .button { |
5 | 4 | -moz-border-radius: 3px; |
6 | 5 | -webkit-border-radius: 3px; |
... | ... | @@ -502,11 +501,11 @@ div#notice { |
502 | 501 | } |
503 | 502 | |
504 | 503 | #content .profile-list li a, |
505 | -#content .common-profile-list-block li a { | |
504 | +#content .common-profile-list-block .vcard li a { | |
506 | 505 | color: #555; |
507 | 506 | } |
508 | 507 | #content .profile-list li a:hover, |
509 | -#content .common-profile-list-block li a:hover { | |
508 | +#content .common-profile-list-block .vcard li a:hover { | |
510 | 509 | color: #000; |
511 | 510 | text-decoration: none; |
512 | 511 | } | ... | ... |
public/javascripts/application.js
... | ... | @@ -773,3 +773,17 @@ jQuery('a[title]').live('mouseout', function (e) { |
773 | 773 | altBeautify.hide(); |
774 | 774 | }); |
775 | 775 | |
776 | + | |
777 | +function facet_options_toggle(id, url) { | |
778 | + jQuery('#facet-menu-'+id+' .facet-menu-options').toggle('fast' , function () { | |
779 | + more = jQuery('#facet-menu-'+id+' .facet-menu-more-options'); | |
780 | + console.log(more); | |
781 | + if (more.is(':visible') && more.children().length == 0) { | |
782 | + more.addClass('small-loading'); | |
783 | + more.load(url, function () { | |
784 | + more.removeClass('small-loading'); | |
785 | + }); | |
786 | + } | |
787 | + }); | |
788 | +} | |
789 | + | ... | ... |