app/helpers/blacklight/hierarchy_helper.rb in blacklight-hierarchy-0.0.3 vs app/helpers/blacklight/hierarchy_helper.rb in blacklight-hierarchy-0.1.0
- old
+ new
@@ -1,135 +1,172 @@
module Blacklight::HierarchyHelper
-def is_hierarchical?(field_name)
- (prefix,order,suffix) = field_name.split(/_/)
- list = blacklight_config.facet_display[:hierarchy][prefix] and list.include?(order)
-end
-
-def facet_order(prefix)
- param_name = "#{prefix}_facet_order".to_sym
- params[param_name] || blacklight_config.facet_display[:hierarchy][prefix].first
-end
+ # 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
+ def render_facet_hierarchy_item(field_name, data, key)
+ item = data[:_]
+ subset = data.reject { |k,v| ! k.is_a?(String) }
-def facet_after(prefix, order)
- orders = blacklight_config.facet_display[:hierarchy][prefix]
- orders[orders.index(order)+1] || orders.first
-end
+ li_class = subset.empty? ? 'h-leaf' : 'h-node'
+ li = ul = ''
+
+ if item.nil?
+ li = key
+ elsif facet_in_params?(field_name, item.qvalue)
+ li = render_selected_qfacet_value(field_name, item)
+ else
+ li = render_qfacet_value(field_name, item)
+ end
+
+ unless subset.empty?
+ subul = subset.keys.sort.collect do |subkey|
+ render_facet_hierarchy_item(field_name, subset[subkey], subkey)
+ end.join('')
+ ul = "<ul>#{subul}</ul>".html_safe
+ end
+
+ %{<li class="#{li_class}">#{li.html_safe}#{ul.html_safe}</li>}.html_safe
+ end
-def hide_facet?(field_name)
- if is_hierarchical?(field_name)
- prefix = field_name.split(/_/).first
- field_name != "#{prefix}_#{facet_order(prefix)}_facet"
- else
- false
+ # TODO: remove baked in notion of underscores being part of the blacklight facet field names,
+ # and of _facet being the suffix of the Solr field name seems to be baked in.
+ #
+ # @param [Blacklight::Configuration::FacetField] as defined in controller with config.add_facet_field (and with :partial => 'blacklight/hierarchy/facet_hierarchy')
+ # @return [String] html for the facet tree
+ def render_hierarchy(bl_facet_field)
+ field_name = bl_facet_field.field
+ prefix = field_name.gsub("_#{field_name.split(/_/).last}", '')
+ tree = facet_tree(prefix)[field_name]
+ if tree
+ result = tree.keys.sort.collect do |key|
+ render_facet_hierarchy_item(field_name, tree[key], key)
+ end.join("\n").html_safe
+ else
+ ""
+ end
end
-end
-def rotate_facet_value(val, from, to)
- components = Hash[from.split(//).zip(val.split(/:/))]
- new_values = components.values_at(*(to.split(//)))
- while new_values.last.nil?
- new_values.pop
+ def render_qfacet_value(facet_solr_field, item, options ={})
+ (link_to_unless(options[:suppress_link], item.value, add_facet_params(facet_solr_field, item.qvalue), :class=>"facet_select") + " " + render_facet_count(item.hits)).html_safe
end
- if new_values.include?(nil)
- nil
- else
- new_values.compact.join(':')
+
+ # Standard display of a SELECTED facet value, no link, special span
+ # with class, and 'remove' button.
+ def render_selected_qfacet_value(facet_solr_field, item)
+ content_tag(:span, render_qfacet_value(facet_solr_field, item, :suppress_link => true), :class => "selected") + " " +
+ link_to(content_tag(:span, '', :class => "glyphicon glyphicon-remove") + content_tag(:span, '[remove]', :class => 'sr-only'), remove_facet_params(facet_solr_field, item.qvalue, params), :class=>"remove")
end
-end
-def rotate_facet_params(prefix, from, to, p=params.dup)
- return p if from == to
- from_field = "#{prefix}_#{from}_facet"
- to_field = "#{prefix}_#{to}_facet"
- 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
+ HierarchicalFacetItem = Struct.new :qvalue, :value, :hits
+
+ # @param [String] hkey - a key to access the rest of the hierarchy tree, as defined in controller config.facet_display[:hierarchy] declaration.
+ # e.g. if you had this in controller:
+ # config.facet_display = {
+ # :hierarchy => {
+ # 'wf' => [['wps','wsp','swp'], ':'],
+ # 'callnum' => [['top_facet'], '/']
+ # }
+ # }
+ # then possible hkey values would be 'wf' and 'callnum'
+ def facet_tree(hkey)
+ @facet_tree ||= {}
+ if blacklight_config.facet_display[:hierarchy] && blacklight_config.facet_display[:hierarchy][hkey]
+ value_delim = blacklight_config.facet_display[:hierarchy][hkey].last
+ split_regex = Regexp.new("\s*#{Regexp.escape(value_delim)}\s*")
+ if @facet_tree[hkey].nil?
+ @facet_tree[hkey] = {}
+ blacklight_config.facet_display[:hierarchy][hkey].first.each { |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.facet_by_field_name(facet_field)
+ next if data.nil?
-def render_facet_rotate(field_name)
- if is_hierarchical?(field_name)
- (prefix,order,suffix) = field_name.split(/_/)
- 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'
+ data.items.each { |facet_item|
+ path = facet_item.value.split(split_regex)
+ loc = @facet_tree[hkey][facet_field]
+ while path.length > 0
+ loc = loc[path.shift] ||= {}
+ end
+ loc[:_] = HierarchicalFacetItem.new(facet_item.value, facet_item.value.split(split_regex).last, facet_item.hits)
+ }
+ }
+ end
+ end
+ @facet_tree[hkey]
end
-end
-# 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
-def render_facet_hierarchy_item(field_name, data, key)
- item = data[:_]
- subset = data.reject { |k,v| ! k.is_a?(String) }
+# --------------------------------------------------------------------------------------------------------------------------------
+# below are methods pertaining to the "rotate" notion where you may want to look at the same tree data organized another way
+# --------------------------------------------------------------------------------------------------------------------------------
- li_class = subset.empty? ? 'h-leaf' : 'h-node'
- li = ul = ''
-
- if item.nil?
- li = key
- elsif facet_in_params?(field_name, item.qvalue)
- li = render_selected_qfacet_value(field_name, item)
- else
- li = render_qfacet_value(field_name, item)
+ # FIXME: remove baked in underscore separator in field name
+ def is_hierarchical?(field_name)
+ (prefix,order) = field_name.split(/_/, 2)
+ list = blacklight_config.facet_display[:hierarchy][prefix] and list.include?(order)
end
-
- unless subset.empty?
- subul = subset.keys.sort.collect do |subkey|
- render_facet_hierarchy_item(field_name, subset[subkey], subkey)
- end.join('')
- ul = "<ul>#{subul}</ul>".html_safe
+
+ def facet_order(prefix)
+ param_name = "#{prefix}_facet_order".to_sym
+ params[param_name] || blacklight_config.facet_display[:hierarchy][prefix].first
end
-
- %{<li class="#{li_class}">#{li.html_safe}#{ul.html_safe}</li>}.html_safe
-end
-def render_hierarchy(field)
- prefix = field.field.split(/_/).first
- tree = facet_tree(prefix)[field.field]
- tree.keys.sort.collect do |key|
- render_facet_hierarchy_item(field.field, tree[key], key)
- end.join("\n").html_safe
-end
+ def facet_after(prefix, order)
+ orders = blacklight_config.facet_display[:hierarchy][prefix]
+ orders[orders.index(order)+1] || orders.first
+ end
-def render_qfacet_value(facet_solr_field, item, options ={})
- (link_to_unless(options[:suppress_link], item.value, add_facet_params(facet_solr_field, item.qvalue), :class=>"facet_select label") + " " + render_facet_count(item.hits)).html_safe
-end
+ # FIXME: remove baked in underscore separator in field name
+ def hide_facet?(field_name)
+ if is_hierarchical?(field_name)
+ prefix = field_name.split(/_/).first
+ field_name != "#{prefix}_#{facet_order(prefix)}"
+ else
+ false
+ end
+ end
+
+ # FIXME: remove baked in colon separator
+ def rotate_facet_value(val, from, to)
+ components = Hash[from.split(//).zip(val.split(/:/))]
+ new_values = components.values_at(*(to.split(//)))
+ while new_values.last.nil?
+ new_values.pop
+ end
+ if new_values.include?(nil)
+ nil
+ else
+ new_values.compact.join(':')
+ end
+ end
-# Standard display of a SELECTED facet value, no link, special span
-# with class, and 'remove' button.
-def render_selected_qfacet_value(facet_solr_field, item)
- content_tag(:span, render_qfacet_value(facet_solr_field, item, :suppress_link => true), :class => "selected label") +
- link_to("[remove]", remove_facet_params(facet_solr_field, item.qvalue, params), :class=>"remove")
+ # FIXME: remove baked in underscore separator in field name
+ 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
-HierarchicalFacetItem = Struct.new :qvalue, :value, :hits
-def facet_tree(prefix)
- @facet_tree ||= {}
- if @facet_tree[prefix].nil?
- @facet_tree[prefix] = {}
- blacklight_config.facet_display[:hierarchy][prefix].each { |key|
- facet_field = [prefix,key,'facet'].compact.join('_')
- @facet_tree[prefix][facet_field] ||= {}
- data = @response.facet_by_field_name(facet_field)
- next if data.nil?
+ # FIXME: remove baked in underscore separator in field name
+ def render_facet_rotate(field_name)
+ if is_hierarchical?(field_name)
+ (prefix,order) = field_name.split(/_/, 2)
- data.items.each { |facet_item|
- path = facet_item.value.split(/\s*:\s*/)
- loc = @facet_tree[prefix][facet_field]
- while path.length > 0
- loc = loc[path.shift] ||= {}
- end
- loc[:_] = HierarchicalFacetItem.new(facet_item.value, facet_item.value.split(/\s*:\s*/).last, facet_item.hits)
- }
- }
+ 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
end
- @facet_tree[prefix]
-end
end