Class: LatoCms::PageField
- Inherits:
-
ApplicationRecord
- Object
- ApplicationRecord
- LatoCms::PageField
- Defined in:
- app/models/lato_cms/page_field.rb
Constant Summary collapse
- REPEATER_ORDER_FIELD_ID =
"__repeater_order".freeze
Instance Method Summary collapse
- #as_json(_options = {}) ⇒ Object
- #base_field_id ⇒ Object
- #field_config ⇒ Object
- #field_name ⇒ Object
- #field_required? ⇒ Boolean
- #field_settings ⇒ Object
- #field_type ⇒ Object
-
#generate_video_poster! ⇒ Object
Generates a poster image from the video via Active Storage previews (ffmpeg) and attaches it alongside the video.
- #parsed_value ⇒ Object
- #poster_attachment ⇒ Object
- #repeater_item_id ⇒ Object
- #repeater_order? ⇒ Boolean
-
#video_attachment ⇒ Object
A video field stores two attachments in
files: the video itself and an optional auto-generated poster image.
Instance Method Details
#as_json(_options = {}) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'app/models/lato_cms/page_field.rb', line 110 def as_json( = {}) result = { id: id, persisted_field_id: field_id, field_id: base_field_id, field_type: field_type, field_name: field_name, required: field_required?, value: nil, attachments: [] } case field_type when 'file' result[:attachments] = files.map { |f| (f) } when 'image' attached = files.first result[:attachments] = attached ? [(attached, with_variants: true)] : [] when 'video' attached = result[:attachments] = attached ? [(attached)] : [] when 'gallery' order = value ? (JSON.parse(value) rescue []) : [] all_files = files.to_a ordered = order.any? ? all_files.sort_by { |f| order.index(f.id.to_s) || Float::INFINITY } : all_files result[:attachments] = ordered.map { |f| (f, with_variants: true) } else result[:value] = parsed_value end result end |
#base_field_id ⇒ Object
56 57 58 59 60 |
# File 'app/models/lato_cms/page_field.rb', line 56 def base_field_id return field_id unless repeater_item_id field_id.to_s.split('.', 2).last end |
#field_config ⇒ Object
38 39 40 41 42 43 44 |
# File 'app/models/lato_cms/page_field.rb', line 38 def field_config return nil if repeater_order? component = LatoCms::TemplateManager.find_component(component_id) return nil unless component component.dig('fields', base_field_id) end |
#field_name ⇒ Object
66 67 68 |
# File 'app/models/lato_cms/page_field.rb', line 66 def field_name field_config&.dig('name') || field_id.to_s.humanize end |
#field_required? ⇒ Boolean
70 71 72 |
# File 'app/models/lato_cms/page_field.rb', line 70 def field_required? field_config&.dig('required') == true end |
#field_settings ⇒ Object
74 75 76 |
# File 'app/models/lato_cms/page_field.rb', line 74 def field_settings field_config&.dig('settings') || {} end |
#field_type ⇒ Object
62 63 64 |
# File 'app/models/lato_cms/page_field.rb', line 62 def field_type field_config&.dig('type') || 'string' end |
#generate_video_poster! ⇒ Object
Generates a poster image from the video via Active Storage previews (ffmpeg) and attaches it alongside the video. Best effort: any failure is logged and the video keeps working without a poster.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'app/models/lato_cms/page_field.rb', line 92 def generate_video_poster! video = return unless video return if unless video.previewable? Rails.logger.warn("LatoCms: video preview unavailable (ffmpeg missing?) for attachment #{video.id}, skipping poster generation") return end preview = video.preview(resize_to_limit: [1280, 720]).processed preview.image.blob.open do |file| files.attach(io: file, filename: "#{video.filename.base}_poster.jpg", content_type: preview.image.blob.content_type) end rescue StandardError => e Rails.logger.warn("LatoCms: failed to generate video poster for field #{id}: #{e.}") end |
#parsed_value ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'app/models/lato_cms/page_field.rb', line 17 def parsed_value return nil if value.blank? case field_type when 'number' value.include?('.') ? value.to_f : value.to_i when 'boolean' value == 'true' when 'json' JSON.parse(value) rescue value when 'date' Date.parse(value) rescue value when 'datetime' DateTime.parse(value) rescue value when 'multiselect' JSON.parse(value) rescue [value] else value end end |
#poster_attachment ⇒ Object
85 86 87 |
# File 'app/models/lato_cms/page_field.rb', line 85 def files.find { |file| file.content_type.to_s.start_with?("image/") } end |
#repeater_item_id ⇒ Object
50 51 52 53 54 |
# File 'app/models/lato_cms/page_field.rb', line 50 def repeater_item_id return nil unless field_id.to_s.include?('.') field_id.to_s.split('.', 2).first end |
#repeater_order? ⇒ Boolean
46 47 48 |
# File 'app/models/lato_cms/page_field.rb', line 46 def repeater_order? field_id == REPEATER_ORDER_FIELD_ID end |
#video_attachment ⇒ Object
A video field stores two attachments in files: the video itself and an
optional auto-generated poster image. Content type is the discriminator,
so no extra column or naming convention is needed.
81 82 83 |
# File 'app/models/lato_cms/page_field.rb', line 81 def files.find { |file| file.content_type.to_s.start_with?("video/") } end |