Module: SearchHelper

Defined in:
app/helpers/search_helper.rb

Overview

Markup generators for the search controller

Instance Method Summary (collapse)

Instance Method Details

- (String) document_bibliography_entry(doc)

Get the short, formatted representation of a document

This function returns the short bibliographic entry for a document that will appear in the search results list. The formatting here depends on the current user's settings. By default, we use a jQuery Mobile-formatted partial with an H3 and some P's. The user can set, however, to format the bibliographic entries using their favorite CSL style.

Examples:

Get the entry for a given document

document_bibliography_entry(Document.new(:authors => 'W. Johnson', :year => '2000'))
# "Johnson, W. 2000. ..."

Parameters:

  • doc (Document)

    document for which bibliographic entry is desired

Returns:

  • (String)

    bibliographic entry for document



276
277
278
279
280
281
282
# File 'app/helpers/search_helper.rb', line 276

def document_bibliography_entry(doc)
  if user_signed_in? && current_user.csl_style
    return doc.to_csl_entry(current_user.csl_style)
  end
  
  render :partial => 'document', :locals => { :document => doc }
end

Create a link to the given set of facets

This function converts an array of facets to a link (generated via link_to) to the search page for that filtered query. All parameters other than :fq are simply duplicated (including the search query itself, :q).

Examples:

Get a “remove all facets” link

facet_link("Remove all facets", [])
# => link_to "Remove all facets", search_path

Get a link to a given set of facets

facet_link("Some facets", [...])
# => link_to "Some facets", search_path({ :fq => [ ... ] })

Parameters:

  • text (String)

    body of the link

  • facets (Array<Solr::Facet>)

    array of facets, possibly empty

Returns:

  • (String)

    link to search for the given set of facets



165
166
167
168
169
170
171
172
173
174
175
176
# File 'app/helpers/search_helper.rb', line 165

def facet_link(text, facets)
  new_params = params.dup

  if facets.empty?
    new_params[:fq] = nil
    return link_to text, search_path(new_params), 'data-transition' => 'none'
  end

  new_params[:fq] = []
  facets.each { |f| new_params[:fq] << f.query }
  link_to text, search_path(new_params), 'data-transition' => 'none'
end

Return a set of list items for faceted browsing

This function queries both the active facets on the current search and the available facets for authors, journals, and years. It returns a set of <li> elements (not a <ul>), including list dividers.

Examples:

Get all of the links for faceted browsing

facet_link_list
# "<li>Active Filters</li>...<li>Authors</li><li><a href='...'>Johnson</a></li>..."

Returns:

  • (String)

    set of list items for faceted browsing



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'app/helpers/search_helper.rb', line 227

def facet_link_list
  # Make sure there are facets
  return ''.html_safe unless Document.facets
  
  # Convert the active facet queries to facets
  active_facets = []
  if params[:fq]
    params[:fq].each do |query|
      active_facets << Document.facets.for_query(query)
    end
    active_facets.compact!
  end

  # Start with the active facets
  ret = ''.html_safe
  unless active_facets.empty?
    ret << (:li, I18n.t('search.index.active_filters'), 'data-role' => 'list-divider')
    ret << (:li, 'data-icon' => 'delete') do
      facet_link I18n.t('search.index.remove_all'), []
    end
    active_facets.each do |f|
      ret << (:li, 'data-icon' => 'delete') do
        facet_link "#{f.field_label}: #{f.label}", active_facets.reject { |x| x == f }
      end
    end
  end

  # Run the facet-list code for all three facet fields
  ret << list_links_for_facet(:authors_facet, I18n.t('search.index.authors_facet'), active_facets)
  ret << list_links_for_facet(:journal_facet, I18n.t('search.index.journal_facet'), active_facets)
  ret << list_links_for_facet(:year, I18n.t('search.index.year_facet'), active_facets)
  ret
end

Get the list of facet links for one particular field

This function takes the facets from the Document class, checks them against active_facets, and creates a set of list items. It is used by facet_link_list.

Examples:

Get the links for the authors facet

list_links_for_facet(:authors_facet, "Authors", [...])
# "<li><a href='...'>Johnson <span class='ui-li-count'>2</a></li>..."

Parameters:

  • field (Symbol)

    field we're faceting on

  • header (String)

    content of list item header

  • active_facets (Array<Solr::Facet>)

    array of active facets

Returns:

  • (String)

    list items for links for the given facet



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'app/helpers/search_helper.rb', line 192

def list_links_for_facet(field, header, active_facets)
  return ''.html_safe unless Document.facets
  
  # Get the facets for this field
  facets = Document.facets.sorted_for_field(field).reject { |f| active_facets.include? f }.take(5)

  # Bail if there's no facets
  ret = ''.html_safe
  return ret if facets.empty?

  # Build the return value
  ret << (:li, header, 'data-role' => 'list-divider')
  facets.each do |f|
    ret << (:li) do
      # Link to whatever the current facets are, plus the new one
      link = facet_link f.label, active_facets + [f]
      count =  :span, f.hits.to_s, :class => 'ui-li-count'
      link + count
    end
  end

  ret
