Class: ActionText::Content
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Instance Chain:
self,
Rendering,
Serialization,
ContentHelper
|
|
| Inherits: | Object |
| Defined in: | actiontext/lib/action_text/content.rb |
Overview
The 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
Content.
class Message < ActiveRecord::Base
has_rich_text :content
end
= Message.create!(content: "<h1>Funny times!</h1>")
body = .content.body # => #<ActionText::Content "<div class=\"trix-conte...">
body.to_s # => "<h1>Funny times!</h1>"
body.to_plain_text # => "Funny times!"
Rendering - Attributes & Methods
- #render readonly
Class Method Summary
Instance Attribute Summary
- #deconstruct readonly
- #fragment readonly
- #html_safe readonly
Instance Method Summary
- #==(other)
- #append_attachables(attachables)
- #as_json
-
#attachables
Extracts
Attachableobjects from the HTML fragment: - #attachment_galleries
-
#attachments
Extracts
Attachmentobjects from the HTML fragment: - #blank? ⇒ Boolean
- #empty? ⇒ Boolean
- #gallery_attachments
- #inspect
-
#links
Extracts links from the HTML fragment:
- #present? ⇒ Boolean
- #render_attachment_galleries(&block)
- #render_attachments(**options, &block)
- #to_html
-
#to_markdown(attachment_links: false)
Returns a Markdown version of the markup contained by the content.
- #to_partial_path
-
#to_plain_text
Returns a plain-text version of the markup contained by the content, with tags removed but HTML entities encoded.
- #to_rendered_html_with_layout
-
#to_s
Safely transforms
Contentinto an HTML String. - #to_trix_html
- #attachment_for_node(node, with_full_attributes: true) private
- #attachment_gallery_for_node(node) private
- #attachment_gallery_nodes private
- #attachment_nodes private
- #to_editor_html Internal use only
Serialization - Included
Constructor Details
.new(content = nil, options = {}) ⇒ Content
# File 'actiontext/lib/action_text/content.rb', line 39
def initialize(content = nil, = {}) .with_defaults! canonicalize: true if [:canonicalize] @fragment = self.class.fragment_by_canonicalizing_content(content) else @fragment = ActionText::Fragment.wrap(content) end end
Class Method Details
.fragment_by_canonicalizing_content(content)
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 31
def fragment_by_canonicalizing_content(content) fragment = ActionText::Attachment.(content) fragment = ActionText::AttachmentGallery.(fragment) fragment = ActionText::MarkdownConversion.(fragment) fragment end
Instance Attribute Details
#deconstruct (readonly)
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 27
delegate :deconstruct, to: :fragment
#fragment (readonly)
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 25
attr_reader :fragment
#html_safe (readonly)
[ GitHub ]#render (readonly)
[ GitHub ]# File 'actiontext/lib/action_text/rendering.rb', line 11
delegate :render, to: :class
Instance Method Details
#==(other)
[ GitHub ]#append_attachables(attachables)
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 92
def append_attachables(attachables) = ActionText::Attachment.from_attachables(attachables) self.class.new([self.to_s.presence, *].compact.join("\n")) end
#as_json
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 194
def as_json(*) to_html end
#attachables
Extracts Attachable objects 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 86
def attachables @attachables ||= .map do |node| ActionText::Attachable.from_node(node) end end
#attachment_for_node(node, with_full_attributes: true) (private)
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 219
def (node, with_full_attributes: true) = ActionText::Attachment.from_node(node) with_full_attributes ? .with_full_attributes : end
#attachment_galleries
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 70
def @attachment_galleries ||= .map do |node| (node) end end
#attachment_gallery_for_node(node) (private)
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 224
def (node) ActionText::AttachmentGallery.from_node(node) end
#attachment_gallery_nodes (private)
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 215
def @attachment_gallery_nodes ||= ActionText::AttachmentGallery.(fragment) end
#attachment_nodes (private)
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 211
def @attachment_nodes ||= fragment.find_all(ActionText::Attachment.tag_name) end
#attachments
Extracts Attachment objects 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. # => [#<ActionText::Attachment attachable=#<ActiveStorage::Blob...
# File 'actiontext/lib/action_text/content.rb', line 64
def @attachments ||= .map do |node| (node) end end
#blank? ⇒ Boolean
#empty? ⇒ Boolean
#gallery_attachments
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 76
def @gallery_attachments ||= .flat_map(&:) end
#inspect
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 198
def inspect "#<#{self.class.name} #{to_html.truncate(25).inspect}>" end
#links
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 54
def links @links ||= fragment.find_all("a[href]").map { |a| a["href"] }.uniq end
#present? ⇒ Boolean
#render_attachment_galleries(&block)
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 108
def (&block) content = ActionText::AttachmentGallery.(fragment) do |node| block.call((node)) end self.class.new(content, canonicalize: false) end
#render_attachments(**options, &block)
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 97
def (**, &block) content = fragment.replace(ActionText::Attachment.tag_name) do |node| if node.key?("content") sanitized_content = (node.remove_attribute("content").to_s) node["content"] = sanitized_content if sanitized_content.present? end block.call((node, **)) end self.class.new(content, canonicalize: false) end
#to_editor_html
#to_html
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 171
def to_html fragment.to_html end
#to_markdown(attachment_links: false)
Returns a Markdown version of the markup contained by the content.
content = ActionText::Content.new("<h1>Funny times!</h1>")
content.to_markdown # => "# Funny times!"
content = ActionText::Content.new("<p>Hello <strong>world</strong></p>")
content.to_markdown # => "Hello **world**"
When attachment_links is true, ::ActiveStorage blob attachments generate Markdown links with
URLs. This requires a rendering context (e.g., controller or mailer action) and will raise if
URL generation fails.
NOTE: The returned string is not HTML safe and should not be rendered in browsers without additional sanitization.
NOTE: Links with unsafe protocols like javascript: are stripped from the returned
Markdown on a best-effort basis. Markdown renderers do not all parse Markdown the same way,
so HTML rendered from the Markdown should not be displayed in browsers without additional
sanitization.
# File 'actiontext/lib/action_text/content.rb', line 153
def to_markdown(attachment_links: false) (with_full_attributes: false) { || ActionText::MarkdownConversion.(, attachment_links: ) }.fragment.to_markdown end
#to_partial_path
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 179
def to_partial_path "action_text/contents/content" end
#to_plain_text
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 # => "safe"
NOTE: that the returned string is not HTML safe and should not be rendered in browsers without additional sanitization.
content = ActionText::Content.new("<script>alert()</script>")
content.to_plain_text # => "<script>alert()</script>"
ActionText::ContentHelper.sanitizer.sanitize(content.to_plain_text) # => ""
# File 'actiontext/lib/action_text/content.rb', line 130
def to_plain_text (with_full_attributes: false, &:to_plain_text).fragment.to_plain_text end
#to_rendered_html_with_layout
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 175
def to_rendered_html_with_layout render layout: "action_text/contents/content", partial: to_partial_path, formats: :html, locals: { content: self } end
#to_s
Safely transforms Content into an HTML String.
content = ActionText::Content.new("<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 190
def to_s to_rendered_html_with_layout end
#to_trix_html
[ GitHub ]# File 'actiontext/lib/action_text/content.rb', line 159
def to_trix_html to_editor_html end