Skip to content

Commit

Permalink
Add cms:page_file_link tag to render page files
Browse files Browse the repository at this point in the history
Examples:

  {{ cms:page_file_link header }}
  {{ cms:page_file_link attachments, filename: "cat.jpg", as: image }}

Dragging page-level files onto the textarea generates these tags.

See #796 for more information.
  • Loading branch information
glebm committed Feb 27, 2018
1 parent d595c13 commit 092e8a9
Show file tree
Hide file tree
Showing 10 changed files with 253 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@
- variant = attachment.variant(Comfy::Cms::File::VARIANT_SIZE[:thumb])
- thumb = image_tag(url_for(variant), size: "200x150")
.fragment-attachment.btn-group.btn-group-sm.mb-1
- filename = attachment.filename.to_s
- truncated_filename = truncate(filename, length: 40, omission: "...#{filename.last(10)}")
= link_to truncated_filename, attachment, data: {toggle: "page-file-popover", content: thumb}, class: "btn btn-light text-truncate", target: "_blank"
:ruby
filename = attachment.filename.to_s
truncated_filename = truncate(filename, length: 40, omission: "...#{filename.last(10)}")
cms_page_file_link_tag = [
"{{ cms:page_file_link #{fragment_id}",
(", filename: \"#{filename}\"" if multiple),
(", as: image" if attachment.image?),
" }}".html_safe
].compact.join
= link_to truncated_filename, attachment,
data: {toggle: "page-file-popover", content: thumb},
class: "btn btn-light text-truncate", target: "_blank",
ondragstart: "event.dataTransfer.setData('text/plain', '#{cms_page_file_link_tag}');"
= check_box_tag "#{object_name}[fragments_attributes][#{index}][file_ids_destroy][]", attachment.id, false, id: dom_id(attachment)
%label.btn.btn-light{for: dom_id(attachment)}
%i.fas.fa-fw.fa-times
1 change: 1 addition & 0 deletions lib/comfortable_mexican_sofa/content.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module ComfortableMexicanSofa::Content
require_relative "content/tags/snippet"
require_relative "content/tags/asset"
require_relative "content/tags/file_link"
require_relative "content/tags/page_file_link"
require_relative "content/tags/helper"
require_relative "content/tags/partial"
require_relative "content/tags/template"
36 changes: 11 additions & 25 deletions lib/comfortable_mexican_sofa/content/tags/file.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require "comfortable_mexican_sofa/content/tags/file_content.rb"

# File tag allows attaching of file to the page. This controls how files are
# uploaded and then displayed on the page. Example tag:
# {{cms:file identifier, as: link, label: "My File"}}
Expand All @@ -12,14 +14,15 @@
#
class ComfortableMexicanSofa::Content::Tag::File < ComfortableMexicanSofa::Content::Tag::Fragment

include ComfortableMexicanSofa::Content::Tag::FileContent
include ActionView::Helpers::OutputSafetyHelper

# @type ["url", "link", "image"]
attr_reader :as

# @type [{String => String}]
attr_reader :variant_attrs

delegate :rails_blob_path, to: "Rails.application.routes.url_helpers"

# @param (see ComfortableMexicanSofa::Content::Tag#initialize)
def initialize(context:, params: [], source: nil)
super
Expand All @@ -28,25 +31,6 @@ def initialize(context:, params: [], source: nil)
@variant_attrs = options.slice("resize", "gravity", "crop")
end

def content(file = attachment)
return "" unless file

if @variant_attrs.present? && attachment.image?
file = file.variant(@variant_attrs)
end

url = rails_blob_path(file, only_path: true)

case @as
when "link"
"<a href='#{url}' target='_blank'>#{label}</a>"
when "image"
"<img src='#{url}' alt='#{label}'/>"
else
url
end
end

def form_field(object_name, view, index)
name = "#{object_name}[fragments_attributes][#{index}][files]"
input = view.send(:file_field_tag, name, id: nil, class: "form-control")
Expand All @@ -58,24 +42,26 @@ def form_field(object_name, view, index)
locals: {
object_name: object_name,
index: index,
attachments: fragment.attachments
attachments: fragment.attachments,
fragment_id: identifier,
multiple: false
}
)
end

yield [input, attachments_partial].join.html_safe
yield safe_join([input, attachments_partial], "")
end

protected

# @return [ActiveStorage::Blob]
def attachment
def file
fragment.attachments.first
end

# @return [String]
def label
@label || attachment&.filename
@label || file&.filename
end

