Module: VenusMediaLibrary::PickerHelper
- Defined in:
- app/helpers/venus_media_library/picker_helper.rb
Overview
Host-facing helper. Included into the host app's views by the engine (see VenusMediaLibrary::Engine), so apps can drop the picker next to any URL field.
<%= form_with model: @page do |f| %>
<%= media_picker_field f, :og_image %>
<% end %>
Renders a text input (the field the host already had) plus a "Choose from
library" button wired to open the modal. Selecting an image writes its URL
into the input; a hidden <field>_signed_id input also receives the blob's
signed id so the host can attach it if desired.
Instance Method Summary collapse
-
#media_attach_field(form, attachment, **opts) ⇒ Object
Attach-mode picker.
-
#media_picker_field(form, field, **opts) ⇒ Object
form - a form builder (form_with / form_for) field - the attribute holding the image URL (e.g. :og_image) opts: :label - button label (default "Choose from library") :placeholder - text input placeholder :signed_id_field - name for the hidden signed-id input (default "
_signed_id"); pass false to skip :input_html - extra HTML options merged into the text input :class - wrapper CSS class. -
#ml_attachment_preview_value(record, attachment) ⇒ Object
Best-effort URL for the currently attached file, used to seed the preview.
-
#venus_media_library_modal_shell ⇒ Object
Renders the shared modal shell once per page.
Instance Method Details
#media_attach_field(form, attachment, **opts) ⇒ Object
Attach-mode picker. Use this for an Active Storage attachment (has_one_attached) rather than a URL column: the picker writes the chosen blob's signed_id into a hidden field NAMED FOR THE ATTACHMENT (e.g. product), so Rails attaches that blob on save.
<%= form_with model: @product do |f| %>
<%= media_attach_field f, :cover %>
<% end %>
The visible input is a read-only preview (it is NOT submitted). The hidden
attachment field is disabled until an image is picked, because submitting an
empty string for a has_one_attached would DETACH the current file; the JS sets
the signed_id and enables the field on selection.
form - a form builder bound to the record attachment - the has_one_attached name (e.g. :cover) opts:
:label - button label (default "Choose from library")
:placeholder - preview input placeholder
:input_html - extra HTML options merged into the preview input
:class - wrapper CSS class
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'app/helpers/venus_media_library/picker_helper.rb', line 77 def media_attach_field(form, , **opts) input_id = "#{form.object_name}_#{}".parameterize.tr("-", "_") label = opts.fetch(:label, "Choose from library") wrapper = opts.fetch(:class, "ml-field") preview_html = { id: input_id, class: "ml-field__input", type: "text", readonly: true, value: (form.object, ), placeholder: opts[:placeholder] }.merge(opts[:input_html] || {}) picker_src = venus_media_library.picker_path(target: input_id) content_tag(:div, class: wrapper, data: { ml_field: input_id }) do parts = [] # Read-only preview of the current/chosen image. No name -> not submitted. parts << tag.input(**preview_html) # Hidden field named for the attachment. Disabled (so a blank value can't # detach on save) until the JS writes a signed_id and enables it. parts << form.hidden_field(, value: "", disabled: true, id: "#{input_id}_signed_id", data: { ml_signed_id_for: input_id }) parts << (label, type: "button", class: "ml-btn ml-btn--primary ml-field__button", data: { ml_open: true, ml_target: input_id, ml_src: picker_src }) safe_join(parts) end + venus_media_library_modal_shell end |
#media_picker_field(form, field, **opts) ⇒ Object
form - a form builder (form_with / form_for) field - the attribute holding the image URL (e.g. :og_image) opts:
:label - button label (default "Choose from library")
:placeholder - text input placeholder
:signed_id_field - name for the hidden signed-id input
(default "<field>_signed_id"); pass false to skip
:input_html - extra HTML options merged into the text input
:class - wrapper CSS class
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 |
# File 'app/helpers/venus_media_library/picker_helper.rb', line 23 def media_picker_field(form, field, **opts) input_id = "#{form.object_name}_#{field}".parameterize.tr("-", "_") label = opts.fetch(:label, "Choose from library") wrapper = opts.fetch(:class, "ml-field") input_html = { id: input_id, class: "ml-field__input", placeholder: opts[:placeholder] }.merge(opts[:input_html] || {}) signed_id_field = opts.fetch(:signed_id_field, "#{field}_signed_id") # Endpoint the JS uses to load the picker frame for this field. picker_src = venus_media_library.picker_path(target: input_id) content_tag(:div, class: wrapper, data: { ml_field: input_id }) do parts = [] parts << form.text_field(field, input_html) if signed_id_field hidden_id = "#{input_id}_signed_id" parts << form.hidden_field(signed_id_field, id: hidden_id, data: { ml_signed_id_for: input_id }) end parts << (label, type: "button", class: "ml-btn ml-btn--primary ml-field__button", data: { ml_open: true, ml_target: input_id, ml_src: picker_src }) safe_join(parts) end + venus_media_library_modal_shell end |
#ml_attachment_preview_value(record, attachment) ⇒ Object
Best-effort URL for the currently attached file, used to seed the preview. Rescues to the filename (or blank) so a missing host/route never breaks the form.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'app/helpers/venus_media_library/picker_helper.rb', line 118 def (record, ) attached = record.respond_to?() && record.public_send() return "" unless attached && attached.respond_to?(:attached?) && attached.attached? if VenusMediaLibrary.configuration.url_type == :proxy rails_storage_proxy_url(attached) else rails_blob_url(attached) end rescue StandardError begin attached && attached.attached? ? attached.filename.to_s : "" rescue StandardError "" end end |
#venus_media_library_modal_shell ⇒ Object
Renders the shared modal shell once per page. The picker frame is lazy loaded into it when a button is clicked.
137 138 139 140 141 142 |
# File 'app/helpers/venus_media_library/picker_helper.rb', line 137 def venus_media_library_modal_shell return "".html_safe if @_venus_media_library_modal_rendered @_venus_media_library_modal_rendered = true render partial: "venus_media_library/pickers/modal" end |