edge
更多信息请访问 rubyonrails.org: 更多 Ruby on Rails

Action Text概述

本指南为您提供了一切所需,以开始处理富文本内容。

阅读本指南后,您将了解:

1 什么是Action Text?

Action Text为Rails带来了富文本内容和编辑功能。它包括Trix编辑器,该编辑器可以处理从格式设置到链接、引用、列表、嵌入图像和图库的所有内容。Trix编辑器生成的富文本内容保存在其自己的RichText模型中,该模型与应用程序中的任何现有Active Record模型相关联。任何嵌入的图像(或其他附件)都会自动使用Active Storage存储,并与包含的RichText模型相关联。

2 Trix与其他富文本编辑器的比较

大多数所见即所得(WYSIWYG)编辑器都是HTML的contenteditableexecCommand API的包装器,由Microsoft设计用于支持在Internet Explorer 5.5中实时编辑网页,并且最终被其他浏览器逆向工程并复制。

由于这些API从未完全指定或记录,并且由于所见即所得HTML编辑器的范围非常广泛,每个浏览器的实现都有自己的一套错误和怪异行为,JavaScript开发人员需要解决这些不一致之处。

Trix通过将contenteditable视为输入/输出设备来避开这些不一致之处:当输入到达编辑器时,Trix将该输入转换为对其内部文档模型的编辑操作,然后将该文档重新呈现到编辑器中。这使得Trix可以完全控制每个按键后发生的情况,并且完全避免使用execCommand。

3 安装

运行bin/rails action_text:install来添加Yarn包并复制必要的迁移文件。此外,您需要为嵌入的图像和其他附件设置Active Storage。请参考Active Storage概述指南。

注意:Action Text使用多态关系与action_text_rich_texts表共享,以便可以与具有富文本属性的所有模型共享。如果使用UUID值作为标识符的模型使用Action Text内容,则所有使用Action Text属性的模型都需要使用UUID值作为其唯一标识符。生成的Action Text迁移还需要更新以指定:record references行的type: :uuid

安装完成后,Rails应用程序应具有以下更改:

  1. 在JavaScript入口点中,应同时引入trix@rails/actiontext

    // application.js
    import "trix"
    import "@rails/actiontext"
    
  2. trix样式表将与Action Text样式一起包含在application.css文件中。

4 创建富文本内容

向现有模型添加富文本字段:

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

或者在创建新模型时添加富文本字段:

$ bin/rails generate model Message content:rich_text

注意:您不需要在messages表中添加content字段。

然后在模型的表单中使用rich_text_area引用该字段:

<%# 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 %>

注意:如果content字段中有附加资源,除非您在本地计算机上安装了libvips/libvips42软件包,否则可能无法正确显示。请查阅他们的安装文档以获取详细信息。

要接受富文本内容,您只需要允许引用的属性:

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

5 渲染富文本内容

默认情况下,Action Text将在具有.trix-content类的元素内呈现富文本内容:

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

具有此类的元素以及Action Text编辑器都受trix样式表的样式控制。如果要提供自己的样式,请从安装程序创建的app/assets/stylesheets/actiontext.css样式表中删除= require trix行。

要自定义富文本内容周围呈现的HTML,请编辑安装程序创建的app/views/layouts/action_text/contents/_content.html.erb布局。

要自定义嵌入图像和其他附件(称为blob)的呈现的HTML,请编辑安装程序创建的app/views/active_storage/blobs/_blob.html.erb模板。

5.1 渲染附件

除了通过Active Storage上传的附件外,Action Text还可以嵌入任何可以由签名的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…

接下来,考虑一些包含引用User实例的签名GlobalID的<action-text-attachment>元素的富文本内容:

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

Action Text使用"BAh7CEkiCG…"字符串来解析User实例。接下来,考虑应用程序的users/user局部视图:

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

Action Text渲染的结果HTML将类似于:

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

要渲染不同的局部视图,请定义User#to_attachable_partial_path

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

然后声明该局部视图。User实例将作为user局部变量可用:

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

如果Action Text无法解析User实例(例如,记录已被删除),则会渲染默认的回退局部视图。

Rails提供了一个用于缺失附件的全局局部视图。该局部视图在应用程序的views/action_text/attachables/missing_attachable中安装,并且可以根据需要进行修改以渲染不同的HTML。

要渲染不同的缺失附件局部视图,请定义一个类级别的to_missing_attachable_partial_path方法:

class User < ApplicationRecord
  def self.to_missing_attachable_partial_path
    "users/missing_attachable"
  end
end

然后声明该局部视图。

<%# app/views/users/missing_attachable.html.erb %>
<span>Deleted user</span>

要与Action Text的<action-text-attachment>元素渲染集成,一个类必须:

  • 包含ActionText::Attachable模块
  • 实现#to_sgid(**options)(通过GlobalID::Identification concern提供)
  • (可选)声明#to_attachable_partial_path
  • (可选)声明一个处理缺失记录的类级别方法#to_missing_attachable_partial_path

默认情况下,所有的ActiveRecord::Base子类都混入了GlobalID::Identification concern,因此与ActionText::Attachable兼容。

6 避免N+1查询

如果您希望预加载相关的ActionText::RichText模型,假设您的富文本字段名为content,您可以使用命名作用域:

Message.all.with_rich_text_content # 预加载正文,不包括附件。
Message.all.with_rich_text_content_and_embeds # 预加载正文和附件。

7 API / 后端开发

  1. 后端API(例如,使用JSON)需要一个单独的端点来上传文件,创建一个ActiveStorage::Blob并返回其attachable_sgid

    {
      "attachable_sgid": "BAh7CEkiCG…"
    }
    
  2. 使用<action-text-attachment>标签将attachable_sgid插入富文本内容中,要求前端执行此操作:

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

这是基于Basecamp的,所以如果您仍然找不到您要找的内容,请查看此Basecamp文档

反馈

欢迎您帮助改进本指南的质量。

如果您发现任何拼写错误或事实错误,请贡献您的意见。 要开始,请阅读我们的 文档贡献 部分。

您还可能会发现不完整的内容或过时的内容。 请为主要内容添加任何缺失的文档。请先检查 Edge 指南,以验证问题是否已经修复或尚未修复。 请参阅 Ruby on Rails 指南准则 以了解样式和规范。

如果您发现需要修复但无法自行修复的问题,请 提交问题

最后但同样重要的是,欢迎您在 官方 Ruby on Rails 论坛 上讨论有关 Ruby on Rails 文档的任何问题。