From 836308471f8d31ccdcdd3a5bd88bc76cc1c0831b Mon Sep 17 00:00:00 2001 From: erdgeist Date: Mon, 20 Jul 2026 19:45:43 +0200 Subject: Make headline images explicit, add asset credits - related_assets gains a `headline` boolean (DB-enforced: at most one per page), replacing "first image by position" as the headline rule. A rake task backfills the current first image on every live head/draft, so nothing changes visually until an editor changes it. - The image picker sidebar gets a star toggle reflecting the flag; the TinyMCE inline-image picker's badge now reads it too, instead of assuming position 0. - No headline chosen (or none attached) now falls back to the gallery-count caption itself becoming the lightbox trigger, instead of the gallery being unreachable. - Assets gain creator, source_url, and license_key (against a new config/asset_licenses.yml dictionary). asset_credit renders a degrading attribution line, reused as a hidden per-image glightbox caption so credit is one click away for every image, not only the headline's always-visible one. - Fixed: asset thumbnails rendered unconditionally regardless of whether a real variant exists on disk. Asset#has_variant? checks file existence, not content type -- some legacy PDFs have real pre-rewrite thumbnails a content-type check would have hidden. - assets#new/edit rebuilt onto the same node_description/node_content layout as assets#show, picking up the three new fields in the process. --- app/models/asset.rb | 8 +++++++- app/models/asset_license.rb | 15 +++++++++++++++ app/models/concerns/file_attachment.rb | 8 ++++++++ app/models/related_asset.rb | 9 +++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 app/models/asset_license.rb (limited to 'app/models') diff --git a/app/models/asset.rb b/app/models/asset.rb index aca0ee8..8bea1b3 100644 --- a/app/models/asset.rb +++ b/app/models/asset.rb @@ -1,12 +1,18 @@ class Asset < ApplicationRecord + IMAGE_CONTENT_TYPES = ["image/gif", "image/jpeg", "image/png", "image/webp"] include FileAttachment has_many :related_assets, :dependent => :destroy has_many :pages, :through => :related_assets - scope :images, -> { where(:upload_content_type => ["image/gif", "image/jpeg", "image/png", "image/webp"]) } + scope :images, -> { where(:upload_content_type => IMAGE_CONTENT_TYPES) } scope :documents, -> { where(:upload_content_type => ["application/pdf", "text/plain", "text/rtf"]) } scope :audio, -> { where(:upload_content_type => ["audio/mpeg", "audio/x-m4a", "audio/wav", "audio/x-wav"]) } + validates :license_key, inclusion: { in: -> { AssetLicense.keys } }, allow_blank: true + + def image? + IMAGE_CONTENT_TYPES.include?(upload_content_type) + end end diff --git a/app/models/asset_license.rb b/app/models/asset_license.rb new file mode 100644 index 0000000..ca66d40 --- /dev/null +++ b/app/models/asset_license.rb @@ -0,0 +1,15 @@ +class AssetLicense + Entry = Struct.new(:key, :url, :requires_attribution, :style, keyword_init: true) + + DICTIONARY = YAML.load_file(Rails.root.join("config", "asset_licenses.yml")).freeze + + def self.keys + DICTIONARY.keys + end + + def self.find(key) + entry = DICTIONARY[key.to_s] if key.present? + return nil unless entry + Entry.new(key: key.to_s, url: entry["url"], requires_attribution: entry["requires_attribution"], style: entry["style"]) + end +end diff --git a/app/models/concerns/file_attachment.rb b/app/models/concerns/file_attachment.rb index 3c09456..e7a33c5 100644 --- a/app/models/concerns/file_attachment.rb +++ b/app/models/concerns/file_attachment.rb @@ -52,6 +52,14 @@ module FileAttachment build_upload_proxy end + def has_variant?(style) + upload_file_name.present? && File.exist?(file_path(style)) + end + + def previewable? + has_variant?(:medium) + end + private def build_upload_proxy diff --git a/app/models/related_asset.rb b/app/models/related_asset.rb index 8f16460..62000cc 100644 --- a/app/models/related_asset.rb +++ b/app/models/related_asset.rb @@ -5,4 +5,13 @@ class RelatedAsset < ApplicationRecord acts_as_list :scope => :page_id default_scope -> { order("position ASC") } + + validate :headline_only_for_images + + private + + def headline_only_for_images + return unless asset + errors.add(:headline, "can only be set on image assets") if headline? && !asset.image? + end end -- cgit v1.3