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
[R] | fragment |
Public class methods
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 30
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
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 37
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
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 161
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
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 90
def append_attachables(attachables)
attachments = ActionText::Attachment.from_attachables(attachables)
self.class.new([self.to_s.presence, *attachments].compact.join("\n"))
end
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 153
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]
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 84
def attachables
@attachables ||= attachment_nodes.map do |node|
ActionText::Attachable.from_node(node)
end
end
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 68
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...
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 62
def attachments
@attachments ||= attachment_nodes.map do |node|
attachment_for_node(node)
end
end
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 74
def gallery_attachments
@gallery_attachments ||= attachment_galleries.flat_map(&:attachments)
end
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 157
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/"]
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 52
def links
@links ||= fragment.find_all("a[href]").map { |a| a["href"] }.uniq
end
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 102
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
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 95
def render_attachments(**options, &block)
content = fragment.replace(ActionText::Attachment.tag_name) do |node|
block.call(attachment_for_node(node, **options))
end
self.class.new(content, canonicalize: false)
end
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 130
def to_html
fragment.to_html
end
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 138
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>"
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 122
def to_plain_text
render_attachments(with_full_attributes: false, &:to_plain_text).fragment.to_plain_text
end
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 134
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>"
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 149
def to_s
to_rendered_html_with_layout
end
Source code GitHub
# File actiontext/lib/action_text/content.rb, line 126
def to_trix_html
render_attachments(&:to_trix_attachment).to_html
end