class ActionText::Content
Action Text Content
¶ ↑
The ActionText::Content
class wraps an HTML fragment to add support for parsing, rendering and serialization. It can be used to extract links and attachments, convert the fragment to plain text, or serialize the fragment to the database.
The ActionText::RichText
record serializes the body
attribute as ActionText::Content
.
class Message < ActiveRecord::Base has_rich_text :content end message = Message.create!(content: "<h1>Funny times!</h1>") body = message.content.body # => #<ActionText::Content "<div class=\"trix-conte..."> body.to_s # => "<h1>Funny times!</h1>" body.to_plain_text # => "Funny times!"
Attributes
Public Class Methods
# File actiontext/lib/action_text/content.rb, line 33 def fragment_by_canonicalizing_content(content) fragment = ActionText::Attachment.fragment_by_canonicalizing_attachments(content) fragment = ActionText::AttachmentGallery.fragment_by_canonicalizing_attachment_galleries(fragment) fragment end
# File actiontext/lib/action_text/content.rb, line 40 def initialize(content = nil, options = {}) options.with_defaults! canonicalize: true if options[:canonicalize] @fragment = self.class.fragment_by_canonicalizing_content(content) else @fragment = ActionText::Fragment.wrap(content) end end
Public Instance Methods
# File actiontext/lib/action_text/content.rb, line 169 def ==(other) if self.class == other.class to_html == other.to_html elsif other.is_a?(self.class) to_s == other.to_s end end
# File actiontext/lib/action_text/content.rb, line 93 def append_attachables(attachables) attachments = ActionText::Attachment.from_attachables(attachables) self.class.new([self.to_s.presence, *attachments].compact.join("\n")) end
# File actiontext/lib/action_text/content.rb, line 161 def as_json(*) to_html end
Extracts +ActionText::Attachable+s from the HTML fragment:
attachable = ActiveStorage::Blob.first html = %Q(<action-text-attachment sgid="#{attachable.attachable_sgid}" caption="Captioned"></action-text-attachment>) content = ActionText::Content.new(html) content.attachables # => [attachable]
# File actiontext/lib/action_text/content.rb, line 87 def attachables @attachables ||= attachment_nodes.map do |node| ActionText::Attachable.from_node(node) end end
# File actiontext/lib/action_text/content.rb, line 71 def attachment_galleries @attachment_galleries ||= attachment_gallery_nodes.map do |node| attachment_gallery_for_node(node) end end
Extracts +ActionText::Attachment+s from the HTML fragment:
attachable = ActiveStorage::Blob.first html = %Q(<action-text-attachment sgid="#{attachable.attachable_sgid}" caption="Captioned"></action-text-attachment>) content = ActionText::Content.new(html) content.attachments # => [#<ActionText::Attachment attachable=#<ActiveStorage::Blob...
# File actiontext/lib/action_text/content.rb, line 65 def attachments @attachments ||= attachment_nodes.map do |node| attachment_for_node(node) end end
# File actiontext/lib/action_text/content.rb, line 77 def gallery_attachments @gallery_attachments ||= attachment_galleries.flat_map(&:attachments) end
# File actiontext/lib/action_text/content.rb, line 165 def inspect "#<#{self.class.name} #{to_html.truncate(25).inspect}>" end
Extracts links from the HTML fragment:
html = '<a href="http://example.com/">Example</a>' content = ActionText::Content.new(html) content.links # => ["http://example.com/"]
# File actiontext/lib/action_text/content.rb, line 55 def links @links ||= fragment.find_all("a[href]").map { |a| a["href"] }.uniq end
# File actiontext/lib/action_text/content.rb, line 109 def render_attachment_galleries(&block) content = ActionText::AttachmentGallery.fragment_by_replacing_attachment_gallery_nodes(fragment) do |node| block.call(attachment_gallery_for_node(node)) end self.class.new(content, canonicalize: false) end
# File actiontext/lib/action_text/content.rb, line 98 def render_attachments(**options, &block) content = fragment.replace(ActionText::Attachment.tag_name) do |node| if node.key?("content") sanitized_content = sanitize_content_attachment(node.remove_attribute("content").to_s) node["content"] = sanitized_content if sanitized_content.present? end block.call(attachment_for_node(node, **options)) end self.class.new(content, canonicalize: false) end
# File actiontext/lib/action_text/content.rb, line 138 def to_html fragment.to_html end
# File actiontext/lib/action_text/content.rb, line 146 def to_partial_path "action_text/contents/content" end
Returns a plain-text version of the markup contained by the content, with tags removed but HTML entities encoded.
content = ActionText::Content.new("<h1>Funny times!</h1>") content.to_plain_text # => "Funny times!" content = ActionText::Content.new("<div onclick='action()'>safe<script>unsafe</script></div>") content.to_plain_text # => "safeunsafe"
NOTE: that the returned string is not HTML safe and should not be rendered in browsers.
content = ActionText::Content.new("<script>alert()</script>") content.to_plain_text # => "<script>alert()</script>"
# File actiontext/lib/action_text/content.rb, line 130 def to_plain_text render_attachments(with_full_attributes: false, &:to_plain_text).fragment.to_plain_text end
# File actiontext/lib/action_text/content.rb, line 142 def to_rendered_html_with_layout render layout: "action_text/contents/content", partial: to_partial_path, formats: :html, locals: { content: self } end
Safely transforms Content
into an HTML String
.
content = ActionText::Content.new(content: "<h1>Funny times!</h1>") content.to_s # => "<h1>Funny times!</h1>" content = ActionText::Content.new("<div onclick='action()'>safe<script>unsafe</script></div>") content.to_s # => "<div>safeunsafe</div>"
# File actiontext/lib/action_text/content.rb, line 157 def to_s to_rendered_html_with_layout end
# File actiontext/lib/action_text/content.rb, line 134 def to_trix_html render_attachments(&:to_trix_attachment).to_html end