Commit dad628a9875934c8d18f27efb6e4f59b94237aa0
1 parent
4ef7f762
Exists in
master
and in
28 other branches
Refactor search ordering, boost, indexing and CSS
Showing
33 changed files
with
373 additions
and
363 deletions
Show diff stats
app/controllers/public/search_controller.rb
| 1 | 1 | class SearchController < PublicController |
| 2 | 2 | |
| 3 | - MAP_SEARCH_LIMIT = 2000 | |
| 4 | - LIST_SEARCH_LIMIT = 20 | |
| 5 | - BLOCKS_SEARCH_LIMIT = 18 | |
| 6 | - MULTIPLE_SEARCH_LIMIT = 8 | |
| 7 | - | |
| 8 | 3 | helper TagsHelper |
| 9 | 4 | include SearchHelper |
| 10 | 5 | include ActionView::Helpers::NumberHelper |
| ... | ... | @@ -33,7 +28,6 @@ class SearchController < PublicController |
| 33 | 28 | full_text_search ['public:true'] |
| 34 | 29 | else |
| 35 | 30 | @results[@asset] = @environment.articles.public.send(@filter).paginate(paginate_options) |
| 36 | - facets = {} | |
| 37 | 31 | end |
| 38 | 32 | end |
| 39 | 33 | |
| ... | ... | @@ -46,7 +40,6 @@ class SearchController < PublicController |
| 46 | 40 | full_text_search ['public:true'] |
| 47 | 41 | else |
| 48 | 42 | @results[@asset] = @environment.people.visible.send(@filter).paginate(paginate_options) |
| 49 | - @facets = {} | |
| 50 | 43 | end |
| 51 | 44 | end |
| 52 | 45 | |
| ... | ... | @@ -54,8 +47,19 @@ class SearchController < PublicController |
| 54 | 47 | if !@empty_query |
| 55 | 48 | full_text_search ['public:true'] |
| 56 | 49 | else |
| 57 | - @results[@asset] = @environment.products.send(@filter).paginate(paginate_options) | |
| 58 | - @facets = {} | |
| 50 | + @one_page = true | |
| 51 | + @geosearch = logged_in? && current_user.person.lat && current_user.person.lng | |
| 52 | + | |
| 53 | + extra_limit = LIST_SEARCH_LIMIT*5 | |
| 54 | + sql_options = {:limit => LIST_SEARCH_LIMIT, :order => 'random()'} | |
| 55 | + if @geosearch | |
| 56 | + full_text_search ['public:true', "{!geofilt}"], :sql_options => sql_options, :extra_limit => extra_limit, | |
| 57 | + :alternate_query => "{!boost b=recip(geodist(),#{1/DistBoost},1,1)}", | |
| 58 | + :radius => DistFilt, :latitude => current_user.person.lat, :longitude => current_user.person.lng | |
| 59 | + else | |
| 60 | + full_text_search ['public:true'], :sql_options => sql_options, :extra_limit => extra_limit, | |
| 61 | + :boost_functions => ['recip(ms(NOW/HOUR,updated_at),1.3e-10,1,1)'] | |
| 62 | + end | |
| 59 | 63 | end |
| 60 | 64 | end |
| 61 | 65 | |
| ... | ... | @@ -77,40 +81,25 @@ class SearchController < PublicController |
| 77 | 81 | end |
| 78 | 82 | |
| 79 | 83 | def events |
| 80 | - @category_id = @category ? @category.id : nil | |
| 81 | - | |
| 82 | 84 | year = (params[:year] ? params[:year].to_i : Date.today.year) |
| 83 | 85 | month = (params[:month] ? params[:month].to_i : Date.today.month) |
| 84 | 86 | day = (params[:day] ? params[:day].to_i : Date.today.day) |
| 85 | - date = Date.new(year, month, day) | |
| 87 | + date = build_date(params[:year], params[:month], params[:day]) | |
| 86 | 88 | date_range = (date - 1.month)..(date + 1.month).at_end_of_month |
| 87 | 89 | |
| 88 | - if @query.blank? | |
| 89 | - # Ignore pagination for asset events | |
| 90 | - if date_range | |
| 91 | - @results[@asset] = Event.send('find', :all, | |
| 92 | - :conditions => [ | |
| 93 | - 'start_date BETWEEN :start_day AND :end_day OR end_date BETWEEN :start_day AND :end_day', | |
| 94 | - {:start_day => date_range.first, :end_day => date_range.last} | |
| 95 | - ]) | |
| 96 | - else | |
| 97 | - @results[@asset] = Event.send('find', :all) | |
| 98 | - end | |
| 99 | - else | |
| 100 | - full_text_search | |
| 101 | - end | |
| 102 | - | |
| 103 | 90 | @selected_day = nil |
| 104 | 91 | @events_of_the_day = [] |
| 105 | - date = build_date(params[:year], params[:month], params[:day]) | |
| 106 | - | |
| 107 | 92 | if params[:day] || !params[:year] && !params[:month] |
| 108 | 93 | @selected_day = date |
| 109 | - if @category_id and Category.exists?(@category_id) | |
| 110 | - @events_of_the_day = environment.events.by_day(@selected_day).in_category(Category.find(@category_id)) | |
| 111 | - else | |
| 112 | - @events_of_the_day = environment.events.by_day(@selected_day) | |
| 113 | - end | |
| 94 | + @events_of_the_day = @category ? | |
| 95 | + environment.events.by_day(@selected_day).in_category(Category.find(@category_id)) : | |
| 96 | + environment.events.by_day(@selected_day) | |
| 97 | + end | |
| 98 | + | |
| 99 | + if !@empty_query | |
| 100 | + full_text_search | |
| 101 | + else | |
| 102 | + @results[@asset] = date_range ? environment.events.by_range(date_range) : environment.events | |
| 114 | 103 | end |
| 115 | 104 | |
| 116 | 105 | events = @results[@asset] |
| ... | ... | @@ -135,17 +124,10 @@ class SearchController < PublicController |
| 135 | 124 | @asset = nil |
| 136 | 125 | @facets = {} |
| 137 | 126 | |
| 138 | - if @results.keys.size == 1 | |
| 139 | - specific_action = @results.keys.first | |
| 140 | - if respond_to?(specific_action) | |
| 141 | - @asset_name = getterm(@names[@results.keys.first]) | |
| 142 | - send(specific_action) | |
| 143 | - render :action => specific_action | |
| 144 | - return | |
| 145 | - end | |
| 146 | - end | |
| 127 | + render :action => @results.keys.first if @results.keys.size == 1 | |
| 147 | 128 | end |
| 148 | 129 | |
| 130 | + # keep old URLs workings | |
| 149 | 131 | def assets |
| 150 | 132 | params[:action] = params[:asset].is_a?(Array) ? :index : params.delete(:asset) |
| 151 | 133 | redirect_to params |
| ... | ... | @@ -167,6 +149,7 @@ class SearchController < PublicController |
| 167 | 149 | ].each do |asset, name, filter| |
| 168 | 150 | @order << asset |
| 169 | 151 | @results[asset] = @category.send(filter, limit) |
| 152 | + raise "nao total #{asset}" unless @results[asset].respond_to?(:total_entries) | |
| 170 | 153 | @names[asset] = name |
| 171 | 154 | end |
| 172 | 155 | end |
| ... | ... | @@ -182,7 +165,8 @@ class SearchController < PublicController |
| 182 | 165 | @tag = params[:tag] |
| 183 | 166 | @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_env_#{environment.id.to_s}_page_#{params[:npage]}" |
| 184 | 167 | if is_cache_expired?(@tag_cache_key) |
| 185 | - @tagged = environment.articles.find_tagged_with(@tag).paginate(:per_page => 10, :page => params[:npage]) | |
| 168 | + @asset = :articles | |
| 169 | + @results[@asset] = environment.articles.find_tagged_with(@tag).paginate(paginate_options) | |
| 186 | 170 | end |
| 187 | 171 | end |
| 188 | 172 | |
| ... | ... | @@ -241,7 +225,7 @@ class SearchController < PublicController |
| 241 | 225 | 'communities_more_recent' => _('More recent communities from network'), |
| 242 | 226 | 'communities_more_active' => _('More active communities from network'), |
| 243 | 227 | 'communities_more_popular' => _('More popular communities from network'), |
| 244 | - 'products_more_recent' => _('More recent products from network'), | |
| 228 | + 'products_more_recent' => _('Highlights'), | |
| 245 | 229 | }[asset.to_s + '_' + filter] |
| 246 | 230 | end |
| 247 | 231 | |
| ... | ... | @@ -284,21 +268,30 @@ class SearchController < PublicController |
| 284 | 268 | { :per_page => limit, :page => page } |
| 285 | 269 | end |
| 286 | 270 | |
| 287 | - def full_text_search(filters = []) | |
| 271 | + def full_text_search(filters = [], options = {}) | |
| 288 | 272 | paginate_options = paginate_options(params[:page]) |
| 289 | 273 | asset_class = asset_class(@asset) |
| 290 | 274 | |
| 291 | - solr_options = {} | |
| 292 | - if !@results_only and asset_class.methods.include?('facets') | |
| 275 | + solr_options = options | |
| 276 | + if !@results_only and asset_class.respond_to? :facets | |
| 293 | 277 | solr_options.merge! asset_class.facets_find_options(params[:facet]) |
| 294 | 278 | solr_options[:all_facets] = true |
| 295 | 279 | solr_options[:limit] = 0 if @facets_only |
| 296 | - #solr_options[:facets][:browse] << asset_class.facet_category_query.call(@category) if @category and asset_class.facet_category_query | |
| 297 | 280 | end |
| 298 | - solr_options[:order] = params[:order_by] if params[:order_by] | |
| 299 | 281 | solr_options[:filter_queries] ||= [] |
| 300 | 282 | solr_options[:filter_queries] += filters |
| 301 | 283 | solr_options[:filter_queries] << "environment_id:#{environment.id}" |
| 284 | + solr_options[:filter_queries] << asset_class.facet_category_query.call(@category) if @category | |
| 285 | + | |
| 286 | + solr_options[:boost_functions] ||= [] | |
| 287 | + params[:order_by] = nil if params[:order_by] == 'none' | |
| 288 | + if params[:order_by] | |
| 289 | + order = SortOptions[@asset][params[:order_by].to_sym] | |
| 290 | + raise "Unknown order by" if order.nil? | |
| 291 | + order[:solr_opts].each do |opt, value| | |
| 292 | + solr_options[opt] = value.is_a?(Proc) ? instance_eval(&value) : value | |
| 293 | + end | |
| 294 | + end | |
| 302 | 295 | |
| 303 | 296 | ret = asset_class.find_by_contents(@query, paginate_options, solr_options) |
| 304 | 297 | @results[@asset] = ret[:results] | ... | ... |
app/helpers/search_helper.rb
| 1 | 1 | module SearchHelper |
| 2 | 2 | |
| 3 | + MAP_SEARCH_LIMIT = 2000 | |
| 4 | + LIST_SEARCH_LIMIT = 20 | |
| 5 | + BLOCKS_SEARCH_LIMIT = 18 | |
| 6 | + MULTIPLE_SEARCH_LIMIT = 8 | |
| 7 | + DistFilt = 200 | |
| 8 | + DistBoost = 50 | |
| 9 | + SortOptions = { | |
| 10 | + :products => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | |
| 11 | + :more_recent, {:label => _('More Recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}}, | |
| 12 | + :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}}, | |
| 13 | + :closest, {:label => _('Closest to me'), :if => proc{ logged_in? && (profile=current_user.person).lat && profile.lng }, | |
| 14 | + :solr_opts => {:sort => "geodist() asc", | |
| 15 | + :latitude => proc{ current_user.person.lat }, :longitude => proc{ current_user.person.lng }}}, | |
| 16 | + ], | |
| 17 | + :events => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | |
| 18 | + :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}}, | |
| 19 | + ], | |
| 20 | + :articles => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | |
| 21 | + :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}}, | |
| 22 | + :name, {:label => _('Most recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}}, | |
| 23 | + ], | |
| 24 | + :enterprises => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | |
| 25 | + :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}}, | |
| 26 | + ], | |
| 27 | + :people => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | |
| 28 | + :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}}, | |
| 29 | + ], | |
| 30 | + :communities => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | |
| 31 | + :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}}, | |
| 32 | + ], | |
| 33 | + } | |
| 34 | + | |
| 3 | 35 | # FIXME remove it after search_controler refactored |
| 4 | 36 | include EventsHelper |
| 5 | 37 | |
| ... | ... | @@ -130,18 +162,14 @@ module SearchHelper |
| 130 | 162 | end |
| 131 | 163 | |
| 132 | 164 | def order_by(asset) |
| 133 | - options = { | |
| 134 | - :products => [[_('Relevance'), ''], [_('More Recent'), 'updated_at desc'], [_('Name'), 'name_or_category_sort asc']], | |
| 135 | - :events => [[_('Relevance'), ''], [_('Name'), 'name_sort asc']], | |
| 136 | - :articles => [[_('Relevance'), ''], [_('Name'), 'name_sort asc'], [_('Most recent'), 'updated_at desc']], | |
| 137 | - :enterprises => [[_('Relevance'), ''], [_('Name'), 'name_sort asc']], | |
| 138 | - :people => [[_('Relevance'), ''], [_('Name'), 'name_sort asc']], | |
| 139 | - :communities => [[_('Relevance'), ''], [_('Name'), 'name_sort asc']], | |
| 140 | - } | |
| 165 | + options = SortOptions[asset].map do |name, options| | |
| 166 | + next if options[:if] and ! instance_eval(&options[:if]) | |
| 167 | + [_(options[:label]), name.to_s] | |
| 168 | + end.compact | |
| 141 | 169 | |
| 142 | 170 | content_tag('div', _('Sort results by ') + |
| 143 | - select_tag(asset.to_s + '[order]', options_for_select(options[asset], params[:order_by]), | |
| 144 | - {:onchange => "window.location=jQuery.param.querystring(window.location.href, { 'order_by' : this.options[this.selectedIndex].value})"}), | |
| 171 | + select_tag(asset.to_s + '[order]', options_for_select(options, params[:order_by] || 'none'), | |
| 172 | + {:onchange => "window.location = jQuery.param.querystring(window.location.href, { 'order_by' : this.options[this.selectedIndex].value})"}), | |
| 145 | 173 | :class => "search-ordering") |
| 146 | 174 | end |
| 147 | 175 | ... | ... |
app/models/article.rb
| ... | ... | @@ -618,15 +618,14 @@ class Article < ActiveRecord::Base |
| 618 | 618 | def f_category |
| 619 | 619 | self.categories.collect(&:name) |
| 620 | 620 | end |
| 621 | - def name_sort | |
| 621 | + | |
| 622 | + delegate :region, :region_id, :environment, :environment_id, :to => :profile | |
| 623 | + def name_sortable # give a different name for solr | |
| 622 | 624 | name |
| 623 | 625 | end |
| 624 | 626 | def public |
| 625 | 627 | self.public? |
| 626 | 628 | end |
| 627 | - def environment_id | |
| 628 | - profile.environment_id | |
| 629 | - end | |
| 630 | 629 | public |
| 631 | 630 | |
| 632 | 631 | acts_as_faceted :fields => { |
| ... | ... | @@ -639,16 +638,24 @@ class Article < ActiveRecord::Base |
| 639 | 638 | :category_query => proc { |c| "f_category:\"#{c.name}\"" }, |
| 640 | 639 | :order => [:f_type, :f_published_at, :f_profile_type, :f_category] |
| 641 | 640 | |
| 642 | - acts_as_searchable :additional_fields => [ | |
| 643 | - {:name_sort => {:type => :string}}, | |
| 644 | - {:public => {:type => :boolean}}, | |
| 645 | - {:environment_id => {:type => :integer}}, | |
| 646 | - ] + facets_fields_for_solr, | |
| 647 | - :exclude_fields => [:setting], | |
| 648 | - :include => [:profile, :comments, :categories], | |
| 649 | - :facets => facets_option_for_solr, | |
| 650 | - :boost => proc {|a| 10 if a.profile.enabled}, | |
| 651 | - :if => proc{|a| ! ['RssFeed'].include?(a.class.name)} | |
| 641 | + acts_as_searchable :fields => facets_fields_for_solr + [ | |
| 642 | + # searched fields | |
| 643 | + {:name => {:type => :text, :boost => 2.0}}, | |
| 644 | + {:slug => :text}, {:body => :text}, | |
| 645 | + {:abstract => :text}, {:filename => :text}, | |
| 646 | + # filtered fields | |
| 647 | + {:public => :boolean}, {:environment_id => :integer}, | |
| 648 | + :language, :published, | |
| 649 | + # ordered/query-boosted fields | |
| 650 | + {:name_sortable => :string}, :last_changed_by_id, :published_at, :is_image, | |
| 651 | + :updated_at, :created_at, | |
| 652 | + ], :include => [ | |
| 653 | + {:profile => {:fields => [:name, :identifier, :address, :nickname, :region_id, :lat, :lng]}}, | |
| 654 | + {:comments => {:fields => [:title, :body, :author_name, :author_email]}}, | |
| 655 | + {:categories => {:fields => [:name, :path, :slug, :lat, :lng, :acronym, :abbreviation]}}, | |
| 656 | + ], :facets => facets_option_for_solr, | |
| 657 | + :boost => proc { |a| 10 if a.profile.enabled }, | |
| 658 | + :if => proc{ |a| ! ['RssFeed'].include?(a.class.name) } | |
| 652 | 659 | handle_asynchronously :solr_save |
| 653 | 660 | |
| 654 | 661 | private | ... | ... |
app/models/category.rb
| ... | ... | @@ -15,9 +15,6 @@ class Category < ActiveRecord::Base |
| 15 | 15 | |
| 16 | 16 | acts_as_filesystem |
| 17 | 17 | |
| 18 | - acts_as_searchable :additional_fields => [{:name => {:boost => 2.0}}] | |
| 19 | - handle_asynchronously :solr_save | |
| 20 | - | |
| 21 | 18 | has_many :article_categorizations, :dependent => :destroy |
| 22 | 19 | has_many :articles, :through => :article_categorizations |
| 23 | 20 | has_many :comments, :through => :articles |
| ... | ... | @@ -68,7 +65,7 @@ class Category < ActiveRecord::Base |
| 68 | 65 | end |
| 69 | 66 | |
| 70 | 67 | def upcoming_events(limit = 10) |
| 71 | - self.events.find(:all, :conditions => [ 'start_date >= ?', Date.today ], :order => 'start_date') | |
| 68 | + self.events.paginate(:conditions => [ 'start_date >= ?', Date.today ], :order => 'start_date', :page => 1, :per_page => limit) | |
| 72 | 69 | end |
| 73 | 70 | |
| 74 | 71 | def display_in_menu? |
| ... | ... | @@ -92,4 +89,23 @@ class Category < ActiveRecord::Base |
| 92 | 89 | self.children.find(:all, :conditions => {:display_in_menu => true}).empty? |
| 93 | 90 | end |
| 94 | 91 | |
| 92 | + private | |
| 93 | + def name_sortable # give a different name for solr | |
| 94 | + name | |
| 95 | + end | |
| 96 | + public | |
| 97 | + | |
| 98 | + acts_as_searchable :fields => [ | |
| 99 | + # searched fields | |
| 100 | + {:name => {:type => :text, :boost => 2.0}}, | |
| 101 | + {:path => :text}, {:slug => :text}, | |
| 102 | + {:abbreviation => :text}, {:acronym => :text}, | |
| 103 | + # filtered fields | |
| 104 | + :parent_id, | |
| 105 | + # ordered/query-boosted fields | |
| 106 | + {:name_sortable => :string}, | |
| 107 | + ] | |
| 108 | + after_save_reindex [:articles, :profiles], :with => :delayed_job | |
| 109 | + handle_asynchronously :solr_save | |
| 110 | + | |
| 95 | 111 | end | ... | ... |
app/models/certifier.rb
app/models/image.rb
app/models/product_category.rb
| 1 | 1 | class ProductCategory < Category |
| 2 | + # FIXME: do not allow category with products or inputs to be destroyed | |
| 2 | 3 | has_many :products |
| 3 | 4 | has_many :inputs |
| 4 | 5 | |
| ... | ... | @@ -9,4 +10,7 @@ class ProductCategory < Category |
| 9 | 10 | def self.menu_categories(top_category, env) |
| 10 | 11 | top_category ? top_category.children : top_level_for(env).select{|c|c.kind_of?(ProductCategory)} |
| 11 | 12 | end |
| 13 | + | |
| 14 | + after_save_reindex [:products], :with => :delayed_job | |
| 15 | + | |
| 12 | 16 | end | ... | ... |
app/models/profile.rb
| ... | ... | @@ -87,7 +87,7 @@ class Profile < ActiveRecord::Base |
| 87 | 87 | named_scope :more_popular |
| 88 | 88 | named_scope :more_active |
| 89 | 89 | |
| 90 | - named_scope :more_recent, :order => "updated_at DESC" | |
| 90 | + named_scope :more_recent, :order => "created_at DESC" | |
| 91 | 91 | |
| 92 | 92 | acts_as_trackable :dependent => :destroy |
| 93 | 93 | |
| ... | ... | @@ -125,8 +125,6 @@ class Profile < ActiveRecord::Base |
| 125 | 125 | |
| 126 | 126 | validates_length_of :description, :maximum => 550, :allow_nil => true |
| 127 | 127 | |
| 128 | - acts_as_mappable :default_units => :kms | |
| 129 | - | |
| 130 | 128 | # Valid identifiers must match this format. |
| 131 | 129 | IDENTIFIER_FORMAT = /^#{Noosfero.identifier_format}$/ |
| 132 | 130 | |
| ... | ... | @@ -859,7 +857,8 @@ private :generate_url, :url_options |
| 859 | 857 | c.name |
| 860 | 858 | end |
| 861 | 859 | end |
| 862 | - def name_sort | |
| 860 | + | |
| 861 | + def name_sortable # give a different name for solr | |
| 863 | 862 | name |
| 864 | 863 | end |
| 865 | 864 | def public |
| ... | ... | @@ -875,13 +874,24 @@ private :generate_url, :url_options |
| 875 | 874 | :category_query => proc { |c| "f_categories:#{c.id}" }, |
| 876 | 875 | :order => [:f_region, :f_categories] |
| 877 | 876 | |
| 878 | - acts_as_searchable :additional_fields => [ | |
| 879 | - {:name_sort => {:type => :string}}, | |
| 880 | - {:public => {:type => :boolean}}, | |
| 881 | - :extra_data_for_index ] + facets.keys.map{|i| {i => :facet}}, | |
| 882 | - :boost => proc {|p| 10 if p.enabled}, | |
| 883 | - :include => [:categories, :region], | |
| 884 | - :facets => facets.keys | |
| 877 | + acts_as_searchable :fields => facets_fields_for_solr + [:extra_data_for_index, | |
| 878 | + # searched fields | |
| 879 | + {:name => {:type => :text, :boost => 2.0}}, | |
| 880 | + {:identifier => :text}, {:address => :text}, {:nickname => :text}, | |
| 881 | + # filtered fields | |
| 882 | + {:public => :boolean}, {:environment_id => :integer}, | |
| 883 | + # ordered/query-boosted fields | |
| 884 | + {:name_sortable => :string}, {:user_id => :integer}, | |
| 885 | + :enabled, :active, :validated, :public_profile, | |
| 886 | + {:lat => :float}, {:lng => :float}, | |
| 887 | + :updated_at, :created_at, | |
| 888 | + ], | |
| 889 | + :include => [ | |
| 890 | + {:region => {:fields => [:name, :path, :slug, :lat, :lng]}}, | |
| 891 | + {:categories => {:fields => [:name, :path, :slug, :lat, :lng, :acronym, :abbreviation]}}, | |
| 892 | + ], :facets => facets_option_for_solr, | |
| 893 | + :boost => proc{ |p| 10 if p.enabled } | |
| 894 | + after_save_reindex [:articles], :with => :delayed_job | |
| 885 | 895 | handle_asynchronously :solr_save |
| 886 | 896 | |
| 887 | 897 | def control_panel_settings_button | ... | ... |
app/models/qualifier.rb
app/views/search/_article.rhtml
| ... | ... | @@ -3,9 +3,10 @@ |
| 3 | 3 | <div class="search-content-first-column"> |
| 4 | 4 | <%= render :partial => 'image', :object => article %> |
| 5 | 5 | </div> |
| 6 | - <div class="search-content-second-column"> | |
| 7 | - | |
| 8 | - </div> | |
| 6 | + <table class="noborder search-content-second-column"> | |
| 7 | + <%= render :partial => 'article_common', :object => article %> | |
| 8 | + </table> | |
| 9 | + <%= render :partial => 'article_last_change', :object => article %> | |
| 9 | 10 | |
| 10 | 11 | <div style="clear:both"></div> |
| 11 | 12 | </li> | ... | ... |
app/views/search/_article_author.rhtml
| 1 | 1 | <% article = article_author %> |
| 2 | 2 | |
| 3 | -<div class="search-article-author"> | |
| 4 | - <div class="search-article-author-name"> | |
| 5 | - <span class="search-field-label"><%= _("Author") %></span> | |
| 3 | +<tr class="search-article-author search-article-author-name"> | |
| 4 | + <td class="search-field-label"><%= _("Author") %></td> | |
| 5 | + <td> | |
| 6 | 6 | <%= link_to_profile article.profile.name, article.profile.identifier %> |
| 7 | - </div> | |
| 8 | -</div> | |
| 7 | + </td> | |
| 8 | +</tr> | ... | ... |
app/views/search/_article_categories.rhtml
| 1 | -<div class="search-article-categories"> | |
| 2 | - <span class="search-field-label"><%= _('Categories') %></span> | |
| 3 | - <span class="search-article-categories-container"> | |
| 1 | +<tr class="search-article-categories"> | |
| 2 | + <td class="search-field-label"><%= _('Categories') %></td> | |
| 3 | + <td class="search-article-categories-container <%= "search-field-none" if article_categories.empty? %>"> | |
| 4 | 4 | <% article_categories.each do |category| %> |
| 5 | 5 | <%= link_to_category category, false, :class => "search-article-category" %> |
| 6 | 6 | <% end %> |
| 7 | - <span class="search-field-none"><%= _('None') if article_categories.empty? %></span> | |
| 8 | - </span> | |
| 9 | -</div> | |
| 7 | + <%= _('None') if article_categories.empty? %> | |
| 8 | + </td> | |
| 9 | +</tr> | ... | ... |
app/views/search/_article_common.rhtml
| ... | ... | @@ -5,4 +5,3 @@ |
| 5 | 5 | <%= render :partial => 'article_description', :object => article if show_description %> |
| 6 | 6 | <%= render :partial => 'article_tags', :object => article.tags %> |
| 7 | 7 | <%= render :partial => 'article_categories', :object => article.categories %> |
| 8 | -<%= render :partial => 'article_last_change', :object => article %> | ... | ... |
app/views/search/_article_description.rhtml
| 1 | 1 | <% article = article_description %> |
| 2 | 2 | |
| 3 | -<div class="search-article-description"> | |
| 4 | - <span class="search-field-label"><%= _("Description") %></span> | |
| 3 | +<tr class="search-article-description"> | |
| 4 | + <td class="search-field-label"><%= _("Description") %></td> | |
| 5 | + | |
| 5 | 6 | <% if !article.body.blank? %> |
| 6 | - <% body_stripped = strip_tags(article.body.to_s) %> | |
| 7 | - <span class="search-article-body"><%= excerpt(body_stripped, body_stripped.first(3), 200) %></span> | |
| 7 | + <% description = strip_tags(article.body.to_s) %> | |
| 8 | + <% description = excerpt(description, description.first(3), 200).gsub!(/\s{2,}/, ' ') %> | |
| 9 | + <td class="search-article-body"><%= description %></td> | |
| 8 | 10 | <% else %> |
| 9 | - <span class="search-field-none"><%= _('None') %></span> | |
| 11 | + <td class="search-field-none"><%= _('None') %></td> | |
| 10 | 12 | <% end %> |
| 11 | -</div> | |
| 13 | +</tr> | ... | ... |
app/views/search/_article_last_change.rhtml
| 1 | 1 | <% article = article_last_change %> |
| 2 | 2 | |
| 3 | 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> | |
| 4 | + <% if article.last_changed_by and article.last_changed_by != article.profile %> | |
| 5 | + <span><%= _('by %{name} at %{date}') % {:name => link_to(article.last_changed_by.name, article.last_changed_by.url), | |
| 6 | + :date => show_date(article.updated_at) } %></span> | |
| 6 | 7 | <% else %> |
| 7 | 8 | <span><%= _('Last update: %s.') % show_date(article.updated_at) %></span> |
| 8 | 9 | <% end %> | ... | ... |
app/views/search/_article_tags.rhtml
| 1 | -<div class="search-article-tags"> | |
| 2 | - <span class="search-field-label"><%= _('Tags') %></span> | |
| 3 | - <span class="search-article-tags-container"> | |
| 1 | +<tr class="search-article-tags"> | |
| 2 | + <td class="search-field-label"><%= _('Tags') %></td> | |
| 3 | + <td class="search-article-tags-container <%= "search-field-none" if article_tags.empty? %>"> | |
| 4 | 4 | <% article_tags.each do |tag| %> |
| 5 | 5 | <%= link_to_tag tag, :class => "search-article-tag" %> |
| 6 | 6 | <% end %> |
| 7 | - <span class="search-field-none"><%= _('None') if article_tags.empty? %></span> | |
| 8 | - </span> | |
| 9 | -</div> | |
| 7 | + <%= _('None') if article_tags.empty? %></td> | |
| 8 | + </td> | |
| 9 | +</tr> | ... | ... |
app/views/search/_blog.rhtml
| ... | ... | @@ -3,21 +3,22 @@ |
| 3 | 3 | <div class="search-content-first-column"> |
| 4 | 4 | <%= render :partial => 'image', :object => blog %> |
| 5 | 5 | </div> |
| 6 | - <div class="search-content-second-column"> | |
| 7 | - <div class="search-blog-items"> | |
| 8 | - <span class="search-field-label"><%= _("Last posts") %></span> | |
| 6 | + <table class="noborder search-content-second-column"> | |
| 7 | + <tr class="search-blog-items"> | |
| 8 | + <td class="search-field-label"><%= _("Last posts") %></td> | |
| 9 | + | |
| 9 | 10 | <% 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> | |
| 11 | + <td class="<%= "search-field-none" if r.empty? %>"> | |
| 12 | + <% r.each do |a| %> | |
| 13 | + <%= link_to a.title, a.view_url, :class => 'search-blog-sample-item '+icon_for_article(a) %> | |
| 14 | + <% end %> | |
| 15 | + <%= _('None') if r.empty? %> | |
| 16 | + </td> | |
| 17 | + </tr> | |
| 15 | 18 | |
| 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> | |
| 19 | + <%= render :partial => 'article_common', :object => blog %> | |
| 20 | + </table> | |
| 21 | + <%= render :partial => 'article_last_change', :object => blog %> | |
| 21 | 22 | |
| 22 | 23 | <div style="clear: both;"/></div> |
| 23 | 24 | </li> | ... | ... |
app/views/search/_display_results.rhtml
| 1 | 1 | <div id="search-results" class="<%= 'only-one-result-box' if @results.size == 1 %>"> |
| 2 | - | |
| 3 | 2 | <% @order.each do |name| %> |
| 4 | 3 | <% results = @results[name] %> |
| 5 | - <% if !results.nil? and !results.empty? %> | |
| 6 | - <div class="search-results-<%= name %> search-results-box"> | |
| 7 | - | |
| 4 | + <% empty = results.nil? || results.empty? %> | |
| 5 | + | |
| 6 | + <div class="search-results-<%= name %> search-results-box <%= "search-results-empty" if empty %>"> | |
| 7 | + <% if not empty %> | |
| 8 | + <% partial = partial_for_class(results.first.class.class_name.constantize) %> | |
| 9 | + | |
| 8 | 10 | <% if @results.size > 1 %> |
| 9 | 11 | <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' ) %> | |
| 12 | + <% if results.total_entries > SearchController::MULTIPLE_SEARCH_LIMIT %> | |
| 13 | + <%= link_to(_('see all (%d)') % results.total_entries, params.merge(:action => name), :class => 'see-more' ) %> | |
| 14 | + <% end %> | |
| 12 | 15 | <% end %> |
| 13 | - | |
| 14 | - <% partial = partial_for_class(results.first.class.class_name.constantize) %> | |
| 16 | + | |
| 15 | 17 | <div class="search-results-innerbox search-results-type-<%= partial %> <%= 'common-profile-list-block' if partial == 'profile' %>"> |
| 16 | - <div class="search-results-innerbox2"><!-- the innerbox2 is a workarround for MSIE --> | |
| 17 | - <ul> | |
| 18 | - <% results.each do |hit| %> | |
| 19 | - <%= render :partial => partial_for_class(hit.class), :object => hit %> | |
| 20 | - <% end %> | |
| 21 | - </ul> | |
| 22 | - <hr /> | |
| 23 | - </div><!-- end class="search-results-innerbox2" --> | |
| 24 | - </div><!-- end class="search-results-innerbox" --> | |
| 25 | - | |
| 26 | - </div><!-- end class="search-results-<%= name %>" --> | |
| 27 | - <% else %> | |
| 28 | - <div class="search-results-<%= name %> search-results-empty search-results-box"> | |
| 18 | + <ul> | |
| 19 | + <% results.each do |hit| %> | |
| 20 | + <%= render :partial => partial_for_class(hit.class), :object => hit %> | |
| 21 | + <% end %> | |
| 22 | + </ul> | |
| 23 | + </div> | |
| 24 | + <% else %> | |
| 29 | 25 | <% if @results.size > 1 %> |
| 30 | 26 | <h3><%= @names[name] %></h3> |
| 31 | 27 | <% end %> |
| 32 | 28 | <div class="search-results-innerbox search-results-type-empty"> |
| 33 | 29 | <div> <%= _('None') %> </div> |
| 34 | - <hr /> | |
| 35 | - </div><!-- end class="search-results-innerbox" --> | |
| 36 | - </div><!-- end class="search-results-<%= name %>" --> | |
| 37 | - <% end %> | |
| 30 | + </div> | |
| 31 | + <% end %> | |
| 32 | + </div> | |
| 38 | 33 | <% end %> |
| 39 | 34 | |
| 40 | 35 | <div style="clear:both"></div> |
| 41 | 36 | |
| 42 | 37 | <%= add_zoom_to_images %> |
| 43 | -</div><!-- end id="search-results" --> | |
| 38 | +</div> | |
| 44 | 39 | ... | ... |
app/views/search/_event.rhtml
| ... | ... | @@ -3,22 +3,23 @@ |
| 3 | 3 | <div class="search-content-first-column"> |
| 4 | 4 | <%= render :partial => 'image', :object => event %> |
| 5 | 5 | </div> |
| 6 | - <div class="search-content-second-column"> | |
| 6 | + <table class="noborder search-content-second-column"> | |
| 7 | 7 | <% if event.start_date %> |
| 8 | - <div class="searc-article-event-date"> | |
| 9 | - <span class="search-field-label"><%= _('Start date') %></span> | |
| 10 | - <span class="article-item-date"><%= event.start_date %></span> | |
| 11 | - </div> | |
| 8 | + <tr class="searc-article-event-date"> | |
| 9 | + <td class="search-field-label"><%= _('Start date') %></td> | |
| 10 | + <td class="article-item-date"><%= event.start_date %></td> | |
| 11 | + </tr> | |
| 12 | 12 | <% end %> |
| 13 | 13 | <% if event.end_date %> |
| 14 | - <div class="searc-article-event-date"> | |
| 15 | - <span class="search-field-label"><%= _('End date') %></span> | |
| 16 | - <span class="article-item-date"><%= event.end_date %></span> | |
| 17 | - </div> | |
| 14 | + <tr class="searc-article-event-date"> | |
| 15 | + <td class="search-field-label"><%= _('End date') %></td> | |
| 16 | + <td class="article-item-date"><%= event.end_date %></td> | |
| 17 | + </tr> | |
| 18 | 18 | <% end %> |
| 19 | 19 | |
| 20 | 20 | <%= render :partial => 'article_common', :object => event %> |
| 21 | - </div> | |
| 21 | + </table> | |
| 22 | + <%= render :partial => 'article_last_change', :object => event %> | |
| 22 | 23 | |
| 23 | 24 | <div style="clear: both"></div> |
| 24 | 25 | </li> | ... | ... |
app/views/search/_folder.rhtml
| ... | ... | @@ -3,18 +3,22 @@ |
| 3 | 3 | <div class="search-content-first-column"> |
| 4 | 4 | <%= render :partial => 'image', :object => folder %> |
| 5 | 5 | </div> |
| 6 | - <div class="search-content-second-column"> | |
| 7 | - <div class="search-folder-items"> | |
| 8 | - <span class="search-field-label"><%= _("Last items") %></span> | |
| 6 | + <table class="noborder search-content-second-column"> | |
| 7 | + <tr class="search-folder-items"> | |
| 8 | + <td class="search-field-label"><%= _("Last items") %></td> | |
| 9 | + | |
| 9 | 10 | <% 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> | |
| 11 | + <td class="<%= "search-field-none" if r.empty? %>"> | |
| 12 | + <% r.each do |a| %> | |
| 13 | + <%= link_to a.title, a.view_url, :class => 'search-folder-sample-item '+icon_for_article(a) %> | |
| 14 | + <% end %> | |
| 15 | + <%= _('None') if r.empty? %> | |
| 16 | + </td> | |
| 17 | + </tr> | |
| 15 | 18 | |
| 16 | 19 | <%= render :partial => 'article_common', :object => folder %> |
| 17 | - </div> | |
| 20 | + </table> | |
| 21 | + <%= render :partial => 'article_last_change', :object => folder %> | |
| 18 | 22 | |
| 19 | 23 | <div style="clear:both"></div> |
| 20 | 24 | </li> | ... | ... |
app/views/search/_forum.rhtml
| ... | ... | @@ -3,18 +3,22 @@ |
| 3 | 3 | <div class="search-content-first-column"> |
| 4 | 4 | <%= render :partial => 'image', :object => forum %> |
| 5 | 5 | </div> |
| 6 | - <div class="search-content-second-column"> | |
| 7 | - <div class="search-forum-items"> | |
| 8 | - <span class="search-field-label"><%= _("Last topics") %></span> | |
| 6 | + <table class="noborder search-content-second-column"> | |
| 7 | + <tr class="search-forum-items"> | |
| 8 | + <td class="search-field-label"><%= _("Last topics") %></td> | |
| 9 | + | |
| 9 | 10 | <% 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> | |
| 11 | + <td class="<%= "search-field-none" if r.empty? %>"> | |
| 12 | + <% r.each do |a| %> | |
| 13 | + <%= link_to a.title, a.view_url, :class => 'search-forum-sample-item '+icon_for_article(a) %> | |
| 14 | + <% end %> | |
| 15 | + <%= _('None') if r.empty? %> | |
| 16 | + </td> | |
| 17 | + </tr> | |
| 15 | 18 | |
| 16 | 19 | <%= render :partial => 'article_common', :object => forum %> |
| 17 | - </div> | |
| 20 | + </table> | |
| 21 | + <%= render :partial => 'article_last_change', :object => forum %> | |
| 18 | 22 | |
| 19 | 23 | <div style="clear:both"></div> |
| 20 | 24 | </li> | ... | ... |
app/views/search/_gallery.rhtml
| ... | ... | @@ -3,9 +3,10 @@ |
| 3 | 3 | <div class="search-content-first-column"> |
| 4 | 4 | <%= render :partial => 'image', :object => gallery %> |
| 5 | 5 | </div> |
| 6 | - <div class="search-content-second-column"> | |
| 6 | + <table class="noborder search-content-second-column"> | |
| 7 | 7 | <%= render :partial => 'article_common', :object => gallery %> |
| 8 | - </div> | |
| 8 | + </table> | |
| 9 | + <%= render :partial => 'article_last_change', :object => gallery %> | |
| 9 | 10 | |
| 10 | 11 | <div style="clear: both"></div> |
| 11 | 12 | </li> | ... | ... |
app/views/search/_image.rhtml
| 1 | 1 | <div class="search-image-container"> |
| 2 | 2 | |
| 3 | - <% if image.is_a? UploadedFile %> | |
| 3 | + <% if image.is_a? UploadedFile and image.filename %> | |
| 4 | 4 | <% extension = image.filename[(image.filename.rindex('.')+1)..-1].downcase %> |
| 5 | 5 | <% if ['jpg', 'jpeg', 'gif', 'png', 'tiff', 'svg'].include? extension %> |
| 6 | 6 | <%= link_to '', image.view_url, :class => "search-image-pic", :style => 'background-image: url(%s)'% image.public_filename(:thumb) %> | ... | ... |
app/views/search/_product.rhtml
| ... | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | <% extra_properties = @plugins.dispatch(:asset_product_properties, product)%> |
| 3 | 3 | |
| 4 | 4 | <li class="search-product-item"> |
| 5 | + | |
| 5 | 6 | <div class="search-product-item-first-column"> |
| 6 | 7 | <%= render :partial => 'search/image', :object => product %> |
| 7 | 8 | |
| ... | ... | @@ -18,17 +19,9 @@ |
| 18 | 19 | <% end %> |
| 19 | 20 | <% end %> |
| 20 | 21 | <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 | |
| 25 | - when 0..24.999 then ["0", _("")]; | |
| 26 | - when 25..49.999 then ["25", _("25%")]; | |
| 27 | - when 50..74.999 then ["50", _("50%")]; | |
| 28 | - when 75..99.999 then ["75", _("75%")]; | |
| 29 | - when 100 then ["100", _("100%")]; | |
| 30 | - end %> | |
| 31 | - <div class="search-product-percentage-from-solidarity-economy search-product-ecosol-percentage-icon-<%=p[0]%>" title="<%=_('Percentage of inputs from solidarity economy')%>"> | |
| 22 | + <% if p = product.percentage_from_solidarity_economy %> | |
| 23 | + <div class="search-product-percentage-from-solidarity-economy search-product-ecosol-percentage-icon-<%= p[0].to_s %>" | |
| 24 | + title="<%=_('Percentage of inputs from solidarity economy')%>"> | |
| 32 | 25 | <%= p[1] %> |
| 33 | 26 | </div> |
| 34 | 27 | <% end %> | ... | ... |
app/views/search/_profile.rhtml
app/views/search/_search_form.rhtml
| ... | ... | @@ -5,10 +5,13 @@ |
| 5 | 5 | |
| 6 | 6 | <%= hidden_field_tag :display, params[:display] %> |
| 7 | 7 | |
| 8 | - <% CGI::unescape(request.request_uri).split("&").each do |part| %> | |
| 9 | - <% if part.start_with? "facet" %> | |
| 10 | - <% name_value = part.split("=") %> | |
| 11 | - <%= hidden_field_tag name_value[0], name_value[1] %> | |
| 8 | + <% params_uri = CGI::unescape(request.request_uri) %> | |
| 9 | + <% if params_uri.index('?') %> | |
| 10 | + <% params_uri[(params_uri.index('?')+1)..-1].to_s.split("&").each do |part| %> | |
| 11 | + <% if part.start_with? "facet" %> | |
| 12 | + <% name_value = part.split("=") %> | |
| 13 | + <%= hidden_field_tag name_value[0], name_value[1] %> | |
| 14 | + <% end %> | |
| 12 | 15 | <% end %> |
| 13 | 16 | <% end %> |
| 14 | 17 | |
| ... | ... | @@ -16,19 +19,9 @@ |
| 16 | 19 | <span class="formfield"> |
| 17 | 20 | <%= text_field_tag 'query', @query, :id => 'search-input', :size => 50 %> |
| 18 | 21 | <%= javascript_tag "jQuery('#search-input').attr('title', \"#{hint}\").hint()" if defined?(hint) %> |
| 19 | - <%= javascript_tag "jQuery('.search_form').submit(function() { | |
| 20 | - if (jQuery('#search-input').val().length < 3) { | |
| 21 | - jQuery('#search-empty-query-error').slideDown(200).delay(2500).slideUp(200); | |
| 22 | - return false; | |
| 23 | - } | |
| 24 | - });" %> | |
| 25 | 22 | </span> |
| 26 | 23 | |
| 27 | 24 | <%= submit_button(:search, _('Search')) %> |
| 28 | - | |
| 29 | - <div id="search-empty-query-error"> | |
| 30 | - <%= _("Type more than 2 characters to start a search") %> | |
| 31 | - </div> | |
| 32 | 25 | </div> |
| 33 | 26 | |
| 34 | 27 | <% end %> | ... | ... |
app/views/search/_text_article.rhtml
| 1 | 1 | <li class="search-text-article-item article-item"> |
| 2 | 2 | <%= link_to(text_article.title, text_article.url, :class => "search-result-title") %> |
| 3 | + | |
| 3 | 4 | <div class="search-content-first-column"> |
| 4 | 5 | <%= render :partial => 'image', :object => text_article %> |
| 5 | 6 | </div> |
| 6 | - <div class="search-content-second-column"> | |
| 7 | + <table class="noborder search-content-second-column"> | |
| 7 | 8 | <%= render :partial => 'article_common', :object => text_article %> |
| 8 | - </div> | |
| 9 | + </table> | |
| 10 | + <%= render :partial => 'article_last_change', :object => text_article %> | |
| 9 | 11 | |
| 10 | 12 | <div style="clear: both"></div> |
| 11 | 13 | </li> | ... | ... |
app/views/search/_uploaded_file.rhtml
| 1 | 1 | <li class="search-uploaded-file-item article-item"> |
| 2 | 2 | <%= link_to uploaded_file.filename, uploaded_file.view_url, :class => 'search-result-title' %> |
| 3 | - <hr class="clear" /> | |
| 4 | 3 | |
| 5 | 4 | <div class="search-content-first-column"> |
| 6 | 5 | <%= render :partial => 'image', :object => uploaded_file %> |
| 7 | 6 | </div> |
| 8 | 7 | |
| 9 | - <div class="search-uploaded-file-second-column"> | |
| 8 | + <table class="noborder search-content-second-column"> | |
| 10 | 9 | <%= render :partial => 'article_author', :object => uploaded_file %> |
| 10 | + <%= render :partial => 'article_description', :object => uploaded_file %> | |
| 11 | 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> | |
| 12 | + <% if uploaded_file.parent and uploaded_file.parent.published? %> | |
| 13 | + <tr class="search-uploaded-file-parent"> | |
| 14 | + <td class="search-field-label"><%= uploaded_file.parent.gallery? ? _("Gallery") : _("Folder") %></td> | |
| 15 | + <td><%= link_to uploaded_file.parent.name, uploaded_file.parent.url %></td> | |
| 16 | + </tr> | |
| 17 | + <% end %> | |
| 30 | 18 | |
| 31 | 19 | <%= render :partial => 'article_tags', :object => uploaded_file.tags %> |
| 32 | 20 | <%= render :partial => 'article_categories', :object => uploaded_file.categories %> |
| 33 | - <%= render :partial => 'article_last_change', :object => uploaded_file %> | |
| 34 | - </div> | |
| 21 | + </table> | |
| 22 | + <%= render :partial => 'article_last_change', :object => uploaded_file %> | |
| 35 | 23 | |
| 36 | 24 | <div style="clear:both"></div> |
| 37 | 25 | </li> | ... | ... |
app/views/search/products.rhtml
app/views/search/tag.rhtml
| ... | ... | @@ -7,16 +7,7 @@ |
| 7 | 7 | <% end %> |
| 8 | 8 | |
| 9 | 9 | <% cache_timeout(@tag_cache_key, 4.hour) do %> |
| 10 | - <div class='search-tagged-items'> | |
| 11 | - <% @tagged.each do |hit| %> | |
| 12 | - <ul class="clean-list"> | |
| 13 | - <%= render :partial => partial_for_class(hit.class), :object => hit %> | |
| 14 | - </ul> | |
| 15 | - <br style='clear: left;'/> | |
| 16 | - <% end %> | |
| 17 | - | |
| 18 | - </div> | |
| 19 | - <%= pagination_links @tagged, :param_name => 'npage' %> | |
| 10 | + <%= display_results %> | |
| 20 | 11 | |
| 21 | 12 | <div style="clear: both"></div> |
| 22 | 13 | <% end %> | ... | ... |
public/designs/themes/base/style.css
| ... | ... | @@ -872,30 +872,6 @@ X.sep { |
| 872 | 872 | border-top: 1px solid #CCC; |
| 873 | 873 | } |
| 874 | 874 | |
| 875 | -#content .search-results-box a.see-more { | |
| 876 | - z-index: 10; | |
| 877 | - position: absolute; | |
| 878 | - bottom: 20px; | |
| 879 | - right: 20px; | |
| 880 | - background: transparent url(imgs/arrow-right-p.png) 100% 55% no-repeat; | |
| 881 | - border: none; | |
| 882 | - padding-right: 15px; | |
| 883 | - color: #000; | |
| 884 | - text-decoration: none; | |
| 885 | - font-weight: bold; | |
| 886 | -} | |
| 887 | -#content .search-results-box a.see-more:hover { | |
| 888 | - background: transparent url(imgs/arrow-right-p.png) 100% 55% no-repeat; | |
| 889 | - color: #888; | |
| 890 | -} | |
| 891 | - | |
| 892 | - | |
| 893 | -.search-results-type-article.search-results-innerbox { | |
| 894 | - padding: 5px 0px 5px 10px; | |
| 895 | - max-height: 215px; | |
| 896 | - height: 225px; | |
| 897 | -} | |
| 898 | - | |
| 899 | 875 | #content .search-results-type-article li, |
| 900 | 876 | #content .search-results-type-event li { |
| 901 | 877 | padding: 5px 0px; |
| ... | ... | @@ -1207,12 +1183,6 @@ table.profile th { |
| 1207 | 1183 | |
| 1208 | 1184 | /**************************** Browse *******************************/ |
| 1209 | 1185 | |
| 1210 | -.search-results-type-article.search-results-innerbox { | |
| 1211 | - padding: 5px 0px 5px 10px; | |
| 1212 | - max-height: 215px; | |
| 1213 | - height: 225px; | |
| 1214 | -} | |
| 1215 | - | |
| 1216 | 1186 | #content .search-results-type-article li { |
| 1217 | 1187 | padding: 5px 0px; |
| 1218 | 1188 | } | ... | ... |
public/stylesheets/application.css
| ... | ... | @@ -3216,7 +3216,7 @@ div#article-parent { |
| 3216 | 3216 | #agenda .calendar-day-out.selected { |
| 3217 | 3217 | background: none; |
| 3218 | 3218 | } |
| 3219 | -#agenda td { | |
| 3219 | +#agenda .agenda-calendar td { | |
| 3220 | 3220 | vertical-align: middle; |
| 3221 | 3221 | } |
| 3222 | 3222 | #agenda .agenda-calendar .current-month caption { | ... | ... |
public/stylesheets/search.css
| ... | ... | @@ -91,7 +91,8 @@ |
| 91 | 91 | margin: 0px; |
| 92 | 92 | padding: 0px; |
| 93 | 93 | } |
| 94 | -.controller-search #product-categories-menu .sub-opening, .controller-search #product-categories-menu .sub-closeing { | |
| 94 | +.controller-search #product-categories-menu .sub-opening, | |
| 95 | +.controller-search #product-categories-menu .sub-closeing { | |
| 95 | 96 | background-color: #FF8; |
| 96 | 97 | } |
| 97 | 98 | .controller-search #product-categories-menu .sub-opened { |
| ... | ... | @@ -101,9 +102,13 @@ |
| 101 | 102 | float: right; |
| 102 | 103 | } |
| 103 | 104 | .controller-search #content .search-results-box a.see-more { |
| 105 | + z-index: 10; | |
| 104 | 106 | position: absolute; |
| 105 | 107 | bottom: 0px; |
| 106 | 108 | right: 25px; |
| 109 | + color: black; | |
| 110 | + text-decoration: none; | |
| 111 | + font-weight: bold; | |
| 107 | 112 | font-size: 11px; |
| 108 | 113 | line-height: 11px; |
| 109 | 114 | background: #B8CFE7; |
| ... | ... | @@ -116,10 +121,14 @@ |
| 116 | 121 | color: #FFF; |
| 117 | 122 | text-decoration: none; |
| 118 | 123 | } |
| 124 | +.controller-search .search-results-innerbox.common-profile-list-block { | |
| 125 | + overflow: hidden; | |
| 126 | +} | |
| 119 | 127 | .controller-search .search-results-innerbox { |
| 120 | - padding: 8px 0px 10px 10px; | |
| 128 | + padding: 8px 10px 10px 10px; | |
| 129 | + overflow: auto; | |
| 130 | + overflow-x: hidden; | |
| 121 | 131 | height: 230px; |
| 122 | - overflow: visible; | |
| 123 | 132 | position: relative; /* work-arround-bug fo MSIE */ |
| 124 | 133 | } |
| 125 | 134 | .controller-search .search-results-innerbox hr { |
| ... | ... | @@ -138,7 +147,10 @@ |
| 138 | 147 | height: 0px; |
| 139 | 148 | visibility: hidden; |
| 140 | 149 | } |
| 141 | -.controller-search #content .search-results-type-article ul, .controller-search #content .search-results-type-article li, .controller-search #content .search-results-type-event ul, .controller-search #content .search-results-type-event li { | |
| 150 | +.search-results-type-article ul, | |
| 151 | +.controller-search #content .search-results-type-article li, | |
| 152 | +.controller-search #content .search-results-type-event ul, | |
| 153 | +.controller-search #content .search-results-type-event li { | |
| 142 | 154 | margin: 0px; |
| 143 | 155 | padding: 0px; |
| 144 | 156 | list-style: none; |
| ... | ... | @@ -146,21 +158,19 @@ |
| 146 | 158 | .controller-search #content .search-results-type-event li { |
| 147 | 159 | padding: 2px 0px 4px 0px; |
| 148 | 160 | } |
| 149 | -.controller-search #content .search-results-type-article li, .controller-search #content .search-results-type-event li { | |
| 150 | - padding: 0px 0px 4px 20px; | |
| 161 | +.controller-search #content .search-results-type-article li { | |
| 162 | + padding: 10px 0; | |
| 151 | 163 | background-repeat: no-repeat; |
| 152 | - border-color: transparent; | |
| 153 | 164 | } |
| 154 | -.controller-search #content .search-results-type-article li:hover, .controller-search #content .search-results-type-event li:hover { | |
| 165 | +.controller-search #content .search-results-type-article li:hover, | |
| 166 | +.controller-search #content .search-results-type-event li:hover { | |
| 155 | 167 | background-color: transparent; |
| 156 | 168 | } |
| 157 | -.controller-search .search-results-type-article .item_meta, .controller-search .search-results-type-event .item_meta { | |
| 169 | +.controller-search .search-results-type-article .item_meta, | |
| 170 | +.controller-search .search-results-type-event .item_meta { | |
| 158 | 171 | font-size: 10px; |
| 159 | 172 | color: #888; |
| 160 | 173 | } |
| 161 | -.search-results-type-article.search-results-innerbox { | |
| 162 | - overflow: auto; | |
| 163 | -} | |
| 164 | 174 | #content .only-one-result-box .search-results-enterprises li.vcard { |
| 165 | 175 | margin: 4.5px; |
| 166 | 176 | } |
| ... | ... | @@ -171,19 +181,14 @@ |
| 171 | 181 | min-height: 16px; |
| 172 | 182 | overflow: hidden; |
| 173 | 183 | } |
| 174 | -.controller-search #content .search-results-type-article ul { | |
| 184 | +.search-results-type-article ul { | |
| 175 | 185 | margin: 0; |
| 176 | - padding:0; | |
| 177 | -} | |
| 178 | -.controller-search #content .search-results-type-article li.article-item, | |
| 179 | -.controller-search .search-tagged-items li.article-item, | |
| 180 | -.controller-search #content .only-one-result-box li.search-product-item { | |
| 181 | - padding:0; | |
| 182 | - border-bottom:1px solid #000; | |
| 183 | - margin: 0 0 10px 0; | |
| 184 | - padding: 0 0 10px 0; | |
| 185 | - font-size: 11px; | |
| 186 | - height: auto; | |
| 186 | + padding: 0; | |
| 187 | +} | |
| 188 | +.search-results-type-article li.article-item, | |
| 189 | +.search-tagged-items li.article-item, | |
| 190 | +.only-one-result-box li.search-product-item { | |
| 191 | + border-bottom: 1px solid #000; | |
| 187 | 192 | } |
| 188 | 193 | .search-result-title { |
| 189 | 194 | display:inline-block; |
| ... | ... | @@ -199,8 +204,6 @@ |
| 199 | 204 | } |
| 200 | 205 | li.article-item .search-result-title { |
| 201 | 206 | color: #007788; |
| 202 | - clear:both; | |
| 203 | - float:left; | |
| 204 | 207 | } |
| 205 | 208 | .search-article-tags, |
| 206 | 209 | .search-uploaded-file-description, |
| ... | ... | @@ -216,37 +219,24 @@ li.article-item .search-result-title { |
| 216 | 219 | clear: both; |
| 217 | 220 | } |
| 218 | 221 | .search-article-body { |
| 219 | - float: right; | |
| 220 | 222 | width: 80%; |
| 221 | 223 | margin-bottom: 7px; |
| 222 | 224 | } |
| 223 | 225 | .search-field-none { |
| 224 | 226 | color: #ccc; |
| 225 | 227 | } |
| 226 | -.search-forum-items .search-field-label { | |
| 227 | - height: 36px; | |
| 228 | -} | |
| 229 | 228 | .search-field-label { |
| 230 | - display: block; | |
| 231 | - float: left; | |
| 232 | 229 | font-size: 10px; |
| 233 | 230 | font-weight: bold; |
| 234 | - height: 18px; | |
| 235 | - line-height: 18px; | |
| 236 | - margin: 0 5px 0 0; | |
| 237 | 231 | text-transform: uppercase; |
| 238 | 232 | width: 110px; |
| 233 | + display: block; | |
| 239 | 234 | } |
| 240 | 235 | .search-product-item-third-column .search-field-label { |
| 241 | 236 | width: 150px; |
| 242 | 237 | } |
| 243 | -li.article-item .search-article-tags-container, | |
| 244 | -li.article-item .search-article-categories-container { | |
| 245 | - display: block; | |
| 246 | - min-height: 18px; | |
| 247 | - line-height: 18px; | |
| 248 | -} | |
| 249 | -.search-article-tags .search-article-tag, .search-article-categories .search-article-category { | |
| 238 | +.search-article-tags .search-article-tag, | |
| 239 | +.search-article-categories .search-article-category { | |
| 250 | 240 | background: #BBB; |
| 251 | 241 | padding:0 2px; |
| 252 | 242 | -moz-border-radius: 3px; |
| ... | ... | @@ -260,10 +250,12 @@ li.article-item .search-article-categories-container { |
| 260 | 250 | color: #FFF; |
| 261 | 251 | font-size: 10px; |
| 262 | 252 | } |
| 263 | -.search-article-tags a.search-article-tag, .search-article-categories a.search-article-category { | |
| 253 | +.search-article-tags a.search-article-tag, | |
| 254 | +.search-article-categories a.search-article-category { | |
| 264 | 255 | text-decoration:none; |
| 265 | 256 | } |
| 266 | -.search-article-tags a:hover.search-article-tag, .search-article-categories a:hover.search-article-category { | |
| 257 | +.search-article-tags a:hover.search-article-tag, | |
| 258 | +.search-article-categories a:hover.search-article-category { | |
| 267 | 259 | background: #555753; |
| 268 | 260 | text-decoration:none; |
| 269 | 261 | } |
| ... | ... | @@ -292,7 +284,8 @@ li.article-item .search-article-categories-container { |
| 292 | 284 | .search-results-innerbox .menu-submenu { |
| 293 | 285 | bottom: 107px; |
| 294 | 286 | } |
| 295 | -.controller-search .search-results-type-product, .controller-search .search-results-type-event { | |
| 287 | +.controller-search .search-results-type-product, | |
| 288 | +.controller-search .search-results-type-event { | |
| 296 | 289 | overflow: auto; |
| 297 | 290 | } |
| 298 | 291 | li.search-product-item { |
| ... | ... | @@ -364,8 +357,8 @@ li.search-product-item { |
| 364 | 357 | float: left; |
| 365 | 358 | font-size: 70%; |
| 366 | 359 | background-repeat: no-repeat; |
| 367 | - height: 18px; | |
| 368 | - line-height: 18px; | |
| 360 | + height: 21px; | |
| 361 | + line-height: 21px; | |
| 369 | 362 | } |
| 370 | 363 | .search-product-ecosol-percentage-icon-0 { |
| 371 | 364 | background-image: none; |
| ... | ... | @@ -376,7 +369,8 @@ li.search-product-item { |
| 376 | 369 | .search-product-ecosol-percentage-icon-50 { |
| 377 | 370 | background-position: 0px -42px; |
| 378 | 371 | } |
| 379 | -.search-product-ecosol-percentage-icon-75 { | |
| 372 | +.search-product-ecosol-percentage-icon-75, | |
| 373 | +.search-product-ecosol-percentage-icon-100 { | |
| 380 | 374 | background-position: 0px -63px; |
| 381 | 375 | } |
| 382 | 376 | .search-product-price-details { |
| ... | ... | @@ -388,18 +382,23 @@ li.search-product-item { |
| 388 | 382 | .controller-search #category-comments { |
| 389 | 383 | margin-left: 55%; |
| 390 | 384 | } |
| 391 | -.controller-search #content .search-results-comments ul, .controller-search #content .search-results-comments li, .controller-search #content #category-comments ul, .controller-search #content #category-comments li { | |
| 385 | +.controller-search #content .search-results-comments ul, | |
| 386 | +.controller-search #content .search-results-comments li, | |
| 387 | +.controller-search #content #category-comments ul, | |
| 388 | +.controller-search #content #category-comments li { | |
| 392 | 389 | margin: 0px; |
| 393 | 390 | padding: 0px; |
| 394 | 391 | list-style: none; |
| 395 | 392 | color: #888; |
| 396 | 393 | } |
| 397 | -.controller-search .search-results-comments .comment-picture, .controller-search #category-comments .comment-picture { | |
| 394 | +.controller-search .search-results-comments .comment-picture, | |
| 395 | +.controller-search #category-comments .comment-picture { | |
| 398 | 396 | width: 20px; |
| 399 | 397 | height: 20px; |
| 400 | 398 | margin: -2px 5px 0px 0px; |
| 401 | 399 | } |
| 402 | -.controller-search #content .search-results-type-product ul, .controller-search #content .search-results-type-product li { | |
| 400 | +.controller-search #content .search-results-type-product ul, | |
| 401 | +.controller-search #content .search-results-type-product li { | |
| 403 | 402 | margin: 0px; |
| 404 | 403 | padding: 0px; |
| 405 | 404 | list-style: none; |
| ... | ... | @@ -572,7 +571,9 @@ li.search-product-item hr { |
| 572 | 571 | border: none; |
| 573 | 572 | background: none; |
| 574 | 573 | } |
| 575 | -.search-product-item-first-column, .search-product-item-second-column, .search-product-item-third-column { | |
| 574 | +.search-product-item-first-column, | |
| 575 | +.search-product-item-second-column, | |
| 576 | +.search-product-item-third-column { | |
| 576 | 577 | float: left; |
| 577 | 578 | margin:0 !important; |
| 578 | 579 | } |
| ... | ... | @@ -600,7 +601,6 @@ li.search-product-item hr { |
| 600 | 601 | } |
| 601 | 602 | .only-one-result-box .common-profile-list-block { |
| 602 | 603 | float: left; |
| 603 | - margin: 10px; | |
| 604 | 604 | } |
| 605 | 605 | .search-enterprise-item { |
| 606 | 606 | border-bottom: 1px solid #ccc; |
| ... | ... | @@ -760,30 +760,41 @@ form .search-field input:hover.button.submit { |
| 760 | 760 | background-repeat: no-repeat; |
| 761 | 761 | padding: 0 0 0 20px; |
| 762 | 762 | } |
| 763 | -.facet-menu a.facet-options-toggle.facet-more-options, .facet-menu a.facet-options-toggle { | |
| 763 | +.facet-menu a.facet-options-toggle.facet-more-options, | |
| 764 | +.facet-menu a.facet-options-toggle { | |
| 764 | 765 | background-position: 0 0; |
| 765 | 766 | } |
| 766 | 767 | .facet-menu a.facet-options-toggle.facet-less-options { |
| 767 | 768 | background-position: 0 -32px; |
| 768 | 769 | } |
| 769 | 770 | |
| 770 | -.search-uploaded-file-first-column, | |
| 771 | -.search-text-article-first-column, | |
| 772 | 771 | .search-content-first-column { |
| 773 | - clear: both; | |
| 774 | - float: left; | |
| 775 | - margin: 0 10px 0 0; | |
| 776 | 772 | width: 130px; |
| 777 | - min-height:98px; | |
| 773 | + min-height: 98px; | |
| 774 | + position: absolute; | |
| 778 | 775 | } |
| 779 | -.search-uploaded-file-second-column, | |
| 780 | -.search-text-article-second-column, | |
| 781 | 776 | .search-content-second-column { |
| 782 | - float: left; | |
| 783 | - width: 570px; | |
| 777 | + margin-left: 140px; | |
| 778 | + width: auto; | |
| 779 | +} | |
| 780 | +.search-content-second-column tr:hover { | |
| 781 | + background-color: none; | |
| 782 | +} | |
| 783 | +.search-content-second-column td { | |
| 784 | + height: auto; | |
| 785 | +} | |
| 786 | +.search-results-articles li { | |
| 787 | + position: relative; | |
| 788 | +} | |
| 789 | + | |
| 790 | +a.search-blog-sample-item.icon, | |
| 791 | +.search-folder-items a, | |
| 792 | +.search-forum-items a, | |
| 793 | +.search-blog-items a { | |
| 794 | + border: none; | |
| 795 | + margin-bottom: 3px; | |
| 796 | + display: block; | |
| 784 | 797 | } |
| 785 | -ul.clean-list .search-uploaded-file-second-column, | |
| 786 | -ul.clean-list .search-text-article-second-column, | |
| 787 | 798 | ul.clean-list .search-content-second-column { |
| 788 | 799 | width:795px; |
| 789 | 800 | } |
| ... | ... | @@ -864,10 +875,7 @@ a.search-image-pic { |
| 864 | 875 | } |
| 865 | 876 | .search-content-first-column .icon-application-vnd-oasis-opendocument-text, |
| 866 | 877 | .search-content-first-column .icon-application-vnd-oasis-opendocument-spreadsheet, |
| 867 | -.search-content-first-column .icon-text-content, | |
| 868 | -.search-uploaded-file-first-column .icon-application-vnd-oasis-opendocument-text, | |
| 869 | -.search-uploaded-file-first-column .icon-application-vnd-oasis-opendocument-spreadsheet, | |
| 870 | -.search-text-article-first-column .icon-text-content { | |
| 878 | +.search-content-first-column .icon-text-content { | |
| 871 | 879 | display:block; |
| 872 | 880 | width: 16px; |
| 873 | 881 | height: 16px; |
| ... | ... | @@ -879,18 +887,6 @@ a.search-image-pic { |
| 879 | 887 | margin: auto; |
| 880 | 888 | |
| 881 | 889 | } |
| 882 | -.search-content-first-column .icon-application-vnd-oasis-opendocument-spreadsheet, | |
| 883 | -.search-content-first-column .icon-application-vnd-oasis-opendocument-spreadsheet { | |
| 884 | - | |
| 885 | -} | |
| 886 | -.search-content-first-column .icon-application-opendocument-spreadsheet, | |
| 887 | -.search-uploaded-file-first-column .icon-application-opendocument-spreadsheet { | |
| 888 | - | |
| 889 | -} | |
| 890 | -.search-content-first-column .icon-text-content, | |
| 891 | -.search-text-article-first-column .icon-text-content { | |
| 892 | - | |
| 893 | -} | |
| 894 | 890 | .search-uploaded-file-line { |
| 895 | 891 | clear: both; |
| 896 | 892 | float: left; |
| ... | ... | @@ -904,7 +900,6 @@ a.search-image-pic { |
| 904 | 900 | width: 130px; |
| 905 | 901 | height: 130px; |
| 906 | 902 | display: block; |
| 907 | - | |
| 908 | 903 | } |
| 909 | 904 | #search-input { |
| 910 | 905 | font-size: 140%; |
| ... | ... | @@ -933,7 +928,8 @@ a.search-image-pic { |
| 933 | 928 | font-style: italic; |
| 934 | 929 | color: gray; |
| 935 | 930 | } |
| 936 | -.search-relevance, .search-result-text { | |
| 931 | +.search-relevance, | |
| 932 | +.search-result-text { | |
| 937 | 933 | margin-left: 40px; |
| 938 | 934 | } |
| 939 | 935 | ... | ... |