end
Expand Down
36 changes: 36 additions & 0 deletions lib/comfortable_mexican_sofa/content/tags/file_content.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

# A mixin for tags that returns the file as their content.
module ComfortableMexicanSofa::Content::Tag::FileContent

# @param [ActiveStorage::Blob] file
# @param ["link", "image", "url"] as
# @param [{String => String}] variant_attrs ImageMagick variant attributes
# @param [String] label alt text for `as: "image"`, link text for `as: "link"`
# @return [String]
def content(file: self.file, as: self.as, variant_attrs: self.variant_attrs, label: self.label)
return "" unless file

if variant_attrs.present? && attachment.image?
file = file.variant(variant_attrs)
end

url = rails_blob_path(file)

case as
when "link"
"<a href='#{url}' target='_blank'>#{label}</a>"
when "image"
"<img src='#{url}' alt='#{label}'/>"
else
url
end
end

# @param [ActiveStorage::Blob]
# @return [String]
def rails_blob_path(blob)
Rails.application.routes.url_helpers.rails_blob_path(blob, only_path: true)
end

end
45 changes: 21 additions & 24 deletions lib/comfortable_mexican_sofa/content/tags/file_link.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require "comfortable_mexican_sofa/content/tags/file_content.rb"

# This is how you link previously uploaded file to anywhere. Good example may be
# a header image you want to use on the layout level.
# {{cms:file_link id, as: image}}
Expand All @@ -12,9 +14,16 @@
#
class ComfortableMexicanSofa::Content::Tag::FileLink < ComfortableMexicanSofa::Content::Tag

attr_reader :identifier, :as, :variant_attrs
include ComfortableMexicanSofa::Content::Tag::FileContent

# @return [String] A {Comfy::Cms::Site#files} ID.
attr_reader :identifier

# @type ["url", "link", "image"]
attr_reader :as

delegate :rails_blob_path, to: "Rails.application.routes.url_helpers"
# @type [{String => String}]
attr_reader :variant_attrs

def initialize(context:, params: [], source: nil)
super
Expand All @@ -29,32 +38,20 @@ def initialize(context:, params: [], source: nil)
end
end

def file
@file ||= context.site.files.detect { |f| f.id == identifier.to_i }
# @return [Comfy::Cms::File]
def file_record
@file_record ||= context.site.files.detect { |f| f.id == identifier.to_i }
end

def label
@file.label.present? ? @file.label : @file.attachment.filename
# @return [ActiveStorage::Blob]
def file
file_record&.attachment
end

def content
return "" unless file&.attachment

attachment = file.attachment
if @variant_attrs.present? && attachment.image?
attachment = attachment.variant(@variant_attrs)
end

url = rails_blob_path(attachment, only_path: true)

case @as
when "link"
"<a href='#{url}' target='_blank'>#{label}</a>"
when "image"
"<img src='#{url}' alt='#{label}'/>"
else
url
end
# @return [String]
def label
return "" if file_record.nil?
file_record.label.presence || file.filename.to_s
end

end
Expand Down
13 changes: 5 additions & 8 deletions lib/comfortable_mexican_sofa/content/tags/files.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,11 @@
#
class ComfortableMexicanSofa::Content::Tag::Files < ComfortableMexicanSofa::Content::Tag::File

# @param (see ComfortableMexicanSofa::Content::Tag#initialize)
def initialize(context:, params: [], source: nil)
super
end

def content
return "" if fragment.attachments.blank?

fragment.attachments.collect do |attachment|
super(attachment)
super(file: attachment, label: attachment.filename)
end.join(" ")
end

Expand All @@ -29,12 +24,14 @@ def form_field(object_name, view, index)
locals: {
object_name: object_name,
index: index,
attachments: fragment.attachments
attachments: fragment.attachments,
fragment_id: identifier,
multiple: true
}
)
end

yield [input, attachments_partial].join.html_safe
yield safe_join([input, attachments_partial], "")
end

end
Expand Down
80 changes: 80 additions & 0 deletions lib/comfortable_mexican_sofa/content/tags/page_file_link.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# frozen_string_literal: true

require "comfortable_mexican_sofa/content/tags/file_content.rb"

# This tag allows you to link page-level files from withing the page.
#
# E.g. if your layout has:
#
# {{ cms:file graphic }}
# {{ cms:files attachments }}
#
# You can link to the files from an individual page like so:
#
# {{ cms:page_file_link graphic }}
# {{ cms:page_file_link attachments, filename: "cat.jpg" }}
#
# `as` - url (default) | link | image - how file gets rendered out
# `label` - attach label attribute to link or image tag
# `resize` - imagemagick option. For example: "100x50>"
# `gravity` - imagemagick option. For example: "center"
# `crop` - imagemagick option. For example: "100x50+0+0"
#
class ComfortableMexicanSofa::Content::Tag::PageFileLink < ComfortableMexicanSofa::Content::Tag

