Module: Blacklight::HierarchyHelper

Defined in:
app/helpers/blacklight/hierarchy_helper.rb

Defined Under Namespace

Classes: HierarchicalFacetItem

Instance Method Summary collapse

Instance Method Details

#facet_after(prefix, order) ⇒ Object



140
141
142
143
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 140

def facet_after(prefix, order)
  orders = blacklight_config.facet_display[:hierarchy][prefix]
  orders[orders.index(order) + 1] || orders.first
end

#facet_order(prefix) ⇒ Object



135
136
137
138
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 135

def facet_order(prefix)
  param_name = "#{prefix}_facet_order".to_sym
  params[param_name] || blacklight_config.facet_display[:hierarchy][prefix].first
end

#facet_toggle_button(field_name, described_by) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 107

def facet_toggle_button(field_name, described_by)
  aria_label = I18n.t(
    "blacklight.hierarchy.#{field_name}_toggle_aria_label",
    default: :'blacklight.hierarchy.toggle_aria_label'
  )
  <<-HTML
    <button
      aria-expanded="false"
      aria-label="#{aria_label}"
      aria-describedby="#{described_by}"
      class="toggle-handle"
    >
      <span aria-hidden="true" class="closed">#{Blacklight::Hierarchy::Engine.config.closed_icon}</span>
      <span aria-hidden="true" class="opened">#{Blacklight::Hierarchy::Engine.config.opened_icon}</span>
    </button>
  HTML
end

#facet_tree(hkey) ⇒ Object

then possible hkey values would be ‘wf’, ‘callnum_top’, and ‘exploded_tag’.

the key in the :hierarchy hash is the “prefix” for the solr field with the hierarchy info. the value

in the hash is a list, where the first element is a list of suffixes, and the second element is the delimiter
used to break up the sections of hierarchical data in the solr field being read.  when joined, the prefix and
suffix should form the field name.  so, for example, 'wf_wps', 'wf_wsp', 'wf_swp', 'callnum_top_facet', and
'exploded_tag_ssim' would be the solr fields with blacklight-hierarchy related configuration according to the
hash above.  ':' would be the delimiter used in all of those fields except for 'callnum_top_facet', which would
use '/'.  exploded_tag_ssim might contain values like ['Book', 'Book : Multi-Volume Work'], and callnum_top_facet
might contain values like ['LB', 'LB/2395', 'LB/2395/.C65', 'LB/2395/.C65/1991'].

note: the suffixes (e.g. ‘ssim’ for ‘exploded_tag’ in the above example) can’t have underscores, otherwise things break.

Parameters:

  • hkey (String)
    • a key to access the rest of the hierarchy tree, as defined in controller config.facet_display declaration.

    e.g. if you had this in controller:

    config.facet_display = {
      :hierarchy => {
        'wf' => [['wps','wsp','swp'], ':'],
        'callnum_top' => [['facet'], '/'],
        'exploded_tag' => [['ssim'], ':']
     }
    

    }



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 84

def facet_tree(hkey)
  @facet_tree ||= {}
  return @facet_tree[hkey] unless @facet_tree[hkey].nil?
  return @facet_tree[hkey] unless blacklight_config.facet_display[:hierarchy] && blacklight_config.facet_display[:hierarchy][hkey]
  @facet_tree[hkey] = {}
  facet_config = blacklight_config.facet_display[:hierarchy][hkey]
  split_regex = Regexp.new("\s*#{Regexp.escape(facet_config.length >= 2 ? facet_config[1] : ':')}\s*")
  facet_config.first.each do |key|
    # TODO: remove baked in notion of underscores being part of the blacklight facet field names
    facet_field = [hkey, key].compact.join('_')
    @facet_tree[hkey][facet_field] ||= {}
    data = @response.aggregations[facet_field]
    next if data.nil?
    data.items.each do |facet_item|
      path = facet_item.value.split(split_regex)
      loc = @facet_tree[hkey][facet_field]
      loc = loc[path.shift] ||= {} while path.length > 0
      loc[:_] = HierarchicalFacetItem.new(facet_item.value, facet_item.value.split(split_regex).last, facet_item.hits)
    end
  end
  @facet_tree[hkey]
end

#hide_facet?(field_name) ⇒ Boolean

FIXME: remove baked in underscore separator in field name

Returns:

  • (Boolean)


146
147
148
149
150
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 146

def hide_facet?(field_name)
  return false unless is_hierarchical?(field_name)
  prefix = field_name.split(/_/).first
  field_name != "#{prefix}_#{facet_order(prefix)}"
end

#is_hierarchical?(field_name) ⇒ Boolean

FIXME: remove baked in underscore separator in field name

Returns:

  • (Boolean)


130
131
132
133
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 130

def is_hierarchical?(field_name)
  (prefix, order) = field_name.split(/_/, 2)
  (list = blacklight_config.facet_display[:hierarchy][prefix]) && list.include?(order)
end

#render_facet_hierarchy_item(field_name, data, key) ⇒ Object