end

- (String) num_results_string

Return a formatted version of the number of documents in the last search

Examples:

Print the number of documents in the last search (in HAML)

= num_results_string

Returns:

  • (String)

    number of documents in the last search



12
13
14
15
16
17
18
# File 'app/helpers/search_helper.rb', line 12

def num_results_string
  if params[:precise] or params[:q] or params[:fq]
    I18n.t 'search.index.num_results_found', :count => Document.num_results
  else
    I18n.t 'search.index.num_results_database', :count => Document.num_results
  end
end

Make a link to a page for the pagination widget

Examples:

Get a link to the 3rd page of results, with an arrow icon on the right

page_link('Page 3!', 2, 'arrow-r', true)

Parameters:

  • text (String)

    text for this link

  • num (Integer)

    the page number (0-based)

  • icon (String) (defaults to: '')

    icon for the button, if desired

  • right (Boolean) (defaults to: false)

    if true, put icon on the right side of the button

Returns:

  • (String)

    the requested link



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'app/helpers/search_helper.rb', line 31

def page_link(text, num, icon = '', right = false)
  new_params = params.dup
  if num == 0
    new_params.delete :page
  else
    new_params[:page] = num
  end

  style = { 'data-transition' => :none, 'data-role' => :button }
  style['data-icon'] = icon unless icon.empty?
  style['data-iconpos'] = 'right' if right

  link_to text, search_path(new_params), style
end

- (String) render_pagination

Render the pagination links

We currently render four buttons, in a 4x1 grid: first, previous, next, and last. Pagination is difficult for an application like this; we don't want infinite scroll, as there are far too many items, but full pagination (like that on Google or Flickr) really doesn't work on mobile devices. So this is a compromise.

Examples:

Put the current pagination links in a paragraph element

<p><%= render_pagination %></p>

Returns:

  • (String)

    full set of pagination links for the current page



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'app/helpers/search_helper.rb', line 58

def render_pagination
  num_pages = Document.num_results.to_f / @per_page.to_f
  num_pages = Integer(num_pages.ceil)
  return '' if num_pages == 0

   :div, :class => 'ui-grid-c' do
    content = (:div, :class => 'ui-block-a') do
      if @page != 0
        page_link(I18n.t(:search.index.first_button'), 0, 'back')
      end
    end
    content << (:div, :class => 'ui-block-b') do
      if @page != 0
        page_link(I18n.t(:search.index.previous_button'), @page - 1, 'arrow-l')
      end
    end

    content << (:div, :class => 'ui-block-c') do
      if @page != (num_pages - 1)
        page_link(I18n.t(:search.index.next_button'), @page + 1, 'arrow-r', true)
      end
    end
    content << (:div, :class => 'ui-block-d') do
      if @page != (num_pages - 1)
        page_link(I18n.t(:search.index.last_button'), num_pages - 1, 'forward', true)
      end
    end

    content
  end
end

- (Array<String>) sort_methods

Return an array of all sort methods

Examples:

Create links to all the sort methods

<%= sort_methods.each do |s| %>
  <%= link_to ... %>

Returns:

  • (Array<String>)

    all possible sorting strings



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'app/helpers/search_helper.rb', line 98

def sort_methods
  [
    'score desc',
    'authors_sort asc',
    'authors_sort desc',
    'title_sort asc',
    'title_sort desc',
    'journal_sort asc',
    'journal_sort desc',
    'year_sort asc',
    'year_sort desc'
  ]
end

- (String) sort_to_string(sort)

Get the given sort method as a string

This function converts a sort method ('relevance', 'title', 'author', 'journal', 'year') and sort direction ('asc' or 'desc') into a user-friendly string.

Examples:

Get the user-friendly version of 'score desc'

sort_to_string 'score desc'
# => 'Sort: Relevance'

Parameters:

  • sort (String)

    sorting string

Returns:

  • (String)

    user-friendly representation of sort method



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'app/helpers/search_helper.rb', line 124

def sort_to_string(sort)
  parts = sort.split(' ')
  return I18n.t('search.index.sort_unknown') unless parts.count == 2
  
  method = parts[0]    
  dir = I18n.t("search.index.sort_#{parts[1]}")
  
  method_spec = case method
  when 'score'
    I18n.t('search.index.sort_score')
  when 'title_sort'
    "#{Document.human_attribute_name('title')} #{dir}"
  when 'authors_sort'
    "#{Document.human_attribute_name('authors')} #{dir}"
  when 'journal_sort'
    "#{Document.human_attribute_name('journal')} #{dir}"
  when 'year_sort'
    "#{Document.human_attribute_name('year')} #{dir}"
  end
  
  "#{I18n.t('search.index.sort_prefix')} #{method_spec}"
end