18

What is the best way to configure ActionText to add buttons to the toolbar. For example, an h2 and h3 button?

Will
  • 4,498
  • 2
  • 38
  • 65

3 Answers3

23

I couldn't find any documentation about the 'correct' way to do this, but the following works:

I've made these modifications to my /app/javascript/application.js file, where ActiveText had placed the require statements for trix and actiontext.

First I got the Trix instance by returning the require into a Variable.

var Trix  = require("trix")
console.log("Config", Trix.config);

Then I specify the extra items I want Trix to recognise:

Trix.config.blockAttributes.heading2 = {
  tagName: 'h2'
}
Trix.config.blockAttributes.heading3 = {
  tagName: 'h3'
}
Trix.config.textAttributes.underline = {
  tagName: 'u'
}

And then I rebuilt the toolbar by just pasting in Trix's code and modifying the html, which is verbose, but simple to understand:

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="underline" title="h3" tabindex="-1">u</button>
    <button type="button" class="trix-button trix-button--icon trix-button--icon-link" data-trix-attribute="href" data-trix-action="link" data-trix-key="k" title="${lang.link}" tabindex="-1">${lang.link}</button>
  </span>
  <span class="trix-button-group trix-button-group--block-tools" data-trix-button-group="block-tools">
    <button type="button" class="trix-button  " data-trix-attribute="heading1" title="h1" tabindex="-1">h1</button>
    <button type="button" class="trix-button  " data-trix-attribute="heading2" title="h2" tabindex="-1">h2</button>
    <button type="button" class="trix-button  " data-trix-attribute="heading3" title="h3" tabindex="-1">h3</button>
    <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>\
`; }
};

This is taken (and decafinated) from https://github.com/basecamp/trix/blob/master/src/trix/config/toolbar.coffee

Will
  • 4,498
  • 2
  • 38
  • 65
  • 3
    not sure whats changed but i can no longer get my answer to work. – Will Jan 20 '22 at 14:50
  • 1
    Your answer is great, but in v2 version of Trix the `toolbar` object cannot be overwritten (it is read only). You need to change only the `getDefaultHTML` property of `toolbar` object to make it work, e.g. `Trix.config.toolbar.getDefaultHTML = () => ...` – Krzysztof Grabania Apr 20 '23 at 09:58
22

To add to Will's answer, you can avoid recreating the whole toolbar by using trix after initialize callback :

example, adding a 'Red' button that turns the text red :

var Trix = require("trix");

/* what the newly created button does */
Trix.config.textAttributes.red = {
    style: { color: "red" },
    parser: function(element) {
        return element.style.color === "red"
    },
    inheritable: true
}

/* insert the button visual in the default toolbar */
addEventListener("trix-initialize", function(event) {
    var buttonHTML = '<button type="button" data-trix-attribute="red">RED</button>'

    event.target.toolbarElement.
    querySelector(".trix-button-group").
    insertAdjacentHTML("beforeend", buttonHTML)
})

output:

enter image description here

Alexis Delahaye
  • 644
  • 5
  • 18
1

I tried all of these answers but couldn't get it working. Trix would add the buttons, the h2 would be added correctly, when you saved everything looked good — but when you loaded the content back into the editor the h2 was stripped.

What eventually worked (on trix 2.0 beta) was downloading the entire repo and:

  1. Add h2's to block_attributes (https://github.com/basecamp/trix/blob/main/src/trix/config/block_attributes.coffee#L8)
  2. Add h2's to lang (not strictly necessary, https://github.com/basecamp/trix/blob/main/src/trix/config/lang.coffee)
  3. Add additional h2 button to toolbar https://github.com/basecamp/trix/blob/main/src/trix/config/toolbar.coffee

Once I modified those three files, I re-built trix, and copied the JS/CSS files into my application — and everything worked beautifully!

bradjasper
  • 83
  • 1
  • 6
  • 1
    wow good effort. its going to be hard to maintain though that way – Will May 03 '22 at 16:33
  • 1
    I ended up using a trix controller and inserting the button: https://www.kindleman.com.au/blog/advanced-actiontext-modifications-for-cms-use/ – Will May 03 '22 at 16:36
  • 2
    This happens because Trix initialises before the config is changed. When you load existing HTML into the editor, the old parsers revert to their defaults. You can get around this by changing the config in the head of the html, as the script will run synchronously. `` – J R Jul 27 '22 at 17:15