include ComfortableMexicanSofa::Content::Tag::FileContent

# @return [String] A `cms:file(s)` identifier.
attr_reader :identifier

# @type ["url", "link", "image"]
attr_reader :as

# @type [{String => String}]
attr_reader :variant_attrs

# @return [String] Used to refer to a file in a {{ cms:files }} tag.
attr_reader :filename

# @param (see ComfortableMexicanSofa::Content::Tag#initialize)
def initialize(context:, params: [], source: nil)
super

options = params.extract_options!
@identifier = params[0]
@as = options["as"] || "url"
@variant_attrs = options.slice("resize", "gravity", "crop")
@filename = options["filename"]

unless @identifier.present?
raise Error, "Missing identifier for page file link tag"
end
end

# @return [Comfy::Cms::Fragment]
def fragment
@fragment ||= context.fragments.detect { |f| f.identifier == identifier }
end

# @return [ActiveStorage::Blob]
def file
@file ||= if fragment.nil?
nil
elsif filename.nil?
fragment.attachments.first
else
fragment.attachments.detect { |a| a.filename.to_s == filename }
end
end

# @return [String]
def label
return if file.nil?
file.filename.to_s
end

end

ComfortableMexicanSofa::Content::Renderer.register_tag(
:page_file_link, ComfortableMexicanSofa::Content::Tag::PageFileLink
)
33 changes: 17 additions & 16 deletions test/lib/content/renderer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,23 @@ class TestBlockTag < ComfortableMexicanSofa::Content::Block
end

DEFAULT_REGISTERED_TAGS = {
"wysiwyg" => ComfortableMexicanSofa::Content::Tag::Wysiwyg,
"text" => ComfortableMexicanSofa::Content::Tag::Text,
"textarea" => ComfortableMexicanSofa::Content::Tag::TextArea,
"markdown" => ComfortableMexicanSofa::Content::Tag::Markdown,
"datetime" => ComfortableMexicanSofa::Content::Tag::Datetime,
"date" => ComfortableMexicanSofa::Content::Tag::Date,
"number" => ComfortableMexicanSofa::Content::Tag::Number,
"checkbox" => ComfortableMexicanSofa::Content::Tag::Checkbox,
"file" => ComfortableMexicanSofa::Content::Tag::File,
"files" => ComfortableMexicanSofa::Content::Tag::Files,
"snippet" => ComfortableMexicanSofa::Content::Tag::Snippet,
"asset" => ComfortableMexicanSofa::Content::Tag::Asset,
"file_link" => ComfortableMexicanSofa::Content::Tag::FileLink,
"helper" => ComfortableMexicanSofa::Content::Tag::Helper,
"partial" => ComfortableMexicanSofa::Content::Tag::Partial,
"template" => ComfortableMexicanSofa::Content::Tag::Template
"wysiwyg" => ComfortableMexicanSofa::Content::Tag::Wysiwyg,
"text" => ComfortableMexicanSofa::Content::Tag::Text,
"textarea" => ComfortableMexicanSofa::Content::Tag::TextArea,
"markdown" => ComfortableMexicanSofa::Content::Tag::Markdown,
"datetime" => ComfortableMexicanSofa::Content::Tag::Datetime,
"date" => ComfortableMexicanSofa::Content::Tag::Date,
"number" => ComfortableMexicanSofa::Content::Tag::Number,
"checkbox" => ComfortableMexicanSofa::Content::Tag::Checkbox,
"file" => ComfortableMexicanSofa::Content::Tag::File,
"files" => ComfortableMexicanSofa::Content::Tag::Files,
"snippet" => ComfortableMexicanSofa::Content::Tag::Snippet,
"asset" => ComfortableMexicanSofa::Content::Tag::Asset,
"file_link" => ComfortableMexicanSofa::Content::Tag::FileLink,
"page_file_link" => ComfortableMexicanSofa::Content::Tag::PageFileLink,
"helper" => ComfortableMexicanSofa::Content::Tag::Helper,
"partial" => ComfortableMexicanSofa::Content::Tag::Partial,
"template" => ComfortableMexicanSofa::Content::Tag::Template
}.freeze

setup do
Expand Down
Loading

0 comments on commit 092e8a9

Please sign in to comment.