Putting bare HTML strings in a helper sucks. But in this case, with a lot of recursive tree-walking going on, it’s an order of magnitude faster than either render(:partial) or content_tag



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 5

def render_facet_hierarchy_item(field_name, data, key)
  item = data[:_]
  subset = data.reject { |k, _v| !k.is_a?(String) }

  li_class = subset.empty? ? 'h-leaf' : 'h-node'
  id = SecureRandom.uuid
  ul = ''
  li = ''
  li << facet_toggle_button(field_name, id) if subset.any?
  li << if item.nil?
          key
        elsif facet_in_params?(field_name, item.qvalue)
          render_selected_qfacet_value(field_name, item)
        else
          render_qfacet_value(field_name, item, id: id)
        end

  unless subset.empty?
    subul = subset.keys.sort.collect do |subkey|
      render_facet_hierarchy_item(field_name, subset[subkey], subkey)
    end.join('')
    ul = "<ul role=\"group\">#{subul}</ul>".html_safe
  end

  %(<li class="#{li_class}" role="treeitem">#{li.html_safe}#{ul.html_safe}</li>).html_safe
end

#render_facet_rotate(field_name) ⇒ Object

FIXME: remove baked in underscore separator in field name



177
178
179
180
181
182
183
184
185
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 177

def render_facet_rotate(field_name)
  return unless is_hierarchical?(field_name)
  (prefix, order) = field_name.split(/_/, 2)
  return if blacklight_config.facet_display[:hierarchy][prefix].length < 2
  new_order = facet_after(prefix, order)
  new_params = rotate_facet_params(prefix, order, new_order)
  new_params["#{prefix}_facet_order"] = new_order
  link_to image_tag('icons/rotate.png', title: new_order.upcase).html_safe, new_params, class: 'no-underline'
end

#render_hierarchy(bl_facet_field, delim = '_') ⇒ String

Returns html for the facet tree.

Parameters:

  • as (Blacklight::Configuration::FacetField)

    defined in controller with config.add_facet_field (and with :partial => ‘blacklight/hierarchy/facet_hierarchy’)

Returns:

  • (String)

    html for the facet tree



34
35
36
37
38
39
40
41
42
43
44
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 34

def render_hierarchy(bl_facet_field, delim = '_')
  field_name = bl_facet_field.field
  prefix = field_name.gsub("#{delim}#{field_name.split(/#{delim}/).last}", '')
  facet_tree_for_prefix = facet_tree(prefix)
  tree = facet_tree_for_prefix ? facet_tree_for_prefix[field_name] : nil

  return '' unless tree
  tree.keys.sort.collect do |key|
    render_facet_hierarchy_item(field_name, tree[key], key)
  end.join("\n").html_safe
end

#render_qfacet_value(facet_solr_field, item, options = {}) ⇒ Object



46
47
48
49
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 46

def render_qfacet_value(facet_solr_field, item, options = {})
  id = options.delete(:id)
  (link_to_unless(options[:suppress_link], item.value, path_for_facet(facet_solr_field, item.qvalue), id: id, class: 'facet_select') + ' ' + render_facet_count(item.hits)).html_safe
end

#render_selected_qfacet_value(facet_solr_field, item) ⇒ Object

Standard display of a SELECTED facet value, no link, special span with class, and ‘remove’ button.



52
53
54
55
56
57
58
59
60
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 52

def render_selected_qfacet_value(facet_solr_field, item)
  remove_href = search_action_path(search_state.remove_facet_params(facet_solr_field, item.qvalue))
  (:span, render_qfacet_value(facet_solr_field, item, suppress_link: true), class: 'selected') + ' ' +
    link_to((:span, '', class: 'glyphicon glyphicon-remove') +
            (:span, '[remove]', class: 'sr-only'),
            remove_href,
            class: 'remove'
           )
end

#rotate_facet_params(prefix, from, to, p = params.dup) ⇒ Object

FIXME: remove baked in underscore separator in field name



162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 162

def rotate_facet_params(prefix, from, to, p = params.dup)
  return p if from == to
  from_field = "#{prefix}_#{from}"
  to_field = "#{prefix}_#{to}"
  p[:f] = (p[:f] || {}).dup # the command above is not deep in rails3, !@#$!@#$
  p[:f][from_field] = (p[:f][from_field] || []).dup
  p[:f][to_field] = (p[:f][to_field] || []).dup
  p[:f][from_field].reject! { |v| p[:f][to_field] << rotate_facet_value(v, from, to); true }
  p[:f].delete(from_field)
  p[:f][to_field].compact!
  p[:f].delete(to_field) if p[:f][to_field].empty?
  p
end

#rotate_facet_value(val, from, to) ⇒ Object

FIXME: remove baked in colon separator



153
154
155
156
157
158
159
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 153

def rotate_facet_value(val, from, to)
  components = Hash[from.split(//).zip(val.split(/:/))]
  new_values = components.values_at(*to.split(//))
  new_values.pop while new_values.last.nil?
  return nil if new_values.include?(nil)
  new_values.compact.join(':')
end