require "inline_editable_metadata_helper"
require "block_helpers"
require "redcloth" # Provides textile parsing support for textile_area method
require 'deprecation'
module Hydra::HydraFedoraMetadataHelperBehavior
extend Deprecation
self.deprecation_horizon = 'hydra-head 5.x'
def fedora_text_field(resource, datastream_name, field_key, opts={})
field_name = field_name_for(field_key)
field_values = get_values_from_datastream(resource, datastream_name, field_key, opts)
field_values = [""] if field_values.empty?
field_values = [field_values.first] unless opts.fetch(:multiple, true)
required = opts.fetch(:required, true) ? "required" : ""
body = ""
field_values.each_with_index do |current_value, z|
base_id = generate_base_id(field_name, current_value, field_values, opts)
name = "asset[#{datastream_name}][#{field_name}][#{z}]"
body << ""
body << "Delete" if opts.fetch(:multiple, true) && !current_value.empty?
end
result = field_selectors_for(datastream_name, field_key)
result << body.html_safe
result
end
deprecation_deprecate :fedora_text_field
def fedora_text_area(resource, datastream_name, field_key, opts={})
fedora_textile_text_area(resource, datastream_name, field_key, opts)
end
deprecation_deprecate :fedora_text_area
# Textile textarea varies from the other methods in a few ways
# Since we're using jeditable with this instead of fluid, we need to provide slightly different hooks for the javascript
# * we are storing the datastream name in data-datastream-name so that we can construct a load url on the fly when initializing the textarea
def fedora_textile_text_area(resource, datastream_name, field_key, opts={})
field_name = field_name_for(field_key)
field_values = get_values_from_datastream(resource, datastream_name, field_key, opts)
field_values = [""] if field_values.empty?
if opts.fetch(:multiple, true)
container_tag_type = :li
else
field_values = [field_values.first]
container_tag_type = :span
end
required = opts.fetch(:required, true) ? "required" : ""
body = ""
field_values.each_with_index do |current_value, z|
base_id = generate_base_id(field_name, current_value, field_values, opts)
name = "asset[#{datastream_name}][#{field_name}][#{z}]"
processed_field_value = Sanitize.clean( RedCloth.new(current_value, [:sanitize_html]).to_html, Sanitize::Config::BASIC)
body << ""
body << "Delete" unless z == 0
end
result = field_selectors_for(datastream_name, field_key)
result << body.html_safe
result
end
deprecation_deprecate :fedora_textile_text_area
# Expects :choices option. Option tags for the select are generated from the :choices option using Rails "options_for_select":http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/options_for_select helper
# If no :choices option is provided, returns a regular fedora_text_field
def fedora_select(resource, datastream_name, field_key, opts={})
if opts[:choices].nil?
result = fedora_text_field(resource, datastream_name, field_key, opts)
else
choices = opts[:choices]
field_name = field_name_for(field_key)
field_values = get_values_from_datastream(resource, datastream_name, field_key, opts)
body = ""
z = 0
base_id = generate_base_id(field_name, field_values.first, field_values, opts.merge({:multiple=>false}))
name = "asset[#{datastream_name}][#{field_name}][#{z}]"
body << ""
result = field_selectors_for(datastream_name, field_key)
result << body.html_safe
end
result
end
deprecation_deprecate :fedora_select
def fedora_date_select(resource, datastream_name, field_key, opts={})
field_name = field_name_for(field_key)
field_values = get_values_from_datastream(resource, datastream_name, field_key, opts)
base_id = generate_base_id(field_name, field_values.first, field_values, opts.merge({:multiple=>false}))
name = "asset[#{datastream_name}][#{base_id}]"
value = field_values.first
field_value = value.nil? ? "" : value
field_value[/(\d+)-(\d+)-(\d+)/]
year = ($1.nil? or $1.empty?) ? "" : $1.to_i
month = ($2.nil? or $2.empty?) ? "-1" : $2
day = ($3.nil? or $3.empty?) ? "-1" : $3
# Make sure that month and day values are double-digit
[month, day].each {|v| v.length == 1 ? v.insert(0, "0") : nil }
year_options = Array.new(101) {|i| 1910+i}
# year_options = Array.new(4) {|i| 1990+i}
year_options.insert(0, ["Year", "-1"])
body = ""
body << "
"
body << ""
body << " / "
body << ""
body << "
"
body << <<-EOF
EOF
result = field_selectors_for(datastream_name, field_key)
result << body.html_safe
result
end
deprecation_deprecate :fedora_date_select
def fedora_submit(resource, datastream_name, field_key, opts={})
result = ""
h_name = OM::XML::Terminology.term_hierarchical_name(*field_key)
field_key.each do |pointer|
result << tag(:input, :type=>"submit", :name=>"field_selectors[#{datastream_name}][#{h_name}]", :value => field_key.to_s.capitalize)
end
return result.html_safe
end
deprecation_deprecate :fedora_submit
def fedora_checkbox(resource, datastream_name, field_key, opts={})
result = ""
field_values = get_values_from_datastream(resource, datastream_name, field_key, opts)
h_name = OM::XML::Terminology.term_hierarchical_name(*field_key)
v_name = field_key.last.to_s
checked = field_values.first.downcase == "yes" ? "checked" : ""
result = field_selectors_for(datastream_name, field_key)
# adding so that customized checked and unchecked values can be passed in
checked_value = (opts[:default_values] && opts[:default_values][:checked]) ? opts[:default_values][:checked] : "yes"
unchecked_value = (opts[:default_values] && opts[:default_values][:unchecked]) ? opts[:default_values][:unchecked] : "no"
result << tag(:input, :type=>"hidden", :id=>"#{h_name}_checked_value", :value=>checked_value )
result << tag(:input, :type=>"hidden", :id=>"#{h_name}_unchecked_value", :value=>unchecked_value )
if field_values.first.downcase == "yes"
result << tag(:input, :type=>"checkbox", :id=>h_name, :class=>"fedora-checkbox", :name=>"asset[#{datastream_name}][#{h_name}][0]", :value=>checked_value, :checked=>"checked")
else
result << tag(:input, :type=>"checkbox", :id=>h_name, :class=>"fedora-checkbox", :name=>"asset[#{datastream_name}][#{h_name}][0]", :value=>unchecked_value)
end
return result.html_safe
end
deprecation_deprecate :fedora_checkbox
# Expects :choices option.
# :choices should be a hash with value/label pairs
# :choices => {"first_choice"=>"Apple", "second_choice"=>"Pear" }
# If no :choices option is provided, returns a regular fedora_text_field
def fedora_radio_button(resource, datastream_name, field_key, opts={})
if opts[:choices].nil?
result = fedora_text_field(resource, datastream_name, field_key, opts)
else
choices = opts[:choices]
field_name = field_name_for(field_key)
field_values = get_values_from_datastream(resource, datastream_name, field_key, opts)
h_name = OM::XML::Terminology.term_hierarchical_name(*field_key)
default_value = opts.keys.include?(:default_value) ? opts[:default_value] : ""
selected_value = field_values.empty? ? "" : field_values.first
selected_value = default_value if selected_value.blank?
body = ""
z = 0
base_id = generate_base_id(field_name, field_values.first, field_values, opts.merge({:multiple=>false}))
name = "asset[#{datastream_name}][#{field_name}][#{z}]"
result = field_selectors_for(datastream_name, field_key)
choices.sort.each do |choice,label|
if choice == selected_value
result << tag(:input, :type=>"radio", :id=>"availability_#{choice}", :class=>"fedora-radio-button", :name=>"asset[#{datastream_name}][#{h_name}][0]", :value=>choice.downcase, :checked=>true)
else
result << tag(:input, :type=>"radio", :id=>"availability_#{choice}", :class=>"fedora-radio-button", :name=>"asset[#{datastream_name}][#{h_name}][0]", :value=>choice.downcase)
end
result << " "
end
result
end
return result.html_safe
end
deprecation_deprecate :fedora_radio_button
def fedora_text_field_insert_link(datastream_name, field_key, opts={})
field_name = field_name_for(field_key) || field_key
field_type = field_name == "person" ? "person" : "textfield"
link_text = "Add #{(opts[:label] || field_key.last || field_key).to_s.camelize.titlecase}"
result = "#{link_text}"
return result.html_safe
end
deprecation_deprecate :fedora_text_field_insert_link
def fedora_text_area_insert_link(datastream_name, field_key, opts={})
field_name = field_name_for(field_key)
link_text = "Add #{(opts[:label] || field_key.last || field_key).to_s.camelize.titlecase}"
result = "#{link_text}"
return result.html_safe
end
deprecation_deprecate :fedora_text_area_insert_link
def fedora_field_label(datastream_name, field_key, label=nil)
field_name = field_name_for(field_key)
if label.nil?
label = field_name
end
if params and params[:action] == "show"
return content_tag(:span, label).html_safe
else
return content_tag("label", label, :for=>field_name).html_safe
end
end
deprecation_deprecate :fedora_field_label
# Generate hidden inputs to handle mapping field names to server-side metadata mappings
# this allows us to round-trip OM metadata mappings
# also (importantly) allows us to avoid executing xpath queries from http requests.
# *Note*: It's important that you serialize these inputs in order from top to bottom (standard HTML form behavior)
def field_selectors_for(datastream_name, field_key)
result = ""
if field_key.kind_of?(Array)
h_name = OM::XML::Terminology.term_hierarchical_name(*field_key)
field_key.each do |pointer|
if pointer.kind_of?(Hash)
k = pointer.keys.first
v = pointer.values.first
result << tag(:input, :type=>"hidden", :class=>"fieldselector", :name=>"field_selectors[#{datastream_name}][#{h_name}][][#{k}]", :value=>v)
else
result << tag(:input, :type=>"hidden", :class=>"fieldselector", :name=>"field_selectors[#{datastream_name}][#{h_name}][]", :value=>pointer.to_s)
end
end
end
result.html_safe
end
deprecation_deprecate :field_selectors_for
# hydra_form_for block helper
# allows you to construct an entire hydra form by passing a block into this method
class HydraFormFor < BlockHelpers::Base
extend Deprecation
def initialize(resource, opts={})
Deprecation.warn self.class.name, "HydraFormFor is deprecated and will be removed from hydra-head 5.x"
@resource = resource
end
def fedora_label(datastream_name, field_key, opts={})
helper.fedora_label(@resource, datastream_name, field_key, opts)
end
deprecation_deprecate :fedora_label
def fedora_text_field(datastream_name, field_key, opts={})
helper.fedora_label(@resource, datastream_name, field_key, opts)
end
deprecation_deprecate :fedora_text_field
def fedora_text_area(datastream_name, field_key, opts={})
helper.fedora_text_area(@resource, datastream_name, field_key, opts)
end
deprecation_deprecate :fedora_text_area
def fedora_select(datastream_name, field_key, opts={})
helper.fedora_select(@resource, datastream_name, field_key, opts)
end
deprecation_deprecate :fedora_select
def fedora_submit(datastream_name, field_key, opts={})
helper.fedora_submit(@resource, datastream_name, field_key, opts)
end
deprecation_deprecate :fedora_submit
def fedora_checkbox(datastream_name, field_key, opts={})
helper.fedora_checkbox(@resource, datastream_name, field_key, opts)
end
deprecation_deprecate :fedora_checkbox
def fedora_radio_button(datastream_name, field_key, opts={})
helper.fedora_radio_button(@resource, datastream_name, field_key, opts)
end
deprecation_deprecate :fedora_radio_button
def fedora_text_field_insert_link(datastream_name, field_key, opts={})
helper.fedora_text_field_insert_link(@resource, datastream_name, field_key, opts={})
end
deprecation_deprecate :fedora_text_field_insert_link
def fedora_field_label(datastream_name, field_key, opts={})
helper.fedora_field_label(@resource, datastream_name, field_key, opts)
end
deprecation_deprecate :fedora_field_label
def display(body)
inner_html = content_tag :input, :type=>"hidden", :name=>"content_type", :value=>@resource.class.to_s.underscore
inner_html = inner_html << body
content_tag :form, inner_html
end
deprecation_deprecate :display
end
#
# Internal helper methods
#
protected
# retrieve field values from datastream.
# If :values is provided, skips accessing the datastream and returns the contents of :values instead.
def get_values_from_datastream(resource, datastream_name, field_key, opts={})
if opts.has_key?(:values)
values = opts[:values]
if values.nil? then values = [opts.fetch(:default, "")] end
else
values = resource.get_values_from_datastream(datastream_name, field_key, opts.fetch(:default, ""))
if values.empty? then values = [ opts.fetch(:default, "") ] end
end
return values
end
#deprecation_deprecate :get_values_from_datastream
def field_name_for(field_key)
if field_key.kind_of?(Array)
return OM::XML::Terminology.term_hierarchical_name(*field_key)
else
field_key.to_s
end
end
#deprecation_deprecate :field_name_for
def generate_base_id(field_name, current_value, values, opts)
if opts.fetch(:multiple, true)
return field_name+"_"+values.index(current_value).to_s
else
return field_name
end
end
#deprecation_deprecate :generate_base_id
end