Module: Blacklight::HierarchyHelper

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

Instance Method Summary collapse

Instance Method Details

#facet_after(prefix, order) ⇒ Object



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

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

#facet_order(prefix) ⇒ Object



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

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



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 120

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'
  )

  # For Rails 5.2 support all options must be symbols.  See https://github.com/rails/rails/issues/39813
  tag.button(:'aria-expanded' => 'false',
              :'aria-label' => aria_label,
              :'aria-describedby' => described_by,
              class: 'toggle-handle') do
    tag.span(Blacklight::Hierarchy::Engine.config.closed_icon, :'aria-hidden' => 'true', class: 'closed') +
    tag.span(Blacklight::Hierarchy::Engine.config.opened_icon, :'aria-hidden' => 'true', class: 'opened')
  end
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'], ':']
     }
    

    }



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 96

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)


159
160
161
162
163
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 159

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)


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

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



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

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 qfacet_selected?(field_name, item)
          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



194
195
196
197
198
199
200
201
202
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 194

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



43
44
45
46
47
48
49
50
51
52
53
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 43

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



56
57
58
59
60
61
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 56

def render_qfacet_value(facet_solr_field, item, options = {})
  id = options.delete(:id)
  facet_config = facet_configuration_for_field(facet_solr_field)
  path_for_facet = facet_item_presenter(facet_config, item.qvalue, facet_solr_field).href
  (link_to_unless(options[:suppress_link], item.value, path_for_facet, 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.



65
66
67
68
69
70
71
72
73
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 65

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



178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 178

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



168
169
170
171
172
173
174
# File 'app/helpers/blacklight/hierarchy_helper.rb', line 168

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