Обзор Action Text

Это руководство предоставляет вам все, что нужно, чтобы начать обрабатывать содержимое обогащенного текста.

После прочтения этого руководства, вы узнаете:

  • Как настроить Action Text.
  • Как обрабатывать содержимое обогащенного текста.
  • Как стилизовать содержимое и вложения обогащенного текста.

1. Что такое Action Text?

Action Text вносит возможность хранения и редактирования обогащенного текста в Rails. Он включает редактор Trix, обрабатывающий все, от форматирования до ссылок, до цитат, до списков, до встроенных изображений и галерей. Обогащенный текст, созданный редактором Trix, сохраняется в собственной модели RichText, связанной с любой существующей моделью Active Record приложения. Любые встроенные изображения (или другие вложения) автоматически сохраняются с помощью Active Storage и связываются с включающей моделью RichText.

2. Trix в сравнении с другими редакторами обогащенного текста

Большинство редакторов WYSIWYG являются обертками для contenteditable и execCommand HTML API, разработанным Microsoft для поддержки живого редактирования веб страниц в Internet Explorer 5.5, и случайно обратно разработанного и скопированного другими браузерами.

Так как эти API никогда не были полностью определены или документированы, и так как редакторы WYSIWYG HTML охватывают слишком многое, в реализации для каждого браузера есть свой набор ошибок и странностей, и разработчики JavaScript оставлены наедине разбираться с этими неудобствами.

Trix уклоняется от этих неудобств, рассматривая contenteditable как устройство ввода/вывода: когда происходит ввод в редактор, Trix конвертирует этот ввод в операцию редактирования в своей внутренней модели документа, и затем перерисовывает этот документ в редакторе. Это предоставляет Trix полный контроль над тем, что происходит после каждого нажатия клавиш, и помогает избегать необходимости использовать execCommand вообще.

3. Установка

Запустите bin/rails action_text:install для добавления пакета Yarn и копирования необходимой миграции. Также нужно настроить Active Storage для встроенных изображений и других вложений. Обратитесь к руководству Обзор Active Storage guide.

После завершения установки, для приложения Rails, использующего Webpacker, следует выполнить следующие изменения:

  • trix и @rails/actiontext должны быть затребованы в пакете JavaScript.

    // application.js
    require("trix")
    require("@rails/actiontext")
    
  • Таблица стилей trix должна быть импортирована в actiontext.scss.

    @import "trix/dist/trix";
    

    Кроме этого, файл actiontext.scss должен быть импортирован в пакет таблиц стилей.

    // application.scss
    @import "./actiontext.scss";
    

4. Создание содержимого обогащенного текста

Добавьте поле обогащенного текста в существующую модель:

# app/models/message.rb
class Message < ApplicationRecord
  has_rich_text :content
end

Note: не нужно добавлять поле content в таблице messages.

Затем обратитесь к этому полю в форме для модели:

<%# app/views/messages/_form.html.erb %>
<%= form_with model: message do |form| %>
  <div class="field">
    <%= form.label :content %>
    <%= form.rich_text_area :content %>
  </div>
<% end %>

И, наконец, отобразите очищенный обогащенный текст на странице:

<%= @message.content %>

Чтобы принимать содержимое обогащенного текста, все, что нужно, это разрешить указанный атрибут:

class MessagesController < ApplicationController
  def create
    message = Message.create! params.require(:message).permit(:title, :content)
    redirect_to message
  end
end

5. Отображение содержимого обогащенного текста

Action Text очистит и отобразит обогащенное содержимое для вас.

По умолчанию редактор и содержимое Action Text стилизовано значениями по умолчанию Trix.

Если хотите изменить эти значения по умолчанию, уберите строчку // require "actiontext.scss" из вашего application.scss чтобы не включать содержимое этого файла.

По умолчанию Action Text отобразит содержимое обогащенного текста в элемент с классом .trix-content:

<%# app/views/layouts/action_text/contents/_content.html.erb %>
<div class="trix-content">
  <%= yield %>
</div>

Если хотите изменить HTML, окружающий содержимое обогащенного текста, на свой макет, объявите собственный шаблон app/views/layouts/action_text/contents/_content.html.erb и вызовите yield в месте содержимого.

Также можно стилизовать HTML, используемый для встроенных картинок и других вложений (известных как бинарные объекты). При установке Action Text скопирует партиал в app/views/active_storage/blobs/_blob.html.erb, который можно адаптировать.

5.1. Отрисовка вложений

В дополнение к вложениям, загруженным с помощью Active Storage, Action Text может встроить все, что может быть найдено по Signed GlobalID.

Action Text отрисовывает вложенные элементы <action-text-attachment>, преобразуя их атрибут sgid в экземпляр. Будучи найденным, этот экземпляр передается в render. Результирующий HTML вкладывается как потомок в элемент <action-text-attachment>.

Например, рассмотрим модель User:

# app/models/user.rb
class User < ApplicationRecord
  has_one_attached :avatar
end

user = User.find(1)
user.to_global_id.to_s #=> gid://MyRailsApp/User/1
user.to_signed_global_id.to_s #=> BAh7CEkiCG…

Затем, рассмотрим некоторое содержимое обогащенного текста, в которое вложен элемент <action-text-attachment>, ссылающийся на подписанный GlobalID экземпляра User:

<p>Hello, <action-text-attachment sgid="BAh7CEkiCG…"></action-text-content>.</p>

Action Text преобразует, используя строку "BAh7CEkiCG…", чтобы найти экземпляр User. Далее, рассмотрим партиал приложения users/user:

<%# app/views/users/_user.html.erb %>
<span><%= image_tag user.avatar %> <%= user.name %></span>

Результирующий HTML, отрисованный Action Text, будет выглядеть наподобие:

<p>Hello, <action-text-attachment sgid="BAh7CEkiCG…"><span><img src="..."> Jane Doe</span></action-text-content>.</p>

Чтобы отобразить другой партиал, определите User#to_attachable_partial_path:

class User < ApplicationRecord
  def to_attachable_partial_path
    "users/attachable"
  end
end

Затем объявите этот партиал. Экземпляр User будет доступен как локальная для партиала переменная:

<%# app/views/users/_attachable.html.erb %>
<span><%= image_tag user.avatar %> <%= user.name %></span>

Для интеграции с отображением Action Text <action-text-attachment> класс должен:

  • включать модуль ActionText::Attachable
  • реализовывать #to_sgid(**options) (доступно в GlobalID::Identification)
  • (опционально) объявить #to_attachable_partial_path

По умолчанию, все потомки ActiveRecord::Base включают GlobalID::Identification, и, следовательно, совместимы с ActionText::Attachable.

6. Избегание N+1 запроса

Если хотите предварительно загрузить зависимую модель ActionText::RichText, если допустить, что поле обогащенного текста названо content, можно использовать именованный скоуп:

Message.all.with_rich_text_content # Загружает тело без вложений.
Message.all.with_rich_text_content_and_embeds # Загружает тело и вложения.

7. Разработка API / Бэкенд

  • В API бэкенда (например, использующий JSON) необходим отдельный адрес для загрузки файлов, создающий ActiveStorage::Blob и возвращающий его attachable_sgid:

    {
      "attachable_sgid": "BAh7CEkiCG…"
    }
    
  • Возьмите этот attachable_sgid и сообщите своему фронтенду вставить его в содержимое обогащенного текста с помощью тега <action-text-attachment>:

    <action-text-attachment sgid="BAh7CEkiCG…"></action-text-attachment>
    

Это основано на подходе Basecamp, поэтому, если не понимаете, что вам нужно, проверьте документацию Basecamp.