Commit 7e54e8ab2527fd9c44ade31f8eba54ec8c090fcb
1 parent
afbcb3d1
Exists in
master
and in
28 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 | class SearchController < PublicController | 1 | class SearchController < PublicController |
2 | 2 | ||
3 | MAP_SEARCH_LIMIT = 2000 | 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 | helper TagsHelper | 8 | helper TagsHelper |
8 | include SearchHelper | 9 | include SearchHelper |
10 | + include ActionView::Helpers::NumberHelper | ||
9 | 11 | ||
10 | before_filter :load_category | 12 | before_filter :load_category |
11 | before_filter :load_search_assets | 13 | before_filter :load_search_assets |
14 | + before_filter :load_query | ||
12 | 15 | ||
13 | no_design_blocks | 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 | end | 38 | end |
31 | end | 39 | end |
32 | 40 | ||
33 | - alias :contents :articles | 41 | + def contents |
42 | + redirect_to params.merge(:action => :articles) | ||
43 | + end | ||
34 | 44 | ||
35 | def people | 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 | else | 48 | else |
49 | + @results[@asset] = @environment.people.visible.send(@filter).paginate(paginate_options) | ||
49 | @facets = {} | 50 | @facets = {} |
50 | end | 51 | end |
51 | - @results[@asset] = @results[@asset].compact.paginate(:per_page => limit, :page => params[:page]) | ||
52 | end | 52 | end |
53 | 53 | ||
54 | def products | 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 | end | 57 | end |
69 | end | 58 | end |
70 | 59 | ||
71 | def enterprises | 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 | else | 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 | end | 66 | end |
86 | end | 67 | end |
87 | 68 | ||
88 | def communities | 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 | else | 72 | else |
102 | - @facets = {} | 73 | + @results[@asset] = @environment.communities.visible.send(@filter).paginate(paginate_options) |
103 | end | 74 | end |
104 | - @results[@asset] = @results[@asset].compact.paginate(:per_page => limit, :page => params[:page]) | ||
105 | end | 75 | end |
106 | 76 | ||
107 | def events | 77 | def events |
108 | - @asset = :events | ||
109 | - params[:asset] |= [@asset] | ||
110 | - @query = params[:query] || '' | ||
111 | - @order ||= [@asset] | ||
112 | - @results ||= {} | ||
113 | @category_id = @category ? @category.id : nil | 78 | @category_id = @category ? @category.id : nil |
114 | 79 | ||
115 | if params[:year] || params[:month] | 80 | if params[:year] || params[:month] |
@@ -129,9 +94,7 @@ class SearchController < PublicController | @@ -129,9 +94,7 @@ class SearchController < PublicController | ||
129 | @results[@asset] = Event.send('find', :all) | 94 | @results[@asset] = Event.send('find', :all) |
130 | end | 95 | end |
131 | else | 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 | end | 98 | end |
136 | 99 | ||
137 | @selected_day = nil | 100 | @selected_day = nil |
@@ -157,6 +120,7 @@ class SearchController < PublicController | @@ -157,6 +120,7 @@ class SearchController < PublicController | ||
157 | @results = {} | 120 | @results = {} |
158 | @order = [] | 121 | @order = [] |
159 | @names = {} | 122 | @names = {} |
123 | + @results_only = true | ||
160 | 124 | ||
161 | @enabled_searchs.select { |key,description| @searching[key] }.each do |key, description| | 125 | @enabled_searchs.select { |key,description| @searching[key] }.each do |key, description| |
162 | send(key) | 126 | send(key) |
@@ -186,19 +150,17 @@ class SearchController < PublicController | @@ -186,19 +150,17 @@ class SearchController < PublicController | ||
186 | @names = {} | 150 | @names = {} |
187 | limit = MULTIPLE_SEARCH_LIMIT | 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 | end | 163 | end |
201 | - @facets = {} | ||
202 | end | 164 | end |
203 | 165 | ||
204 | def tags | 166 | def tags |
@@ -218,50 +180,33 @@ class SearchController < PublicController | @@ -218,50 +180,33 @@ class SearchController < PublicController | ||
218 | 180 | ||
219 | def events_by_day | 181 | def events_by_day |
220 | @selected_day = build_date(params[:year], params[:month], params[:day]) | 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 | render :partial => 'events/events_by_day' | 184 | render :partial => 'events/events_by_day' |
227 | end | 185 | end |
228 | 186 | ||
229 | ####################################################### | 187 | ####################################################### |
230 | protected | 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 | end | 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 | end | 210 | end |
266 | 211 | ||
267 | FILTERS = %w( | 212 | FILTERS = %w( |
@@ -277,112 +222,83 @@ class SearchController < PublicController | @@ -277,112 +222,83 @@ class SearchController < PublicController | ||
277 | end | 222 | end |
278 | end | 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 | end | 236 | end |
306 | 237 | ||
307 | def load_search_assets | 238 | def load_search_assets |
308 | @enabled_searchs = [ | 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 | ].select {|key, name| !environment.enabled?('disable_asset_' + key.to_s) } | 246 | ].select {|key, name| !environment.enabled?('disable_asset_' + key.to_s) } |
316 | 247 | ||
317 | @searching = {} | 248 | @searching = {} |
249 | + @titles = {} | ||
318 | @enabled_searchs.each do |key, name| | 250 | @enabled_searchs.each do |key, name| |
251 | + @titles[key] = name | ||
319 | @searching[key] = params[:action] == 'index' || params[:action] == key.to_s | 252 | @searching[key] = params[:action] == 'index' || params[:action] == key.to_s |
320 | end | 253 | end |
321 | end | 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 | def limit | 256 | def limit |
343 | - searching = @searching.values.select{|v|v} | 257 | + searching = @searching.values.select{ |v| v } |
344 | if params[:display] == 'map' | 258 | if params[:display] == 'map' |
345 | MAP_SEARCH_LIMIT | 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 | else | 268 | else |
347 | - (searching.size <= 1) ? SINGLE_SEARCH_LIMIT : MULTIPLE_SEARCH_LIMIT | 269 | + MULTIPLE_SEARCH_LIMIT |
348 | end | 270 | end |
349 | end | 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 | end | 297 | end |
298 | + | ||
299 | + result[:order] = solr_order if solr_order | ||
300 | + | ||
301 | + result | ||
386 | end | 302 | end |
387 | 303 | ||
388 | def asset_class(asset) | 304 | def asset_class(asset) |
app/helpers/display_helper.rb
@@ -8,14 +8,24 @@ module DisplayHelper | @@ -8,14 +8,24 @@ module DisplayHelper | ||
8 | opts | 8 | opts |
9 | end | 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 | def product_path(product) | 17 | def product_path(product) |
12 | product.enterprise.enabled? ? product.enterprise.public_profile_url.merge(:controller => 'manage_products', :action => 'show', :id => product) : product.enterprise.url | 18 | product.enterprise.enabled? ? product.enterprise.public_profile_url.merge(:controller => 'manage_products', :action => 'show', :id => product) : product.enterprise.url |
13 | end | 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 | return _('Uncategorized product') unless category | 26 | return _('Uncategorized product') unless category |
17 | name = full ? category.full_name(' → ') : category.name | 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 | end | 29 | end |
20 | 30 | ||
21 | def link_to_product_category(category) | 31 | def link_to_product_category(category) |
app/helpers/search_helper.rb
@@ -9,54 +9,31 @@ module SearchHelper | @@ -9,54 +9,31 @@ module SearchHelper | ||
9 | (n * 100.0).round | 9 | (n * 100.0).round |
10 | end | 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 | end | 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 | end | 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 | end | 37 | end |
61 | 38 | ||
62 | def facets_menu(asset, _facets) | 39 | def facets_menu(asset, _facets) |
@@ -148,15 +125,15 @@ module SearchHelper | @@ -148,15 +125,15 @@ module SearchHelper | ||
148 | 125 | ||
149 | def order_by(asset) | 126 | def order_by(asset) |
150 | options = { | 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 | select_tag(asset.to_s + '[order]', options_for_select(options[asset], params[:order_by]), | 137 | select_tag(asset.to_s + '[order]', options_for_select(options[asset], params[:order_by]), |
161 | {:onchange => "window.location=jQuery.param.querystring(window.location.href, { 'order_by' : this.options[this.selectedIndex].value})"}), | 138 | {:onchange => "window.location=jQuery.param.querystring(window.location.href, { 'order_by' : this.options[this.selectedIndex].value})"}), |
162 | :class => "search-ordering") | 139 | :class => "search-ordering") |
@@ -178,4 +155,5 @@ module SearchHelper | @@ -178,4 +155,5 @@ module SearchHelper | ||
178 | '' | 155 | '' |
179 | end | 156 | end |
180 | end | 157 | end |
158 | + | ||
181 | end | 159 | end |
app/models/article.rb
@@ -139,11 +139,18 @@ class Article < ActiveRecord::Base | @@ -139,11 +139,18 @@ class Article < ActiveRecord::Base | ||
139 | {:conditions => [ 'parent_id is null and profile_id = ?', profile.id ]} | 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 | # retrieves the latest +limit+ articles, sorted from the most recent to the | 149 | # retrieves the latest +limit+ articles, sorted from the most recent to the |
143 | # oldest. | 150 | # oldest. |
144 | # | 151 | # |
145 | # Only includes articles where advertise == true | 152 | # Only includes articles where advertise == true |
146 | - def self.recent(limit, extra_conditions = {}) | 153 | + def self.recent(limit = nil, extra_conditions = {}) |
147 | # FIXME this method is a horrible hack | 154 | # FIXME this method is a horrible hack |
148 | options = { :limit => limit, | 155 | options = { :limit => limit, |
149 | :conditions => [ | 156 | :conditions => [ |
@@ -558,17 +565,53 @@ class Article < ActiveRecord::Base | @@ -558,17 +565,53 @@ class Article < ActiveRecord::Base | ||
558 | end | 565 | end |
559 | 566 | ||
560 | private | 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 | def f_type | 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 | end | 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 | end | 615 | end |
573 | def f_profile_type | 616 | def f_profile_type |
574 | self.profile.class.to_s | 617 | self.profile.class.to_s |
@@ -579,16 +622,21 @@ class Article < ActiveRecord::Base | @@ -579,16 +622,21 @@ class Article < ActiveRecord::Base | ||
579 | public | 622 | public |
580 | 623 | ||
581 | acts_as_faceted :fields => { | 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 | :include => [:profile], | 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 | private | 641 | private |
594 | 642 |
app/models/category.rb
@@ -36,18 +36,38 @@ class Category < ActiveRecord::Base | @@ -36,18 +36,38 @@ class Category < ActiveRecord::Base | ||
36 | { :conditions => [ "type IN (?) OR type IS NULL", types.reject{ |t| t.blank? } ] } | 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 | def recent_articles(limit = 10) | 55 | def recent_articles(limit = 10) |
40 | self.articles.recent(limit) | 56 | self.articles.recent(limit) |
41 | end | 57 | end |
42 | 58 | ||
43 | def recent_comments(limit = 10) | 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 | end | 61 | end |
46 | 62 | ||
47 | def most_commented_articles(limit = 10) | 63 | def most_commented_articles(limit = 10) |
48 | self.articles.most_commented(limit) | 64 | self.articles.most_commented(limit) |
49 | end | 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 | def display_in_menu? | 71 | def display_in_menu? |
52 | display_in_menu | 72 | display_in_menu |
53 | end | 73 | end |
@@ -64,10 +84,6 @@ class Category < ActiveRecord::Base | @@ -64,10 +84,6 @@ class Category < ActiveRecord::Base | ||
64 | results | 84 | results |
65 | end | 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 | def is_leaf_displayable_in_menu? | 87 | def is_leaf_displayable_in_menu? |
72 | return false if self.display_in_menu == false | 88 | return false if self.display_in_menu == false |
73 | self.children.find(:all, :conditions => {:display_in_menu => true}).empty? | 89 | self.children.find(:all, :conditions => {:display_in_menu => true}).empty? |
app/models/environment.rb
@@ -247,8 +247,9 @@ class Environment < ActiveRecord::Base | @@ -247,8 +247,9 @@ class Environment < ActiveRecord::Base | ||
247 | 247 | ||
248 | settings_items :enabled_plugins, :type => Array, :default => [] | 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 | def news_amount_by_folder=(amount) | 254 | def news_amount_by_folder=(amount) |
254 | settings[:news_amount_by_folder] = amount.to_i | 255 | settings[:news_amount_by_folder] = amount.to_i |
app/views/layouts/application-ng.rhtml
@@ -66,7 +66,7 @@ | @@ -66,7 +66,7 @@ | ||
66 | </div> | 66 | </div> |
67 | </span> | 67 | </span> |
68 | <form action="/search" class="search_form" method="get" class="clean"> | 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 | <div><%=_('Press <strong>Enter</strong> to send the search query.')%></div> | 70 | <div><%=_('Press <strong>Enter</strong> to send the search query.')%></div> |
71 | <%= javascript_tag 'jQuery("#user form input").hint();' %> | 71 | <%= javascript_tag 'jQuery("#user form input").hint();' %> |
72 | </form> | 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 | </div> | 8 | </div> |
9 | + <br class="clear"/> | ||
21 | </li> | 10 | </li> |
@@ -0,0 +1,8 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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,45 +4,31 @@ | ||
4 | <% results = @results[name] %> | 4 | <% results = @results[name] %> |
5 | <% if !results.nil? and !results.empty? %> | 5 | <% if !results.nil? and !results.empty? %> |
6 | <div class="search-results-<%= name %> search-results-box"> | 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 | <% end %> | 12 | <% end %> |
27 | - <% partial = partial_for_class results.first.class %> | 13 | + |
14 | + <% partial = partial_for_class(results.first.class.class_name.constantize) %> | ||
28 | <div class="search-results-innerbox search-results-type-<%= partial %> <%= 'common-profile-list-block' if partial == 'profile' %>"> | 15 | <div class="search-results-innerbox search-results-type-<%= partial %> <%= 'common-profile-list-block' if partial == 'profile' %>"> |
29 | <div class="search-results-innerbox2"><!-- the innerbox2 is a workarround for MSIE --> | 16 | <div class="search-results-innerbox2"><!-- the innerbox2 is a workarround for MSIE --> |
30 | <ul> | 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 | </ul> | 22 | </ul> |
36 | <hr /> | 23 | <hr /> |
37 | </div><!-- end class="search-results-innerbox2" --> | 24 | </div><!-- end class="search-results-innerbox2" --> |
38 | </div><!-- end class="search-results-innerbox" --> | 25 | </div><!-- end class="search-results-innerbox" --> |
26 | + | ||
39 | </div><!-- end class="search-results-<%= name %>" --> | 27 | </div><!-- end class="search-results-<%= name %>" --> |
40 | <% else %> | 28 | <% else %> |
41 | <div class="search-results-<%= name %> search-results-empty search-results-box"> | 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 | <% end %> | 32 | <% end %> |
47 | <div class="search-results-innerbox search-results-type-empty"> | 33 | <div class="search-results-innerbox search-results-type-empty"> |
48 | <div> <%= _('None') %> </div> | 34 | <div> <%= _('None') %> </div> |
@@ -52,6 +38,6 @@ | @@ -52,6 +38,6 @@ | ||
52 | <% end %> | 38 | <% end %> |
53 | <% end %> | 39 | <% end %> |
54 | 40 | ||
55 | -<br style="clear:both" /> | 41 | +<div style="clear:both"></div> |
56 | </div><!-- end id="search-results" --> | 42 | </div><!-- end id="search-results" --> |
57 | 43 |
@@ -0,0 +1 @@ | @@ -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 | </div> | 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 | </li> | 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 | <div id="facets-menu"> | 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 | <% end %> | 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 | <br /> | 28 | <br /> |
47 | - </div> | ||
48 | <% end %> | 29 | <% end %> |
30 | + | ||
31 | + <% else %> | ||
32 | + <span class="facet-any-result-found"><%= _("No filter available") %></span> | ||
49 | <% end %> | 33 | <% end %> |
50 | - <% end %> | ||
51 | - </div> | 34 | + </div> |
35 | + <% end %> | ||
36 | +</div> |
app/views/search/_facets_unselect_menu.rhtml
1 | - | ||
2 | <div class="facets-applied"> | 1 | <div class="facets-applied"> |
3 | <% if params[:facet] and params[:facet].count > 0 %> | 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 | <% end %> | 5 | <% end %> |
9 | </div> | 6 | </div> |
@@ -0,0 +1,19 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 | <% extra_content = @plugins.map(:asset_product_extras, product, product.enterprise).collect { |content| instance_eval(&content) } %> | 1 | <% extra_content = @plugins.map(:asset_product_extras, product, product.enterprise).collect { |content| instance_eval(&content) } %> |
2 | <% extra_properties = @plugins.map(:asset_product_properties, product)%> | 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 | </div> | 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 | </div> | 49 | </div> |
14 | - <div class="product-description"> | 50 | + <div class="search-product-description"> |
15 | <% if product.description %> | 51 | <% if product.description %> |
16 | <% desc_stripped = strip_tags(product.description) %> | 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 | <% end %> | 54 | <% end %> |
19 | </div> | 55 | </div> |
20 | </div> | 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 | <% if product.enterprise.region %> | 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 | <% end %> | 62 | <% end %> |
27 | </div> | 63 | </div> |
28 | - <div class="product-qualifiers"> | 64 | + <div class="search-product-qualifiers"> |
29 | <% if product.product_qualifiers.count > 0 %> | 65 | <% if product.product_qualifiers.count > 0 %> |
30 | - <span class="product-item-topic"><%= _('QUALIFIERS') %></span> | 66 | + <span class="search-field-label"><%= _('Qualifiers') %></span> |
31 | <% product.product_qualifiers.each do |pq| %> | 67 | <% product.product_qualifiers.each do |pq| %> |
32 | <% if pq.qualifier %> | 68 | <% if pq.qualifier %> |
33 | - <br /><%= pq.qualifier.name %> | 69 | + <span class="search-product-qualifier"><%= pq.qualifier.name + (pq.certifier.nil? ? _(";") : '') %></span> |
34 | <% end %> | 70 | <% end %> |
35 | <% if pq.certifier %> | 71 | <% if pq.certifier %> |
36 | - <br /><%= pq.certifier.name %> | 72 | + <span class="search-product-certifier"> <%= _('cert. ') + pq.certifier.name + _(";") %></span> |
37 | <% end %> | 73 | <% end %> |
38 | <% end %> | 74 | <% end %> |
39 | <% end %> | 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 | </div> | 19 | </div> |
app/views/search/_search_form.rhtml
@@ -3,26 +3,36 @@ | @@ -3,26 +3,36 @@ | ||
3 | 3 | ||
4 | <% form_tag( { :controller => 'search', :action => @asset ? @asset : 'index', :asset => nil, :category_path => ( @category ? @category.explode_path : [] ) }, | 4 | <% form_tag( { :controller => 'search', :action => @asset ? @asset : 'index', :asset => nil, :category_path => ( @category ? @category.explode_path : [] ) }, |
5 | :method => 'get', :class => 'search_form' ) do %> | 5 | :method => 'get', :class => 'search_form' ) do %> |
6 | - <%= '<h3>%s</h3>' % form_title if defined? form_title %> | ||
7 | 6 | ||
8 | <%= hidden_field_tag :display, params[:display] %> | 7 | <%= hidden_field_tag :display, params[:display] %> |
9 | 8 | ||
10 | - <%= hidden_field_tag :asset, params[:asset] %> | ||
11 | - | ||
12 | <div class="search-field"> | 9 | <div class="search-field"> |
13 | <span class="formfield"> | 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 | </span> | 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 | </div> | 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 | <% end %> | 37 | <% end %> |
28 | 38 |
@@ -0,0 +1,10 @@ | @@ -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 @@ | @@ -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 | <br style="clear:both" /> | 20 | <br style="clear:both" /> |
app/views/search/category_index.rhtml
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | <div id="category-image"><%= image_tag(@category.image.public_filename(:thumb), :id => 'category-image') if @category.image %></div> | 3 | <div id="category-image"><%= image_tag(@category.image.public_filename(:thumb), :id => 'category-image') if @category.image %></div> |
4 | <h1 id="category-name"><%= @category.name %></h1> | 4 | <h1 id="category-name"><%= @category.name %></h1> |
5 | 5 | ||
6 | - <%= render :partial => 'display_results' %> | 6 | + <%= display_results %> |
7 | 7 | ||
8 | <div id="category-childs"> | 8 | <div id="category-childs"> |
9 | <h2> <%= _('Sub-categories') %> </h2> | 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 | <% end %> | 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 | </div> | 23 | </div> |
28 | 24 | ||
29 | <br style="clear:both" /> | 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 | <% end %> | 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 | <%= facets_menu(:enterprises, @facets) %> | 14 | <%= facets_menu(:enterprises, @facets) %> |
26 | <% end %> | 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 | <br style="clear:both" /> | 29 | <br style="clear:both" /> |
app/views/search/events.rhtml
@@ -0,0 +1,8 @@ | @@ -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 | <div id="search-page"> | 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 | <%= render :partial => 'search_form', :locals => { :form_title => _("Refine your search"), :simple_search => true } %> | 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 | <br style="clear:both" /> | 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 | <% end %> | 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 | <br style="clear:both" /> | 26 | <br style="clear:both" /> |
lib/acts_as_faceted.rb
@@ -6,47 +6,180 @@ module ActsAsFaceted | @@ -6,47 +6,180 @@ module ActsAsFaceted | ||
6 | module ActsMethods | 6 | module ActsMethods |
7 | # Example: | 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 | def acts_as_faceted(options) | 22 | def acts_as_faceted(options) |
15 | extend ClassMethods | 23 | extend ClassMethods |
24 | + extend ActsAsSolr::CommonMethods | ||
16 | 25 | ||
17 | cattr_accessor :facets | 26 | cattr_accessor :facets |
18 | cattr_accessor :facets_order | 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 | self.facets = options[:fields] | 35 | self.facets = options[:fields] |
23 | self.facets_order = options[:order] || facets | 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 | # A hash to retrieve the field key for the solr facet string returned | 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 | # :field_name => "field_name_facet" | 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 | else | 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 | end | 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 | end | 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 | else | 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 | end | 158 | end |
49 | end | 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 | end | 183 | end |
51 | end | 184 | end |
52 | 185 | ||
@@ -54,3 +187,30 @@ end | @@ -54,3 +187,30 @@ end | ||
54 | 187 | ||
55 | ActiveRecord::Base.extend ActsAsFaceted::ActsMethods | 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,16 +4,18 @@ module ActsAsSearchable | ||
4 | ACTS_AS_SEARCHABLE_ENABLED = true unless defined? ACTS_AS_SEARCHABLE_ENABLED | 4 | ACTS_AS_SEARCHABLE_ENABLED = true unless defined? ACTS_AS_SEARCHABLE_ENABLED |
5 | 5 | ||
6 | def acts_as_searchable(options = {}) | 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 | end | 13 | end |
14 | + acts_as_solr options | ||
15 | + extend FindByContents | ||
16 | + send :include, InstanceMethods | ||
17 | + | ||
18 | + handle_asynchronously :solr_save | ||
17 | end | 19 | end |
18 | 20 | ||
19 | module InstanceMethods | 21 | module InstanceMethods |
@@ -31,14 +33,20 @@ module ActsAsSearchable | @@ -31,14 +33,20 @@ module ActsAsSearchable | ||
31 | def find_by_contents(query, pg_options = {}, options = {}, db_options = {}) | 33 | def find_by_contents(query, pg_options = {}, options = {}, db_options = {}) |
32 | pg_options[:page] ||= 1 | 34 | pg_options[:page] ||= 1 |
33 | pg_options[:per_page] ||= 20 | 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 | query = !schema_name.empty? ? "+schema_name:\"#{schema_name}\" AND #{query}" : query | 39 | query = !schema_name.empty? ? "+schema_name:\"#{schema_name}\" AND #{query}" : query |
40 | + results = [] | ||
41 | + facets = all_facets = {} | ||
42 | + | ||
38 | solr_result = find_by_solr(query, options) | 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 | facets = options.include?(:facets) ? solr_result.facets : [] | 50 | facets = options.include?(:facets) ? solr_result.facets : [] |
43 | 51 | ||
44 | if db_options.empty? | 52 | if db_options.empty? |
@@ -61,7 +69,7 @@ module ActsAsSearchable | @@ -61,7 +69,7 @@ module ActsAsSearchable | ||
61 | results = results.paginate(pg_options.merge(:total_entries => solr_result.total)) | 69 | results = results.paginate(pg_options.merge(:total_entries => solr_result.total)) |
62 | end | 70 | end |
63 | 71 | ||
64 | - {:results => results, :facets => facets} | 72 | + {:results => results, :facets => facets, :all_facets => all_facets} |
65 | end | 73 | end |
66 | end | 74 | end |
67 | end | 75 | end |
public/designs/themes/base/style.css
1 | /* ==> button.css <== */ | 1 | /* ==> button.css <== */ |
2 | 2 | ||
3 | - | ||
4 | .button { | 3 | .button { |
5 | -moz-border-radius: 3px; | 4 | -moz-border-radius: 3px; |
6 | -webkit-border-radius: 3px; | 5 | -webkit-border-radius: 3px; |
@@ -502,11 +501,11 @@ div#notice { | @@ -502,11 +501,11 @@ div#notice { | ||
502 | } | 501 | } |
503 | 502 | ||
504 | #content .profile-list li a, | 503 | #content .profile-list li a, |
505 | -#content .common-profile-list-block li a { | 504 | +#content .common-profile-list-block .vcard li a { |
506 | color: #555; | 505 | color: #555; |
507 | } | 506 | } |
508 | #content .profile-list li a:hover, | 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 | color: #000; | 509 | color: #000; |
511 | text-decoration: none; | 510 | text-decoration: none; |
512 | } | 511 | } |
public/javascripts/application.js
@@ -773,3 +773,17 @@ jQuery('a[title]').live('mouseout', function (e) { | @@ -773,3 +773,17 @@ jQuery('a[title]').live('mouseout', function (e) { | ||
773 | altBeautify.hide(); | 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 | + |