From 13a3e7cbd5d9cf55a47381f71925bdeb3b96738c Mon Sep 17 00:00:00 2001 From: AntonioTerceiro Date: Sat, 1 Dec 2007 18:36:20 +0000 Subject: [PATCH] ActionItem25: providing a nice-looking and extensible search engine --- app/controllers/public/search_controller.rb | 40 ++++++++++++++++++++++++++++++++++++++-- app/helpers/search_helper.rb | 8 ++++++++ app/models/article.rb | 2 ++ app/models/profile.rb | 2 +- app/views/search/_article.rhtml | 10 ++++++++++ app/views/search/_profile.rhtml | 9 +++++++++ app/views/search/index.rhtml | 10 ++++++---- config/ferret_server.yml | 8 -------- lib/acts_as_searchable.rb | 7 +++++++ public/designs/icons/default/README | 1 + public/designs/icons/default/style.css | 1 + public/designs/icons/default/user_icon.png | Bin 0 -> 851 bytes public/stylesheets/search.css | 5 +++++ 13 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 app/views/search/_article.rhtml create mode 100644 app/views/search/_profile.rhtml create mode 100644 lib/acts_as_searchable.rb create mode 100644 public/designs/icons/default/user_icon.png create mode 100644 public/stylesheets/search.css diff --git a/app/controllers/public/search_controller.rb b/app/controllers/public/search_controller.rb index a1f27fd..3425ff5 100644 --- a/app/controllers/public/search_controller.rb +++ b/app/controllers/public/search_controller.rb @@ -1,7 +1,43 @@ class SearchController < ApplicationController + + SEARCHES = [] + + def self.search(&block) + SEARCHES << block + end + + protected + + ############################################# + # XXX add yours searches here + ############################################# + + search do |query| + Article.find_tagged_with(query) + end + + search do |query| + Article.find_by_contents(query) + end + + search do |query| + Profile.find_by_contents(query) + end + + # auxiliary method to search in all defined searches and collect the results + def search(query) + SEARCHES.inject([]) do |acc,finder| + acc += finder.call(query) + end.sort_by do |hit| + (hit.respond_to? :ferret_score) ? (1.0 - hit.ferret_score) : (-1.0) + end + end + + public + def index @query = params[:query] || '' - # TODO: uncomment find_by_contents when ferret start working - @results = Article.find_tagged_with(@query) + Article.find_all_by_title(@query) + Profile.find_all_by_name(@query) + @results = search(@query) end + end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index b3ce20a..26e7dc4 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -1,2 +1,10 @@ module SearchHelper + def partial_for_hit(klass) + name = klass.name.underscore + if File.exists?(File.join(RAILS_ROOT, 'app', 'views', 'search', "_#{name}.rhtml")) + name + else + partial_for_hit(klass.superclass) + end + end end diff --git a/app/models/article.rb b/app/models/article.rb index 65eb58a..39e4105 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -14,6 +14,8 @@ class Article < ActiveRecord::Base acts_as_versioned + acts_as_searchable :fields => [ :name, :abstract, :body ] + # retrieves all articles belonging to the given +profile+ that are not # sub-articles of any other article. def self.top_level_for(profile) diff --git a/app/models/profile.rb b/app/models/profile.rb index 73da1f6..f067173 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -15,7 +15,7 @@ class Profile < ActiveRecord::Base acts_as_design - acts_as_ferret :fields => [ :name ] + acts_as_searchable :fields => [ :name, :identifier ] # Valid identifiers must match this format. IDENTIFIER_FORMAT = /^[a-z][a-z0-9_]*[a-z0-9]$/ diff --git a/app/views/search/_article.rhtml b/app/views/search/_article.rhtml new file mode 100644 index 0000000..13b4a0a --- /dev/null +++ b/app/views/search/_article.rhtml @@ -0,0 +1,10 @@ +
+ + <%= design_display_icon('cms') %> + <%= link_to_document(hit) %> + +
+
+ <%= hit.abstract %> +
+ diff --git a/app/views/search/_profile.rhtml b/app/views/search/_profile.rhtml new file mode 100644 index 0000000..9e9345b --- /dev/null +++ b/app/views/search/_profile.rhtml @@ -0,0 +1,9 @@ +<%# FIXME add photo if available %> +<%# FIXME add more information %> + +
+ + <%= design_display_icon('person') %> + <%= link_to_homepage(hit.name, hit.identifier) %> + +
diff --git a/app/views/search/index.rhtml b/app/views/search/index.rhtml index 9b87747..4688582 100644 --- a/app/views/search/index.rhtml +++ b/app/views/search/index.rhtml @@ -1,8 +1,10 @@

<%= _('Listing articles found') %>

<%= _('Searching for ') + @query %>

-<% @results.each do |a| %> -

<%= link_to_document(a) if a.kind_of?(Article) %>

-

<%= link_to_homepage(a.name, a.identifier) if a.kind_of?(Profile) %>

- +<% @results.each do |hit| %> + <%= render :partial => partial_for_hit(hit.class), :locals => { :hit => hit } %> +
+ <%= _('Relevance: %d%%') % (hit.respond_to?(:ferret_score) ? (hit.ferret_score * 100.0).round : 100) %> +
+
<% end %> diff --git a/config/ferret_server.yml b/config/ferret_server.yml index 6522f12..bc9aa0c 100644 --- a/config/ferret_server.yml +++ b/config/ferret_server.yml @@ -1,12 +1,4 @@ production: - host: ferret.yourdomain.com - port: 9010 - pid_file: log/ferret.pid -development: host: localhost port: 9010 pid_file: log/ferret.pid -test: - host: localhost - port: 9009 - pid_file: log/ferret.pid diff --git a/lib/acts_as_searchable.rb b/lib/acts_as_searchable.rb new file mode 100644 index 0000000..d448aae --- /dev/null +++ b/lib/acts_as_searchable.rb @@ -0,0 +1,7 @@ +class << ActiveRecord::Base + + def acts_as_searchable(options = {}, ferret_options = {}) + acts_as_ferret({ :remote => true }.merge(options), ferret_options) + end + +end diff --git a/public/designs/icons/default/README b/public/designs/icons/default/README index 92f5955..26b53ee 100644 --- a/public/designs/icons/default/README +++ b/public/designs/icons/default/README @@ -15,6 +15,7 @@ abiword_48.png dlg-neu apps/ gtk-save.png Nuovo stock/ gtk-go-up.png Nuovo stock/ gtk-cancel.png Nuovo stock/ +user_icon.png Nuovo apps/ Licensing of GNOME themes ========================= diff --git a/public/designs/icons/default/style.css b/public/designs/icons/default/style.css index 8dea028..beb1e18 100644 --- a/public/designs/icons/default/style.css +++ b/public/designs/icons/default/style.css @@ -7,3 +7,4 @@ .button.save { background-image: url(gtk-save.png); } .button.up { background-image: url(gtk-go-up.png); } .button.cancel { background-image: url(gtk-cancel.png); } +.button.person { background-image: url(user_icon.png); } diff --git a/public/designs/icons/default/user_icon.png b/public/designs/icons/default/user_icon.png new file mode 100644 index 0000000..1b60c08 Binary files /dev/null and b/public/designs/icons/default/user_icon.png differ diff --git a/public/stylesheets/search.css b/public/stylesheets/search.css new file mode 100644 index 0000000..8b5455c --- /dev/null +++ b/public/stylesheets/search.css @@ -0,0 +1,5 @@ +.search-relevance { + font-size: smaller; + font-style: italic; + color: gray; +} -- libgit2 0.21.2