- <% if !@empty_query %>
- <%= facets_menu(:articles, @facets) %>
- <% end %>
-
-
-
- <%= render :partial => 'search_form', :locals => { :hint => _('Type the title, author or content desired') } %>
- <%= render :partial => 'results_header' %>
-
- <%= display_results %>
- <%= pagination_links @results[:articles] %>
-
-
-
- <% if logged_in? %>
- <% button_bar do %>
- <%# FIXME shouldn't the user create the community in the current environment instead of going to its home environment? %>
- <%= button(:add, __('New community'), user.url.merge(:controller => 'memberships', :action => 'new_community', :profile => user.identifier)) %>
- <% end %>
- <% end %>
-
- <% if !@empty_query %>
- <%= facets_menu(:communities, @facets) %>
- <% end %>
-
-
-
- <%= render :partial => 'search_form', :locals => { :hint => _("Type words about the community you're looking for") } %>
- <%= render :partial => 'results_header' %>
-
- <%= display_results %>
- <%= pagination_links @results.values.first %>
-
-
-
- <% if logged_in? && environment.enabled?('enterprise_registration') %>
- <% button_bar do %>
- <%= button(:add, __('New enterprise'), {:controller => 'enterprise_registration'}) %>
- <% end %>
- <% end %>
-
- <% if !@empty_query %>
- <% button_bar do %>
- <%= display_map_list_button %>
- <% end %>
- <%= facets_menu(:enterprises, @facets) %>
- <% end %>
-
-
-
- <%= render :partial => 'search_form', :locals => { :hint => _("Type words about the enterprise you're looking for") } %>
- <%= render :partial => 'results_header' %>
-
- <%= display_results(true) %>
- <% if params[:display] != 'map' %>
- <%= pagination_links @results[:enterprises] %>
- <% end %>
-
-
-
<% if @category %>
diff --git a/app/views/search/people.rhtml b/app/views/search/people.rhtml
deleted file mode 100644
index adb29fd..0000000
--- a/app/views/search/people.rhtml
+++ /dev/null
@@ -1,19 +0,0 @@
-<%= search_page_title( @titles[:people], @category ) %>
-
-
- <% if !@empty_query %>
- <%= facets_menu(:people, @facets) %>
- <% end %>
-
-
-
- <%= render :partial => 'search_form', :locals => { :hint => _("Type words about the person you're looking for") } %>
- <%= render :partial => 'results_header' %>
-
- <%= display_results %>
- <% if params[:display] != 'map' %>
- <%= pagination_links @results.values.first %>
- <% end %>
-
-
-
diff --git a/app/views/search/products.rhtml b/app/views/search/products.rhtml
deleted file mode 100644
index 74e8f02..0000000
--- a/app/views/search/products.rhtml
+++ /dev/null
@@ -1,26 +0,0 @@
-<%= search_page_title( @titles[:products], @category ) %>
-
-
- <% if !@empty_query %>
- <% button_bar do %>
- <%= display_map_list_button %>
-<% end %>
- <%= facets_menu(:products, @facets) %>
-<% end %>
-
-
-
- <%= render :partial => 'search_form', :locals => { :hint => _('Type the product, service, city or qualifier desired') } %>
- <%= render :partial => 'results_header' %>
-
- <%= display_results(true) %>
- <% if !@one_page and params[:display] != 'map' %>
- <%= pagination_links @results[:products] %>
-<% end %>
-
-
-<% javascript_tag do %>
- jQuery('.search-product-price-details').altBeautify();
-<% end %>
-
-
diff --git a/app/views/search/search_page.html.erb b/app/views/search/search_page.html.erb
new file mode 100644
index 0000000..463ad7d
--- /dev/null
+++ b/app/views/search/search_page.html.erb
@@ -0,0 +1,16 @@
+<%= search_page_title( @titles[@asset], @category ) %>
+
+<%= render :partial => 'results_header' %>
+
+<%= display_results(@asset) %>
+<% if params[:display] != 'map' %>
+ <%= pagination_links @results[@asset] %>
+<% end %>
+
+
+
+<% if @asset == :product %>
+ <% javascript_tag do %>
+ jQuery('.search-product-price-details').altBeautify();
+ <% end %>
+<% end %>
diff --git a/lib/noosfero/plugin.rb b/lib/noosfero/plugin.rb
index e374a5d..666686b 100644
--- a/lib/noosfero/plugin.rb
+++ b/lib/noosfero/plugin.rb
@@ -351,6 +351,17 @@ class Noosfero::Plugin
nil
end
+ # -> Specifies plugin that works as a search engine
+ # returns = true/false
+ def search_engine?
+ false
+ end
+
+ # -> Realizes a full text search
+ # returns = whatever the plugin needs to render the view
+ def full_text_search(asset, query, category, paginate_options)
+ end
+
def method_missing(method, *args, &block)
# This is a generic hotspot for all controllers on Noosfero.
# If any plugin wants to define filters to run on any controller, the name of
diff --git a/plugins/solr/dependencies.rb b/plugins/solr/dependencies.rb
new file mode 100644
index 0000000..e52c70f
--- /dev/null
+++ b/plugins/solr/dependencies.rb
@@ -0,0 +1,3 @@
+require 'active_record'
+require 'acts_as_searchable'
+require 'acts_as_faceted'
diff --git a/plugins/solr/lib/solr_plugin.rb b/plugins/solr/lib/solr_plugin.rb
index c32fc1f..d760d27 100644
--- a/plugins/solr/lib/solr_plugin.rb
+++ b/plugins/solr/lib/solr_plugin.rb
@@ -1,5 +1,9 @@
+require_dependency 'solr_plugin/search_helper'
+
class SolrPlugin < Noosfero::Plugin
+ include SolrPlugin::SearchHelper
+
def self.plugin_name
"Solr"
end
@@ -8,6 +12,16 @@ class SolrPlugin < Noosfero::Plugin
_("Uses Solr as search engine.")
end
+ def search_engine?
+ true
+ end
+
+ def full_text_search(asset, query, category, paginate_options)
+ asset_class = asset_class(asset)
+ solr_options = solr_options(asset, category)
+ asset_class.find_by_contents(query, paginate_options, solr_options)
+ end
+
end
Dir[File.join(SolrPlugin.root_path, 'lib', 'ext', '*.rb')].each {|file| require_dependency file }
diff --git a/plugins/solr/lib/solr_plugin/results_helper.rb b/plugins/solr/lib/solr_plugin/results_helper.rb
new file mode 100644
index 0000000..2311394
--- /dev/null
+++ b/plugins/solr/lib/solr_plugin/results_helper.rb
@@ -0,0 +1,113 @@
+class SolrPlugin < Noosfero::Plugin
+ module ResultsHelper
+ def set_results_variables
+ if @results[@asset].kind_of?(Hash)
+ ret = @results[@asset]
+ @results[@asset] = ret[:results]
+ @facets = ret[:facets]
+ @all_facets = ret[:all_facets]
+ end
+ end
+
+ def order_by(asset)
+ options = SolrPlugin::SortOptions[asset].map do |name, options|
+ next if options[:if] && !instance_eval(&options[:if])
+ [_(options[:label]), name.to_s]
+ end.compact
+
+ content_tag('div', _('Sort results by ') +
+ select_tag(asset.to_s + '[order]', options_for_select(options, params[:order_by] || 'none'),
+ {:onchange => "window.location = jQuery.param.querystring(window.location.href, { 'order_by' : this.options[this.selectedIndex].value})"}
+ ),
+ :class => "search-ordering"
+ )
+ end
+
+ def label_total_found(asset, total_found)
+ labels = {
+ :products => _("%s products offers found"),
+ :articles => _("%s articles found"),
+ :events => _("%s events found"),
+ :people => _("%s people found"),
+ :enterprises => _("%s enterprises found"),
+ :communities => _("%s communities found"),
+ }
+ content_tag('span', labels[asset] % total_found,
+ :class => "total-pages-found") if labels[asset]
+ end
+
+ def facets_menu(asset, _facets)
+ @asset_class = asset_class(asset)
+ @facets = _facets
+ render(:partial => 'facets_menu')
+ end
+
+ def facets_unselect_menu(asset)
+ @asset_class = asset_class(asset)
+ render(:partial => 'facets_unselect_menu')
+ end
+
+ def facet_selecteds_html_for(environment, klass, params)
+ def name_with_extra(klass, facet, value)
+ name = klass.facet_result_name(facet, value)
+ name = name[0] + name[1] if name.kind_of?(Array)
+ name
+ end
+
+ ret = []
+ params = params.dup
+ params[:facet].each do |id, value|
+ facet = klass.facet_by_id(id.to_sym)
+ next unless facet
+ if value.kind_of?(Hash)
+ label_hash = facet[:label].call(environment)
+ value.each do |label_id, value|
+ facet[:label_id] = label_id
+ facet[:label] = label_hash[label_id]
+ value.to_a.each do |value|
+ ret << [facet[:label], name_with_extra(klass, facet, value),
+ params.merge(:facet => params[:facet].merge(id => params[:facet][id].merge(label_id => params[:facet][id][label_id].to_a.reject{ |v| v == value })))]
+ end
+ end
+ else
+ ret << [klass.facet_label(facet), name_with_extra(klass, facet, value),
+ params.merge(:facet => params[:facet].reject{ |k,v| k == id })]
+ end
+ end
+
+ ret.map do |label, name, url|
+ content_tag('div', content_tag('span', label, :class => 'facet-selected-label') +
+ content_tag('span', name, :class => 'facet-selected-name') +
+ link_to('', url, :class => 'facet-selected-remove', :title => 'remove facet'), :class => 'facet-selected')
+ end.join
+ end
+
+ def facet_link_html(facet, params, value, label, count)
+ params = params ? params.dup : {}
+ has_extra = label.kind_of?(Array)
+ link_label = has_extra ? label[0] : label
+ id = facet[:solr_field].to_s
+ params[:facet] ||= {}
+ params[:facet][id] ||= {}
+ params[:page] = {} if params[:page]
+
+ selected = facet[:label_id].nil? ? params[:facet][id] == value : params[:facet][id][facet[:label_id]].to_a.include?(value)
+
+ if count > 0
+ url = params.merge(:facet => params[:facet].merge(
+ id => facet[:label_id].nil? ? value : params[:facet][id].merge( facet[:label_id] => params[:facet][id][facet[:label_id]].to_a | [value] )
+ ))
+ else
+ # preserve others filters and change this filter
+ url = params.merge(:facet => params[:facet].merge(
+ id => facet[:label_id].nil? ? value : { facet[:label_id] => value }
+ ))
+ end
+
+ content_tag 'div', link_to(link_label, url, :class => 'facet-result-link-label') +
+ content_tag('span', (has_extra ? label[1] : ''), :class => 'facet-result-extra-label') +
+ (count > 0 ? content_tag('span', " (#{count})", :class => 'facet-result-count') : ''),
+ :class => 'facet-menu-item' + (selected ? ' facet-result-link-selected' : '')
+ end
+ end
+end
diff --git a/plugins/solr/lib/solr_plugin/search_helper.rb b/plugins/solr/lib/solr_plugin/search_helper.rb
new file mode 100644
index 0000000..0d0dac9
--- /dev/null
+++ b/plugins/solr/lib/solr_plugin/search_helper.rb
@@ -0,0 +1,83 @@
+class SolrPlugin < Noosfero::Plugin
+
+ SortOptions = {
+ :products => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
+ :more_recent, {:label => _('More recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}},
+ :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}},
+ :closest, {:label => _('Closest to me'), :if => proc{ logged_in? && (profile=current_user.person).lat && profile.lng },
+ :solr_opts => {:sort => "geodist() asc",
+ :latitude => proc{ current_user.person.lat }, :longitude => proc{ current_user.person.lng }}},
+ ],
+ :events => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
+ :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}},
+ ],
+ :articles => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
+ :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}},
+ :more_recent, {:label => _('More recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}},
+ ],
+ :enterprises => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
+ :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}},
+ ],
+ :people => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
+ :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}},
+ ],
+ :communities => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')},
+ :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}},
+ ],
+ }
+
+ module SearchHelper
+ def asset_class(asset)
+ asset.to_s.singularize.camelize.constantize
+ end
+
+ def asset_table(asset)
+ asset_class(asset).table_name
+ end
+
+ def multiple_search?
+ ['index', 'category_index'].include?(context.params[:action])
+ end
+
+ def filters(asset)
+ case asset
+ when :products
+ ['solr_plugin_public:true']
+ when :events
+ []
+ else
+ ['solr_plugin_public:true']
+ end
+ end
+
+ def results_only?
+ context.params[:action] == 'index'
+ end
+
+ def solr_options(asset, category)
+ asset_class = asset_class(asset)
+ solr_options = {}
+ if !multiple_search?
+ if !results_only? and asset_class.respond_to? :facets
+ solr_options.merge! asset_class.facets_find_options(context.params[:facet])
+ solr_options[:all_facets] = true
+ end
+ solr_options[:filter_queries] ||= []
+ solr_options[:filter_queries] += filters(asset)
+ solr_options[:filter_queries] << "environment_id:#{context.environment.id}"
+ solr_options[:filter_queries] << asset_class.facet_category_query.call(category) if category
+
+ solr_options[:boost_functions] ||= []
+ context.params[:order_by] = nil if context.params[:order_by] == 'none'
+ if context.params[:order_by]
+ order = SolrPlugin::SortOptions[asset][context.params[:order_by].to_sym]
+ raise "Unknown order by" if order.nil?
+ order[:solr_opts].each do |opt, value|
+ solr_options[opt] = value.is_a?(Proc) ? instance_eval(&value) : value
+ end
+ end
+ end
+ solr_options
+ end
+ end
+end
diff --git a/plugins/solr/test/unit/article_test.rb b/plugins/solr/test/unit/article_test.rb
new file mode 100644
index 0000000..a749977
--- /dev/null
+++ b/plugins/solr/test/unit/article_test.rb
@@ -0,0 +1,115 @@
+require 'test_helper'
+
+class ArticleTest < ActiveSupport::TestCase
+ def setup
+ @environment = Environment.default
+ @environment.enable_plugin(SolrPlugin)
+ @profile = create_user('testing').person
+ end
+
+ attr_accessor :environment, :profile
+
+ should 'act as faceted' do
+ person = fast_create(Person)
+ cat = Category.create!(:name => 'hardcore', :environment_id => Environment.default.id)
+ a = Article.create!(:name => 'black flag review', :profile_id => person.id)
+ a.add_category(cat, true)
+ a.save!
+ assert_equal Article.type_name, Article.facet_by_id(:solr_plugin_f_type)[:proc].call(a.send(:solr_plugin_f_type))
+ assert_equal Person.type_name, Article.facet_by_id(:solr_plugin_f_profile_type)[:proc].call(a.send(:solr_plugin_f_profile_type))
+ assert_equal a.published_at, a.send(:solr_plugin_f_published_at)
+ assert_equal ['hardcore'], a.send(:solr_plugin_f_category)
+ assert_equal "solr_plugin_category_filter:\"#{cat.id}\"", Article.facet_category_query.call(cat)
+ end
+
+ should 'act as searchable' do
+ TestSolr.enable
+ person = fast_create(Person, :name => "Hiro", :address => 'U-Stor-It @ Inglewood, California',
+ :nickname => 'Protagonist')
+ person2 = fast_create(Person, :name => "Raven")
+ category = fast_create(Category, :name => "science fiction", :acronym => "sf", :abbreviation => "sci-fi")
+ a = Article.create!(:name => 'a searchable article about bananas', :profile_id => person.id,
+ :body => 'the body talks about mosquitos', :abstract => 'and the abstract is about beer',
+ :filename => 'not_a_virus.exe')
+ a.add_category(category)
+ c = a.comments.build(:title => 'snow crash', :author => person2, :body => 'wanna try some?')
+ c.save!
+
+ # fields
+ assert_includes Article.find_by_contents('bananas')[:results].docs, a
+ assert_includes Article.find_by_contents('mosquitos')[:results].docs, a
+ assert_includes Article.find_by_contents('beer')[:results].docs, a
+ assert_includes Article.find_by_contents('not_a_virus.exe')[:results].docs, a
+ # filters
+ assert_includes Article.find_by_contents('bananas', {}, {:filter_queries => ["solr_plugin_public:true"]})[:results].docs, a
+ assert_not_includes Article.find_by_contents('bananas', {}, {:filter_queries => ["solr_plugin_public:false"]})[:results].docs, a
+ assert_includes Article.find_by_contents('bananas', {}, {:filter_queries => ["environment_id:\"#{Environment.default.id}\""]})[:results].docs, a
+ assert_includes Article.find_by_contents('bananas', {}, {:filter_queries => ["profile_id:\"#{person.id}\""]})[:results].docs, a
+ # includes
+ assert_includes Article.find_by_contents('Hiro')[:results].docs, a
+ assert_includes Article.find_by_contents("person-#{person.id}")[:results].docs, a
+ assert_includes Article.find_by_contents("California")[:results].docs, a
+ assert_includes Article.find_by_contents("Protagonist")[:results].docs, a
+# FIXME: After merging with AI1826, searching on comments is not working
+# assert_includes Article.find_by_contents("snow")[:results].docs, a
+# assert_includes Article.find_by_contents("try some")[:results].docs, a
+# assert_includes Article.find_by_contents("Raven")[:results].docs, a
+#
+# FIXME: After merging with AI1826, searching on categories is not working
+# assert_includes Article.find_by_contents("science")[:results].docs, a
+# assert_includes Article.find_by_contents(category.slug)[:results].docs, a
+# assert_includes Article.find_by_contents("sf")[:results].docs, a
+# assert_includes Article.find_by_contents("sci-fi")[:results].docs, a
+ end
+
+ should 'boost name matches' do
+ TestSolr.enable
+ person = fast_create(Person)
+ in_body = Article.create!(:name => 'something', :profile_id => person.id, :body => 'bananas in the body!')
+ in_name = Article.create!(:name => 'bananas in the name!', :profile_id => person.id)
+ assert_equal [in_name, in_body], Article.find_by_contents('bananas')[:results].docs
+ end
+
+ should 'boost if profile is enabled' do
+ TestSolr.enable
+ person2 = fast_create(Person, :enabled => false)
+ art_profile_disabled = Article.create!(:name => 'profile disabled', :profile_id => person2.id)
+ person1 = fast_create(Person, :enabled => true)
+ art_profile_enabled = Article.create!(:name => 'profile enabled', :profile_id => person1.id)
+ assert_equal [art_profile_enabled, art_profile_disabled], Article.find_by_contents('profile')[:results].docs
+ end
+
+ should 'index comments body together with article' do
+ TestSolr.enable
+ owner = create_user('testuser').person
+ art = fast_create(TinyMceArticle, :profile_id => owner.id, :name => 'ytest')
+ c1 = Comment.create(:title => 'test comment', :body => 'anything', :author => owner, :source => art); c1.save!
+
+ assert_includes Article.find_by_contents('anything')[:results], art
+ end
+
+ should 'index by schema name when database is postgresql' do
+ TestSolr.enable
+ uses_postgresql 'schema_one'
+ art1 = Article.create!(:name => 'some thing', :profile_id => @profile.id)
+ assert_equal [art1], Article.find_by_contents('thing')[:results].docs
+ uses_postgresql 'schema_two'
+ art2 = Article.create!(:name => 'another thing', :profile_id => @profile.id)
+ assert_not_includes Article.find_by_contents('thing')[:results], art1
+ assert_includes Article.find_by_contents('thing')[:results], art2
+ uses_postgresql 'schema_one'
+ assert_includes Article.find_by_contents('thing')[:results], art1
+ assert_not_includes Article.find_by_contents('thing')[:results], art2
+ uses_sqlite
+ end
+
+ should 'not index by schema name when database is not postgresql' do
+ TestSolr.enable
+ uses_sqlite
+ art1 = Article.create!(:name => 'some thing', :profile_id => @profile.id)
+ assert_equal [art1], Article.find_by_contents('thing')[:results].docs
+ art2 = Article.create!(:name => 'another thing', :profile_id => @profile.id)
+ assert_includes Article.find_by_contents('thing')[:results], art1
+ assert_includes Article.find_by_contents('thing')[:results], art2
+ end
+end
diff --git a/plugins/solr/test/unit/environment_test.rb b/plugins/solr/test/unit/environment_test.rb
new file mode 100644
index 0000000..2fd3a22
--- /dev/null
+++ b/plugins/solr/test/unit/environment_test.rb
@@ -0,0 +1,29 @@
+require 'test_helper'
+
+class EnvironmentTest < ActiveSupport::TestCase
+ def setup
+ @environment = Environment.default
+ @environment.enable_plugin(SolrPlugin)
+ end
+
+ attr_accessor :environment
+
+ should 'find by contents from articles' do
+ TestSolr.enable
+ env = fast_create(Environment)
+ env.enable_plugin(SolrPlugin)
+ assert_nothing_raised do
+ env.articles.find_by_contents('')[:results]
+ end
+ end
+
+ should 'return more than 10 enterprises by contents' do
+ TestSolr.enable
+ Enterprise.destroy_all
+ ('1'..'20').each do |n|
+ Enterprise.create!(:name => 'test ' + n, :identifier => 'test_' + n)
+ end
+
+ assert_equal 20, environment.enterprises.find_by_contents('test')[:results].total_entries
+ end
+end
diff --git a/plugins/solr/test/unit/event_test.rb b/plugins/solr/test/unit/event_test.rb
new file mode 100644
index 0000000..1d401d1
--- /dev/null
+++ b/plugins/solr/test/unit/event_test.rb
@@ -0,0 +1,23 @@
+require 'test_helper'
+
+class EventTest < ActiveSupport::TestCase
+ def setup
+ @environment = Environment.default
+ @environment.enable_plugin(SolrPlugin)
+ @profile = create_user('testing').person
+ end
+
+ attr_accessor :environment, :profile
+
+ should 'be indexed by title' do
+ TestSolr.enable
+ e = Event.create!(:name => 'my surprisingly nice event', :start_date => Date.new(2008, 06, 06), :profile => profile)
+ assert_includes Event.find_by_contents('surprisingly')[:results], e
+ end
+
+ should 'be indexed by body' do
+ TestSolr.enable
+ e = Event.create!(:name => 'bli', :start_date => Date.new(2008, 06, 06), :profile => profile, :body => 'my surprisingly long description about my freaking nice event')
+ assert_includes Event.find_by_contents('surprisingly')[:results], e
+ end
+end
diff --git a/plugins/solr/test/unit/text_article_test.rb b/plugins/solr/test/unit/text_article_test.rb
new file mode 100644
index 0000000..7f570ae
--- /dev/null
+++ b/plugins/solr/test/unit/text_article_test.rb
@@ -0,0 +1,17 @@
+require 'test_helper'
+
+class TextArticleTest < ActiveSupport::TestCase
+ def setup
+ @environment = Environment.default
+ @environment.enable_plugin(SolrPlugin)
+ end
+
+ attr_accessor :environment
+
+ should 'found TextileArticle by TextArticle indexes' do
+ TestSolr.enable
+ person = create_user('testuser').person
+ article = TextileArticle.create!(:name => 'found article test', :profile => person)
+ assert_equal TextileArticle.find_by_contents('found')[:results].docs, TextArticle.find_by_contents('found')[:results].docs
+ end
+end
diff --git a/plugins/solr/test/unit/tiny_mce_article_test.rb b/plugins/solr/test/unit/tiny_mce_article_test.rb
new file mode 100644
index 0000000..b2d720b
--- /dev/null
+++ b/plugins/solr/test/unit/tiny_mce_article_test.rb
@@ -0,0 +1,18 @@
+require 'test_helper'
+
+class TinyMceArticleTest < ActiveSupport::TestCase
+ def setup
+ @environment = Environment.default
+ @environment.enable_plugin(SolrPlugin)
+ @profile = create_user('testing').person
+ end
+
+ attr_accessor :environment, :profile
+
+ should 'be found when searching for articles by query' do
+ TestSolr.enable
+ tma = TinyMceArticle.create!(:name => 'test tinymce article', :body => '---', :profile => profile)
+ assert_includes TinyMceArticle.find_by_contents('article')[:results], tma
+ assert_includes Article.find_by_contents('article')[:results], tma
+ end
+end
diff --git a/plugins/solr/views/search/.communities.rhtml.swp b/plugins/solr/views/search/.communities.rhtml.swp
new file mode 100644
index 0000000..ff23962
Binary files /dev/null and b/plugins/solr/views/search/.communities.rhtml.swp differ
diff --git a/plugins/solr/views/search/.people.rhtml.swp b/plugins/solr/views/search/.people.rhtml.swp
new file mode 100644
index 0000000..9add0ea
Binary files /dev/null and b/plugins/solr/views/search/.people.rhtml.swp differ
diff --git a/plugins/solr/views/search/_facets.html.erb b/plugins/solr/views/search/_facets.html.erb
new file mode 100644
index 0000000..de029e9
--- /dev/null
+++ b/plugins/solr/views/search/_facets.html.erb
@@ -0,0 +1,10 @@
+<% if logged_in? %>
+ <% button_bar do %>
+ <%# FIXME shouldn't the user create the community in the current environment instead of going to its home environment? %>
+ <%= button(:add, __('New community'), user.url.merge(:controller => 'memberships', :action => 'new_community', :profile => user.identifier)) if @asset == :communities %>
+ <%= button(:add, __('New enterprise'), {:controller => 'enterprise_registration'}) if @asset == :enterprises && environment.enabled?('enterprise_registration') %>
+ <% end %>
+<% end %>
+<% if !@empty_query %>
+ <%= facets_menu(@asset, @facets) %>
+<% end %>
diff --git a/plugins/solr/views/search/_facets_menu.html.erb b/plugins/solr/views/search/_facets_menu.html.erb
new file mode 100644
index 0000000..1893876
--- /dev/null
+++ b/plugins/solr/views/search/_facets_menu.html.erb
@@ -0,0 +1,36 @@
+<% less_options_limit = 8 %>
+
+
diff --git a/plugins/solr/views/search/_results.html.erb b/plugins/solr/views/search/_results.html.erb
new file mode 100644
index 0000000..cd97d3f
--- /dev/null
+++ b/plugins/solr/views/search/_results.html.erb
@@ -0,0 +1,7 @@
+<%= render :partial => 'search_form', :locals => { :hint => _("Type words about the %s you're looking for") % @asset.to_s.singularize } %>
+<%= render :partial => 'results_header' %>
+
+<%= display_results(@asset) %>
+<% if params[:display] != 'map' %>
+ <%= pagination_links @results[@asset] %>
+<% end %>
diff --git a/plugins/solr/views/search/_results_header.html.erb b/plugins/solr/views/search/_results_header.html.erb
new file mode 100644
index 0000000..9f1785b
--- /dev/null
+++ b/plugins/solr/views/search/_results_header.html.erb
@@ -0,0 +1,22 @@
+
diff --git a/plugins/solr/views/search/search_page.html.erb b/plugins/solr/views/search/search_page.html.erb
new file mode 100644
index 0000000..8ee945d
--- /dev/null
+++ b/plugins/solr/views/search/search_page.html.erb
@@ -0,0 +1,24 @@
+<% extend SolrPlugin::ResultsHelper %>
+<% set_results_variables %>
+
+<%= search_page_title( @titles[@asset], @category ) %>
+
+<% if !@empty_query %>
+
+ <%= render :partial => 'facets' %>
+
+
+
+ <%= render :partial => 'results' %>
+
+<% else %>
+ <%= render :partial => 'results' %>
+<% end %>
+
+
+
+<% if @asset == :products %>
+ <% javascript_tag do %>
+ jQuery('.search-product-price-details').altBeautify();
+ <% end %>
+<% end %>
diff --git a/public/stylesheets/search.css b/public/stylesheets/search.css
index b218b92..1c3a4f5 100644
--- a/public/stylesheets/search.css
+++ b/public/stylesheets/search.css
@@ -647,6 +647,7 @@ li.search-product-item hr {
font-weight: bold;
font-size: 130%;
line-height: 35px;
+ float: left;
}
.search-results-header.search-no-results {
border-bottom: 0px;
@@ -665,6 +666,9 @@ li.search-product-item hr {
color: #ff0000
}
+#search-display-filter {
+ margin-top: 20px;
+}
/* Search field and button */
--
libgit2 0.21.2