Let's say I want to add a button that toggles red colored text on and off.
I've done the basic action_text setup as described on rubyonrails.org, however, I made the following change to my application.js file in order to add a button called RED to the toolbar and style it appropriately:
// app/javascript/packs/application.js
var Trix = require("trix")
require("@rails/actiontext")
const {lang} = Trix.config;
Trix.config.toolbar = {
getDefaultHTML() { return `\
<div class="trix-button-row">
<span class="trix-button-group trix-button-group--text-tools" data-trix-button-group="text-tools">
<button type="button" class="trix-button trix-button--icon trix-button--icon-bold" data-trix-attribute="bold" data-trix-key="b" title="${lang.bold}" tabindex="-1">${lang.bold}</button>
<button type="button" class="trix-button trix-button--icon trix-button--icon-italic" data-trix-attribute="italic" data-trix-key="i" title="${lang.italic}" tabindex="-1">${lang.italic}</button>
<button type="button" class="trix-button trix-button--icon trix-button--icon-strike" data-trix-attribute="strike" title="${lang.strike}" tabindex="-1">${lang.strike}</button>
<button type="button" class="trix-button" data-trix-attribute="red">RED</button>
</span>
<span class="trix-button-group trix-button-group--block-tools" data-trix-button-group="block-tools">
<button type="button" class="trix-button trix-button--icon trix-button--icon-quote" data-trix-attribute="quote" title="${lang.quote}" tabindex="-1">${lang.quote}</button>
<button type="button" class="trix-button trix-button--icon trix-button--icon-code" data-trix-attribute="code" title="${lang.code}" tabindex="-1">${lang.code}</button>
<button type="button" class="trix-button trix-button--icon trix-button--icon-bullet-list" data-trix-attribute="bullet" title="${lang.bullets}" tabindex="-1">${lang.bullets}</button>
<button type="button" class="trix-button trix-button--icon trix-button--icon-number-list" data-trix-attribute="number" title="${lang.numbers}" tabindex="-1">${lang.numbers}</button>
<button type="button" class="trix-button trix-button--icon trix-button--icon-decrease-nesting-level" data-trix-action="decreaseNestingLevel" title="${lang.outdent}" tabindex="-1">${lang.outdent}</button>
<button type="button" class="trix-button trix-button--icon trix-button--icon-increase-nesting-level" data-trix-action="increaseNestingLevel" title="${lang.indent}" tabindex="-1">${lang.indent}</button>
</span>
<span class="trix-button-group trix-button-group--file-tools" data-trix-button-group="file-tools">
<button type="button" class="trix-button trix-button--icon trix-button--icon-attach" data-trix-action="attachFiles" title="${lang.attachFiles}" tabindex="-1">${lang.attachFiles}</button>
</span>
<span class="trix-button-group-spacer"></span>
<span class="trix-button-group trix-button-group--history-tools" data-trix-button-group="history-tools">
<button type="button" class="trix-button trix-button--icon trix-button--icon-undo" data-trix-action="undo" data-trix-key="z" title="${lang.undo}" tabindex="-1">${lang.undo}</button>
<button type="button" class="trix-button trix-button--icon trix-button--icon-redo" data-trix-action="redo" data-trix-key="shift+z" title="${lang.redo}" tabindex="-1">${lang.redo}</button>
</span>
</div>
<div class="trix-dialogs" data-trix-dialogs>
<div class="trix-dialog trix-dialog--link" data-trix-dialog="href" data-trix-dialog-attribute="href">
<div class="trix-dialog__link-fields">
<input type="url" name="href" class="trix-input trix-input--dialog" placeholder="${lang.urlPlaceholder}" aria-label="${lang.url}" required data-trix-input>
<div class="trix-button-group">
<input type="button" class="trix-button trix-button--dialog" value="${lang.link}" data-trix-method="setAttribute">
<input type="button" class="trix-button trix-button--dialog" value="${lang.unlink}" data-trix-method="removeAttribute">
</div>
</div>
</div>
</div>\
`; }
};
Trix.config.textAttributes.red = {
style: { color: "red" },
parser: function(element){
return element.style.color === "red"
}
}
At this point, the red styling will work as expected when creating or updating the form content, but the red styling stops working when I try to display the content outside of a form - in other words, <%= form.rich_text_area :content %>
will correctly show red text, but <%= @message.content %>
will not.
I did some research and noticed that action_text seems to scrub style
attributes out of rendered HTML by default in ActionText::ContentHelper
. I've tried whitelisting the style attribute and have succeeded but only by putting the following into a config/initializers file:
# config/initializers/action_text_config.rb
ActionText::ContentHelper.allowed_attributes << "style"
module ActionText
class Content
end
end
My questions are:
- Is there a better way to do this?
- If I try to manually debug by placing
<%= ActionText::ContentHelper.allowed_attributes.inspect %>
inside my view, why do I not find thestyle
attribute that I added in my initializers file (even though<%= @message.content %>
now correctly displays)? - Why does rails want this weird empty module and class definition in my initializers file in order to make this work? Apparently it does something, because when I comment it out, the red text stops working in
<%= @message.content %>
.
I'm clearly missing something and would appreciate any help on this.
I'm using ruby 2.7.1, rails 6.0.3.2, and trix 1.2.3