How to Modify & Customize ActionText HTML Output in Rails Discussion
This was so helpful.
I was able to override the default actiontext HTML templates after viewing this. My current codebase's ActionText install does not have any editable ERB files in /views/, and I couldn't figure out a way to get an installer to generate them.
I made this initializer and custom ERB templates, and it works for me! I can now point ActionText to load inside a custom div (in my case, one without the trix-content
CSS class.)
Thanks x 1,000 Chris.
# config/initializers/action_text.rb
module ActionTextLoadCustomPartial
def to_rendered_html_with_layout
# this points to app/views/layouts/custom_action_text/contents/_content.html.erb:
render layout: "/custom_action_text/contents/content", partial: to_partial_path, formats: :html, locals: { content: self }
end
def to_partial_path
# this points to app/views/custom_action_text/contents/_content.html.erb:
"/custom_action_text/contents/content"
end
end
ActiveSupport.on_load :action_text_content do
self.prepend ActionTextLoadCustomPartial
end
Here's the layout file:
<div class="rich-text-content-layout">
<%= yield -%>
</div>
IMPORTANT: Here's the partial file:
<div class="rich-text-content">
<%= render_action_text_content(content) %>
</div>
That render_action_text_content(content)
is necessary to output the rich text, I assume b/c it's defined in locals: {}
above in the layout call. I found that poking around in https://github.com/rails/rails/tree/main/actiontext
I’m pretty sure this causes an infinite loop if you need to convert a model column into a rich_text field and do something like model.update/update_attribute(content: model.old_content)
. I’ve never seen such a bad loop — I actually had to kill my PostgreSQL process.
ActionText::ContentHelper.allowed_attributes dont seem to be working in Rails 7.1 due to some changes to the sanitizer
ActionText::ContentHelper.sanitizer.class.allowed_tags += %w[iframe script blockquote time]
ActionText::ContentHelper.sanitizer.class.allowed_attributes += ["data-id", "data-flickr-embed", "target"]
Thanks, that worked. I added this test to my project to verify and handle any future changes
require "test_helper"
class ActionTextCustomizationTest < ActiveSupport::TestCase
test 'action text links should have rel="noopener noreferrer" and target="_blank"' do
text = ActionText::RichText.new(
body: "<a href='https://example.com'>Example</a>"
)
assert_includes text.to_s, "rel=\"noopener noreferrer\""
assert_includes text.to_s, "target=\"_blank\""
end
end
Switching config.load_defaults
to 7.1
switches from Rails::HTML4::SafeListSanitizer to the new Rails::HTML5::SafeListSanitizer which doesn't seem to pickup these changes in the initializer
Can move the code to config.after_initialize
or inside ActiveSupport.on_load(:action_text_content)