Class: ActionText::Content
  
  
  
Overview
  
    
# 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 body.to_s body.to_plain_text 
   
 
  
  Instance Attribute Summary collapse
  
  
    
      Class Method Summary
      collapse
    
    
  
    
      Instance Method Summary
      collapse
    
    
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  #append_features, #class_methods, extended, #included, #prepend_features, #prepended
  
  
  
  
  
  
  
  
  
  #_dump
  
  
  
  
  
  
  
  
  
  #render_action_text_attachment, #render_action_text_attachments, #render_action_text_content, #sanitize_action_text_content, #sanitize_content_attachment, #sanitizer_allowed_attributes, #sanitizer_allowed_tags
  Constructor Details
  
    
  
  
    #initialize(content = nil, options = {})  ⇒ Content 
  
  
  
  
    | 
40
41
42
43
44
45
46
47
48 | # 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 | 
 
  
 
  
    Instance Attribute Details
    
      
      
      
  
  
    
Returns the value of attribute fragment.
   
 
  
  
    | 
27
28
29 | # File 'actiontext/lib/action_text/content.rb', line 27
def fragment
  @fragment
end | 
 
    
   
  
    Class Method Details
    
      
  
  
    .fragment_by_canonicalizing_content(content)  ⇒ Object 
  
  
  
 
    
   
  
    Instance Method Details
    
      
  
  
    #==(other)  ⇒ Object 
  
  
  
  
    | 
169
170
171
172
173
174
175 | # 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 | 
 
    
      
  
  
    #append_attachables(attachables)  ⇒ Object 
  
  
  
  
    | 
93
94
95
96 | # 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 | 
 
    
      
  
  
    | 
161
162
163 | # File 'actiontext/lib/action_text/content.rb', line 161
def as_json(*)
  to_html
end | 
 
    
      
  
  
    #attachables  ⇒ Object 
  
  
  
  
    
Extracts ActionText::Attachables 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 
   
 
  
  
    | 
87
88
89
90
91 | # File 'actiontext/lib/action_text/content.rb', line 87
def attachables
  @attachables ||= attachment_nodes.map do |node|
    ActionText::Attachable.from_node(node)
  end
end | 
 
    
      
  
  
    #attachment_galleries  ⇒ Object 
  
  
  
  
    | 
71
72
73
74
75 | # 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 | 
 
    
      
  
  
    #attachments  ⇒ Object 
  
  
  
  
    
Extracts ActionText::Attachments 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 
   
 
  
  
    | 
65
66
67
68
69 | # File 'actiontext/lib/action_text/content.rb', line 65
def attachments
  @attachments ||= attachment_nodes.map do |node|
    attachment_for_node(node)
  end
end | 
 
    
      
  
  
    #gallery_attachments  ⇒ Object 
  
  
  
  
    | 
77
78
79 | # File 'actiontext/lib/action_text/content.rb', line 77
def gallery_attachments
  @gallery_attachments ||= attachment_galleries.flat_map(&:attachments)
end | 
 
    
      
  
  
    | 
165
166
167 | # 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 
   
 
  
  
    | 
55
56
57 | # File 'actiontext/lib/action_text/content.rb', line 55
def links
  @links ||= fragment.find_all("a[href]").map { |a| a["href"] }.uniq
end | 
 
    
      
  
  
    #render_attachment_galleries(&block)  ⇒ Object 
  
  
  
 
    
      
  
  
    #render_attachments(**options, &block)  ⇒ Object 
  
  
  
  
    | 
98
99
100
101
102
103
104
105
106
107 | # 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 | 
 
    
      
  
  
    | 
138
139
140 | # File 'actiontext/lib/action_text/content.rb', line 138
def to_html
  fragment.to_html
end | 
 
    
      
  
  
    #to_partial_path  ⇒ Object 
  
  
  
  
    | 
146
147
148 | # File 'actiontext/lib/action_text/content.rb', line 146
def to_partial_path
  "action_text/contents/content"
end | 
 
    
      
  
  
    #to_plain_text  ⇒ Object 
  
  
  
  
    
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 
content = ActionText::Content.new("<div onclick='action()'>safe<script>unsafe</script></div>")
content.to_plain_text 
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 
   
 
  
  
    | 
130
131
132 | # 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 | 
 
    
      
  
  
    #to_rendered_html_with_layout  ⇒ Object 
  
  
  
  
    | 
142
143
144 | # 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 
content = ActionText::Content.new("<div onclick='action()'>safe<script>unsafe</script></div>")
content.to_s 
   
 
  
  
    | 
157
158
159 | # File 'actiontext/lib/action_text/content.rb', line 157
def to_s
  to_rendered_html_with_layout
end | 
 
    
      
  
  
    #to_trix_html  ⇒ Object 
  
  
  
  
    | 
134
135
136 | # File 'actiontext/lib/action_text/content.rb', line 134
def to_trix_html
  render_attachments(&:to_trix_attachment).to_html
end |