Class: ActionPresenter::Base
- Inherits:
-
Object
- Object
- ActionPresenter::Base
- Defined in:
- lib/action_presenter/base.rb,
lib/action_presenter/base/form.rb,
lib/action_presenter/base/html.rb,
lib/action_presenter/base/bootstrap.rb
Constant Summary collapse
- PRESENTER_CLASSES =
inheritance tracking
[]
- PRESENTER_ATTRIBUTES =
%i[ content record ]
- BOOTSTRAP_SIZES =
%w[ xs sm md lg ]
Instance Attribute Summary collapse
-
#form_builder ⇒ Object
Returns the value of attribute form_builder.
-
#record ⇒ Object
Returns the value of attribute record.
-
#view ⇒ Object
Returns the value of attribute view.
Class Method Summary collapse
- .define_extension(base_method, new_method, *extension_params) ⇒ Object
- .generate_bootstrap_presenter_methods! ⇒ Object
- .inherited(new_presenter_class) ⇒ Object
- .presenter_options ⇒ Object
Instance Method Summary collapse
- #button_tag(*hashes, &content_block) ⇒ Object
- #check_box(name, *hashes) ⇒ Object
- #check_box_tag(name, *hashes, &content_block) ⇒ Object
- #date_select(name, *hashes) ⇒ Object
- #datetime_select(name, *hashes) ⇒ Object
- #extract(key, *hashes) ⇒ Object
- #extract_content(*hashes, &content_block) ⇒ Object
- #extract_content_block(*hashes, &content_block) ⇒ Object
- #extract_html(*hashes) ⇒ Object
- #extract_query_params(*hashes) ⇒ Object
- #extract_record(*hashes) ⇒ Object
- #file_field_tag(name, *hashes, &content_block) ⇒ Object
- #form_for(*hashes, &content_block) ⇒ Object
- #form_tag(path, *hashes, &content_block) ⇒ Object
- #hidden_field(name, *hashes, &content_block) ⇒ Object
- #hidden_field_tag(name, *hashes, &content_block) ⇒ Object
- #html_tag(tag, *hashes, &content_block) ⇒ Object
- #image_tag(name, *hashes, &content_block) ⇒ Object
-
#initialize ⇒ Base
constructor
core methods.
- #inline_html_tag(tag, *hashes, &content_block) ⇒ Object
-
#label(name, *hashes, &content_block) ⇒ Object
form elements.
- #label_for(name, *hashes, &content_block) ⇒ Object
- #link_to(link, *hashes, &content_block) ⇒ Object
- #method_field(*hashes, &content_block) ⇒ Object
- #presenter_options ⇒ Object
- #radio_button(name, *hashes, &content_block) ⇒ Object
- #radio_button_tag(name, *hashes, &content_block) ⇒ Object
- #select(name, *hashes, &content_block) ⇒ Object
-
#select_tag(name, *hashes, &content_block) ⇒ Object
form elements.
- #set(options) ⇒ Object
- #submit_tag(*hashes, &content_block) ⇒ Object
- #text_area(name, *hashes, &content_block) ⇒ Object
- #text_area_tag(name, *hashes, &content_block) ⇒ Object
- #text_field(name, *hashes, &content_block) ⇒ Object
- #text_field_tag(name, *hashes, &content_block) ⇒ Object
Constructor Details
#initialize ⇒ Base
core methods
12 13 |
# File 'lib/action_presenter/base.rb', line 12 def initialize end |
Instance Attribute Details
#form_builder ⇒ Object
Returns the value of attribute form_builder.
3 4 5 |
# File 'lib/action_presenter/base/form.rb', line 3 def form_builder @form_builder end |
#record ⇒ Object
Returns the value of attribute record.
17 18 19 |
# File 'lib/action_presenter/base.rb', line 17 def record @record end |
#view ⇒ Object
Returns the value of attribute view.
17 18 19 |
# File 'lib/action_presenter/base.rb', line 17 def view @view end |
Class Method Details
.define_extension(base_method, new_method, *extension_params) ⇒ Object
117 118 119 120 121 |
# File 'lib/action_presenter/base.rb', line 117 def define_extension(base_method, new_method, *extension_params) define_method(new_method) do |*params, &content_block| send(base_method, *params, *extension_params.deep_dup, &content_block) end end |
.generate_bootstrap_presenter_methods! ⇒ Object
4 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 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 89 90 |
# File 'lib/action_presenter/base/bootstrap.rb', line 4 def self.generate_bootstrap_presenter_methods! ["", "offset"].each do |namespace| define_method("col_#{namespace}_class".squeeze("_")) do |*hashes, &content_block| classes = [] BOOTSTRAP_SIZES.each do |col_size| col_width = extract("col_#{col_size}", *hashes).to_i.nonzero? if col_width col_width += 1 if extract("#{col_size}_expand", *hashes) == true && col_width < 11 col_width -= 1 if extract("#{col_size}_compact", *hashes) == true && col_width > 2 raise ArgumentError, "col_width must be between 1 and 12" if !col_width.between?(1,12) # col-sm-3 classes << "col-#{col_size}-#{namespace}-#{col_width}".squeeze("-") end end [extract_html(*hashes)[:class], *classes].join(" ") end end define_method(:col_div) do |*hashes, &content_block| classes = [] BOOTSTRAP_SIZES.each do |col_size| col_width = extract("col_#{col_size}", *hashes).to_i.nonzero? col_offset_width = extract("col_#{col_size}_offset", *hashes).to_i.nonzero? if col_width col_width += 1 if extract("#{col_size}_expand", *hashes) == true && col_width < 11 col_width -= 1 if extract("#{col_size}_compact", *hashes) == true && col_width > 2 classes << col_class("col_#{col_size}" => col_width) end if col_offset_width col_offset_width += 1 if extract("#{col_size}_offset_expand", *hashes) == true && col_offset_width < 11 col_offset_width -= 1 if extract("#{col_size}_offset_compact", *hashes) == true && col_offset_width > 2 raise ArgumentError, "col_width must be between 1 and 12" if !col_offset_width.between?(1,12) classes << col_offset_class("col_#{col_size}" => col_offset_width) end end div_tag(*hashes, add_class: classes.join(" "), &content_block) end define_method(:check_box_div_label) do |*hashes, &content_block| content = extract_content(*hashes, &content_block) check_box_div(*hashes) { label_tag(content: content) } end define_method(:label_span) do |label, *hashes, &content_block| span_tag(*hashes, add_class: "label label-#{label}", &content_block) end define_method(:alert_div) do |alert, *hashes, &content_block| div_tag(*hashes, class: "alert alert-#{alert} alert-dismissible", role: "alert", &content_block) end define_method(:dismiss_button) do |target, *hashes, &content_block| (*hashes, "aria-label" => "Dismiss", data: { dismiss: target.to_s }, &content_block) end define_method(:dropdown_toggle_btn) do |*hashes, &content_block| btn = extract(:btn, *hashes, btn: "default") (*hashes, class: "btn btn-#{btn} dropdown-toggle", data: { toggle: "dropdown" }, &content_block) end define_method(:glyphicon) do |glyphicon, *hashes, &content_block| span_tag(*hashes, add_class: "glyphicon glyphicon-#{glyphicon}", &content_block) end # override core classes { core_label_class: -> { "control-label" }, core_select_class: -> { "form-control" }, core_field_class: -> { "form-control" }, core_text_area_class: -> { "form-control" }, }.each do |method, block| define_method(method, &block) end # div define_extension(:div_tag, :row_div, class: "row") define_extension(:div_tag, :form_group_div, class: "form-group") define_extension(:div_tag, :dropdown_div, class: "dropdown") define_extension(:div_tag, :check_box_div, class: "checkbox") # span define_extension(:span_tag, :caret_span, class: "caret") # ul define_extension(:ul_tag, :dropdown_menu_ul, class: "dropdown-menu", role: "menu") # label define_extension(:label_tag, :radio_label, class: "radio") define_extension(:label_tag, :check_box_label, class: "checkbox") end |
.inherited(new_presenter_class) ⇒ Object
6 7 8 9 |
# File 'lib/action_presenter/base.rb', line 6 def self.inherited(new_presenter_class) PRESENTER_CLASSES << new_presenter_class super end |
.presenter_options ⇒ Object
123 124 125 126 127 128 |
# File 'lib/action_presenter/base.rb', line 123 def @presenter_options ||= ActiveSupport::OrderedOptions.new.merge( verify_content: true, presents: name.underscore.remove(/_presenter\z/).singularize.to_sym, ) end |
Instance Method Details
#button_tag(*hashes, &content_block) ⇒ Object
33 34 35 36 |
# File 'lib/action_presenter/base/html.rb', line 33 def (*hashes, &content_block) default_html = { type: "button" } html_tag(:button, *hashes, default_html, &content_block) end |
#check_box(name, *hashes) ⇒ Object
76 77 78 79 80 81 |
# File 'lib/action_presenter/base/form.rb', line 76 def check_box(name, *hashes) default_html = { class: check_box_class } checked_value = extract(:checked_value, *hashes, checked_value: "true") unchecked_value = extract(:unchecked_value, *hashes, unchecked_value: "false") form_builder.check_box(name, extract_html(*hashes, default_html), checked_value, unchecked_value) end |
#check_box_tag(name, *hashes, &content_block) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/action_presenter/base/html.rb', line 92 def check_box_tag(name, *hashes, &content_block) default_html = { id: name.to_s.slugify_html, name: name, class: check_box_class } checked_value = extract_content(*hashes, content: "true").presence unchecked_value = extract(:unchecked_value, *hashes).presence checked = extract(:checked, *hashes, checked: view.params.to_unsafe_h.dig_html(name).presence == checked_value).present? check_box_html = extract_html(*hashes, default_html) content = "".html_safe if unchecked_value.present? content += view.check_box_tag(nil, unchecked_value, true, default_html.merge(id: nil, class: nil, style: "display: none;")) end content + view.check_box_tag(nil, checked_value, checked, check_box_html) end |
#date_select(name, *hashes) ⇒ Object
54 55 56 57 58 59 60 61 62 63 |
# File 'lib/action_presenter/base/form.rb', line 54 def date_select(name, *hashes) default_html = { class: date_select_class } hashes << { order: %i[ month day year ] } = {} %i[ include_blank prompt order default start_year end_year add_month_numbers use_short_month ].each { |key| [key] = extract(key, *hashes) } form_builder.date_select(name, .compact, extract_html(*hashes, default_html)) end |
#datetime_select(name, *hashes) ⇒ Object
65 66 67 68 69 70 71 72 73 74 |
# File 'lib/action_presenter/base/form.rb', line 65 def datetime_select(name, *hashes) default_html = { class: datetime_select_class } hashes << { order: %i[ month day year ], ampm: true } = {} %i[ include_blank prompt ampm order default start_year end_year ].each { |key| [key] = extract(key, *hashes) } form_builder.datetime_select(name, , extract_html(*hashes, class: datetime_select_class)) end |
#extract(key, *hashes) ⇒ Object
28 29 30 31 32 33 34 35 36 |
# File 'lib/action_presenter/base.rb', line 28 def extract(key, *hashes) hashes.compact.map do |hash| begin hash.delete(key.to_sym) || hash.delete(key.to_s) rescue StandardError => error raise ArgumentError, "#{error.class} while trying to extract key #{key.inspect} from #{hash.inspect}: #{error.}" end end.compact.first end |
#extract_content(*hashes, &content_block) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/action_presenter/base.rb', line 85 def extract_content(*hashes, &content_block) content = extract(:content, *hashes) # block has highest precedence content = view.capture(&content_block) if content_block.is_a?(Proc) content = content.to_s if content.is_a?(Numeric) # check for escaped HTML if .verify_content && !content.is_a?(ActiveSupport::SafeBuffer) if content =~ /<[a-zA-Z]+( |>)/ || content =~ / / = "Escaped HTML in #{self.class} content: #{content}" if Rails.env.production? Rails.logger.warn { } else raise ArgumentError, end end end content end |
#extract_content_block(*hashes, &content_block) ⇒ Object
104 105 106 |
# File 'lib/action_presenter/base.rb', line 104 def extract_content_block(*hashes, &content_block) content_block.is_a?(Proc) ? content_block : proc { extract_content(*hashes) } end |
#extract_html(*hashes) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 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 |
# File 'lib/action_presenter/base.rb', line 38 def extract_html(*hashes) html_attributes = {} add_classes = [] remove_classes = [] merge_data = {} reverse_merge_data = {} hashes.each do |hash| next if hash.blank? # custom class attributes add_class = extract(:add_class, hash) add_classes << add_class if add_class.present? remove_class = extract(:remove_class, hash) remove_classes << remove_class if remove_class.present? # custom data attributes merging_data = extract(:merge_data, hash) merge_data.merge!(merging_data.to_h.symbolize_keys) if merging_data.present? reverse_merging_data = extract(:reverse_merge_data, hash) reverse_merge_data.merge!(reverse_merging_data.to_h.symbolize_keys) if reverse_merging_data.present? # rest html_attributes.reverse_merge!(hash.symbolize_keys) end # custom class attributes if add_classes.present? || remove_classes.present? classes_to_a = -> (value) do case value when Symbol then classes_to_a.call(send(value)) when Array then value.map { |v| classes_to_a.call(v) } else value.to_s.split(/\s/) end.flatten end classes = classes_to_a.call(html_attributes[:class]) classes += classes_to_a.call(add_classes) classes -= classes_to_a.call(remove_classes) # reverse so classes appear to append in order html_attributes[:class] = classes.uniq.join(" ").presence end # custom data attributes if merge_data.present? || reverse_merge_data.present? html_attributes[:data] ||= {} html_attributes[:data].merge!(merge_data) if merge_data.present? html_attributes[:data].reverse_merge!(reverse_merge_data) if reverse_merge_data.present? end html_attributes.select do |html_attribute, value| !html_attribute.in?(PRESENTER_ATTRIBUTES) end end |
#extract_query_params(*hashes) ⇒ Object
112 113 114 |
# File 'lib/action_presenter/base.rb', line 112 def extract_query_params(*hashes) extract(:query_params, *hashes, query_params: {}) end |
#extract_record(*hashes) ⇒ Object
108 109 110 |
# File 'lib/action_presenter/base.rb', line 108 def extract_record(*hashes) extract(:record, *hashes, record: record) end |
#file_field_tag(name, *hashes, &content_block) ⇒ Object
70 71 72 73 |
# File 'lib/action_presenter/base/html.rb', line 70 def file_field_tag(name, *hashes, &content_block) default_html = { id: name.to_s.slugify_html, name: name, class: file_field_class } view.file_field_tag(name, extract_html(*hashes, default_html)) end |
#form_for(*hashes, &content_block) ⇒ Object
12 13 14 15 16 17 18 |
# File 'lib/action_presenter/base/form.rb', line 12 def form_for(*hashes, &content_block) record = extract_record(*hashes) view.form_for(record, extract_html(*hashes)) do |form_builder| self.form_builder = form_builder yield(form_builder) end end |
#form_tag(path, *hashes, &content_block) ⇒ Object
5 6 7 8 9 10 |
# File 'lib/action_presenter/base/form.rb', line 5 def form_tag(path, *hashes, &content_block) view.form_tag(path, extract_html(*hashes)) do |form_builder| self.form_builder = form_builder yield(form_builder) end end |
#hidden_field(name, *hashes, &content_block) ⇒ Object
37 38 39 40 |
# File 'lib/action_presenter/base/form.rb', line 37 def hidden_field(name, *hashes, &content_block) default_html = { value: extract_content(*hashes, &content_block) }.compact form_builder.hidden_field(name, extract_html(*hashes, default_html)) end |
#hidden_field_tag(name, *hashes, &content_block) ⇒ Object
75 76 77 78 79 |
# File 'lib/action_presenter/base/html.rb', line 75 def hidden_field_tag(name, *hashes, &content_block) default_html = { id: name.to_s.slugify_html, name: name } content = extract_content(*hashes, content: view.params.to_unsafe_h.dig_html(name), &content_block) view.hidden_field_tag(name, content, extract_html(*hashes, default_html)) end |
#html_tag(tag, *hashes, &content_block) ⇒ Object
4 5 6 |
# File 'lib/action_presenter/base/html.rb', line 4 def html_tag(tag, *hashes, &content_block) view.content_tag(tag, extract_html(*hashes), &extract_content_block(*hashes, &content_block)) end |
#image_tag(name, *hashes, &content_block) ⇒ Object
46 47 48 |
# File 'lib/action_presenter/base/html.rb', line 46 def image_tag(name, *hashes, &content_block) view.image_tag(name, extract_html(*hashes), &extract_content_block(*hashes, &content_block)) end |
#inline_html_tag(tag, *hashes, &content_block) ⇒ Object
8 9 10 |
# File 'lib/action_presenter/base/html.rb', line 8 def inline_html_tag(tag, *hashes, &content_block) view.tag(tag, extract_html(*hashes), &extract_content_block(*hashes, &content_block)) end |
#label(name, *hashes, &content_block) ⇒ Object
form elements
27 28 29 30 |
# File 'lib/action_presenter/base/form.rb', line 27 def label(name, *hashes, &content_block) default_html = { class: label_class } form_builder.label(name, extract_html(*hashes, default_html), &extract_content_block(*hashes, &content_block)) end |
#label_for(name, *hashes, &content_block) ⇒ Object
87 88 89 90 |
# File 'lib/action_presenter/base/html.rb', line 87 def label_for(name, *hashes, &content_block) default_html = { class: label_for_class } view.label_tag(name, extract_html(*hashes, default_html), &extract_content_block(*hashes, &content_block)) end |
#link_to(link, *hashes, &content_block) ⇒ Object
50 51 52 |
# File 'lib/action_presenter/base/html.rb', line 50 def link_to(link, *hashes, &content_block) view.link_to(link, extract_html(*hashes), &extract_content_block(*hashes, &content_block)) end |
#method_field(*hashes, &content_block) ⇒ Object
42 43 44 |
# File 'lib/action_presenter/base/html.rb', line 42 def method_field(*hashes, &content_block) hidden_field_tag("_method", *hashes, id: nil, value: "post", &content_block) end |
#presenter_options ⇒ Object
24 25 26 |
# File 'lib/action_presenter/base.rb', line 24 def self.class..dup end |
#radio_button(name, *hashes, &content_block) ⇒ Object
83 84 85 86 87 |
# File 'lib/action_presenter/base/form.rb', line 83 def (name, *hashes, &content_block) default_html = { class: } content = extract_content(*hashes, &content_block).to_s form_builder.(name, content, extract_html(*hashes, default_html)) end |
#radio_button_tag(name, *hashes, &content_block) ⇒ Object
105 106 107 108 109 110 111 112 |
# File 'lib/action_presenter/base/html.rb', line 105 def (name, *hashes, &content_block) default_html = { id: name.to_s.slugify_html, name: name, class: } content = extract_content(*hashes, &content_block).presence active_content = view.params.to_unsafe_h.dig_html(name).presence checked = extract(:checked, *hashes) checked = checked.in?([true, false]) ? checked : active_content == content view.(nil, content, checked, extract_html(*hashes, default_html)) end |
#select(name, *hashes, &content_block) ⇒ Object
47 48 49 50 51 52 |
# File 'lib/action_presenter/base/form.rb', line 47 def select(name, *hashes, &content_block) default_html = { class: select_class } content = extract_content(*hashes, &content_block) || {} = %i[ include_blank prompt ].map { |key| [key, extract(key, *hashes)] }.to_h form_builder.select(name, content, , extract_html(*hashes, default_html)) end |
#select_tag(name, *hashes, &content_block) ⇒ Object
form elements
55 56 57 58 59 60 61 62 |
# File 'lib/action_presenter/base/html.rb', line 55 def select_tag(name, *hashes, &content_block) default_html = { id: name.to_s.slugify_html, name: name, class: select_class } content = extract_content(*hashes, &content_block) if !content.is_a?(String) content = view.(content, extract(:selected, *hashes, selected: view.params.to_unsafe_h.dig_html(name))) end view.select_tag(name, content, extract_html(*hashes, default_html)) end |
#set(options) ⇒ Object
19 20 21 22 |
# File 'lib/action_presenter/base.rb', line 19 def set() .each { |method, value| send "#{method}=", value } self end |
#submit_tag(*hashes, &content_block) ⇒ Object
38 39 40 |
# File 'lib/action_presenter/base/html.rb', line 38 def submit_tag(*hashes, &content_block) view.submit_tag(extract_content(*hashes, content: "Submit", &content_block), extract_html(*hashes)) end |
#text_area(name, *hashes, &content_block) ⇒ Object
42 43 44 45 |
# File 'lib/action_presenter/base/form.rb', line 42 def text_area(name, *hashes, &content_block) default_html = { class: text_area_class, value: extract_content(*hashes, &content_block) }.compact form_builder.text_area(name, extract_html(*hashes, default_html)) end |
#text_area_tag(name, *hashes, &content_block) ⇒ Object
81 82 83 84 85 |
# File 'lib/action_presenter/base/html.rb', line 81 def text_area_tag(name, *hashes, &content_block) default_html = { id: name.to_s.slugify_html, name: name, class: text_area_class } content = extract_content(*hashes, content: view.params.to_unsafe_h.dig_html(name), &content_block) view.text_area_tag(name, content, extract_html(*hashes, default_html)) end |
#text_field(name, *hashes, &content_block) ⇒ Object
32 33 34 35 |
# File 'lib/action_presenter/base/form.rb', line 32 def text_field(name, *hashes, &content_block) default_html = { class: text_field_class, value: extract_content(*hashes, &content_block) }.compact form_builder.text_field(name, extract_html(*hashes, default_html)) end |
#text_field_tag(name, *hashes, &content_block) ⇒ Object
64 65 66 67 68 |
# File 'lib/action_presenter/base/html.rb', line 64 def text_field_tag(name, *hashes, &content_block) default_html = { id: name.to_s.slugify_html, name: name, class: text_field_class } content = extract_content(*hashes, content: view.params.to_unsafe_h.dig_html(name), &content_block) view.text_field_tag(name, content, extract_html(*hashes, default_html)) end |