Skip to content

Customizing the Richtext Editor ​

Alchemy uses TinyMCE as the richtext editor for Richtext ingredients. You can customize the toolbar, add plugins, apply custom stylesheets, and configure each editor instance independently.

Default Configuration ​

Alchemy ships with a sensible default configuration:

ruby
{
  skin: "alchemy",
  width: "auto",
  resize: true,
  min_height: 250,
  menubar: false,
  statusbar: true,
  toolbar: [
    "bold italic underline | strikethrough subscript superscript | numlist bullist indent outdent | removeformat | fullscreen",
    "pastetext charmap hr | undo redo | alchemy_link unlink anchor | code"
  ],
  fix_list_elements: true,
  convert_urls: false,
  entity_encoding: "raw",
  paste_as_text: true
}

NOTE

Default plugins: alchemy_link, anchor, charmap, code, directionality, fullscreen, link, lists.

Global Customization ​

To change TinyMCE settings for all richtext editors in your application, set Alchemy::Tinymce.init in an initializer. Your settings are merged with the defaults, so you only need to specify what you want to override.

ruby
# config/initializers/alchemy.rb
Alchemy::Tinymce.init = {
  toolbar: [
    "bold italic underline | numlist bullist | removeformat | fullscreen",
    "pastetext | undo redo | alchemy_link unlink | code"
  ]
}

NOTE

Global settings apply to all richtext editors in all elements. Use per-ingredient settings to customize individual editors.

Per-Ingredient Customization ​

You can override TinyMCE settings for individual Richtext ingredients in config/alchemy/elements.yml using the tinymce setting:

yaml
# config/alchemy/elements.yml
- name: article
  ingredients:
    - role: text
      type: Richtext
      settings:
        tinymce:
          toolbar:
            - "bold italic underline | removeformat"
            - "pastetext | undo redo | alchemy_link unlink | code"

Per-ingredient settings are merged with the global configuration, so you only need to specify the options you want to change for that specific editor.

Adding Style Formats ​

Give editors a dropdown to apply predefined styles:

yaml
- name: text
  type: Richtext
  settings:
    tinymce:
      toolbar:
        - "bold italic underline | styleselect | removeformat | fullscreen"
        - "pastetext | undo redo | alchemy_link unlink | code"
      style_formats:
        - title: "Subheadline"
          block: "h3"
        - title: "Quote"
          block: "blockquote"
        - title: "Small"
          inline: "small"

TIP

Keep your style formats minimal. Alchemy's strength is structured content with separate elements for different content types. Resist the temptation to turn a single richtext field into a full page editor.

Toolbar Buttons ​

The toolbar is defined as an array of strings. Each string is one toolbar row. Buttons are separated by spaces, groups are separated by |.

Common buttons:

ButtonDescription
bold italic underline strikethroughText formatting
subscript superscriptSub/superscript
numlist bullistOrdered and unordered lists
indent outdentIndentation
removeformatClear formatting
pastetextPaste as plain text
alchemy_link unlinkAlchemy's link dialog
anchorInsert anchor
charmapSpecial characters
codeView/edit HTML source
fullscreenToggle fullscreen editing
hrHorizontal rule
formatselectBlock format dropdown
styleselectStyle format dropdown

TIP

See the TinyMCE toolbar documentation for all available buttons.

Adding Plugins ​

TinyMCE can be extended with community and premium plugins. Download the plugin and place it in vendor/assets/javascripts/tinymce/plugins/ inside your app.

Then append it to Alchemy::Tinymce.plugins and add its buttons to the toolbar:

ruby
# config/initializers/alchemy.rb
Alchemy::Tinymce.plugins += ["table"]
Alchemy::Tinymce.init = {
  toolbar: [
    "bold italic underline | numlist bullist | removeformat | fullscreen",
    "pastetext | undo redo | alchemy_link unlink | table | code"
  ]
}

NOTE

Plugins added to Alchemy::Tinymce.plugins beyond the built-in set are automatically preloaded in the admin interface.

Custom Stylesheet ​

You can apply a stylesheet to the TinyMCE editor area so the editing experience matches your site's typography:

ruby
# config/initializers/alchemy.rb
Alchemy::Tinymce.init = {
  content_css: "/assets/tinymce_content.css"
}

Create the stylesheet at app/assets/stylesheets/tinymce_content.css. This file is loaded inside the editor's iframe and controls how text appears while editing.

NOTE

Alchemy automatically switches between a light (alchemy) and dark (alchemy-dark) editor skin based on the user's OS preference. Setting a custom content_css overrides the built-in dark mode content stylesheet, so make sure your stylesheet works in both modes if your editors use dark mode.

HTML Sanitization ​

A Richtext ingredient is a trusted-content field: by default its value is rendered as-is, so whatever markup is saved ends up unescaped in the page.

To restrict what gets rendered, configure a sanitizer: setting on the ingredient. When it is present, Alchemy sanitizes the value at render time with Rails' SafeListSanitizer, keeping only the tags and attributes you list:

yaml
- name: text
  type: Richtext
  settings:
    sanitizer:
      tags:
        - p
        - strong
        - em
        - a
        - ul
        - ol
        - li
        - h2
        - h3
      attributes:
        - href
        - target
        - class

WARNING

Without a sanitizer: setting the value is rendered unescaped. Configure a sanitizer: on every Richtext ingredient and allow only the tags and attributes that element actually needs.

Configuration Syntax ​

Any TinyMCE configuration option can be used. When setting options in Ruby (initializer), convert JavaScript syntax to Ruby hashes:

js
// JavaScript
{
  block_formats: "Paragraph=p;Header 2=h2;Header 3=h3"
}
ruby
# Ruby
{
  block_formats: "Paragraph=p;Header 2=h2;Header 3=h3"
}

When setting options in YAML (elements.yml), use standard YAML syntax:

yaml
settings:
  tinymce:
    block_formats: "Paragraph=p;Header 2=h2;Header 3=h3"
    style_formats:
      - title: "Highlight"
        inline: "span"
        classes: "highlight"

TIP

Use YAML anchors to share TinyMCE configurations across multiple elements:

yaml
# config/alchemy/elements.yml
- name: article
  ingredients:
    - role: text
      type: Richtext
      settings:
        tinymce: &minimal_tinymce
          toolbar:
            - "bold italic underline | alchemy_link unlink | code"

- name: news
  ingredients:
    - role: body
      type: Richtext
      settings:
        tinymce: *minimal_tinymce

BSD-3 Licensed · Hosting sponsored by netlify