1 Action Text 是什麼?
Action Text 為 Rails 帶來了豐富的文字內容和編輯功能。這包括 Trix 編輯器 處理從格式設定的所有內容 到引用的連結到嵌入影象和畫廊的列表。 Trix編輯器生成的富文字內容儲存在自己的 與應用程式中任何現有 Active Record model 相關聯的 RichText model。 任何嵌入的影象(或其他附件)都會使用 Active Storage 並與包含的 RichText model 相關聯。
2 Trix 與其他富文字編輯器的對比
大多數 WYSIWYG 編輯器都是 HTML 的 contenteditable
和 execCommand
API 的包裝器,
由 Microsoft 設計,支援在 Internet Explorer 5.5 中實時編輯網頁,
和 最終逆向工程
並被其他瀏覽器複製。
因為這些 API 從未被完全指定或記錄, 並且由於 WYSIWYG HTML 編輯器的範圍很大,每個 瀏覽器的實現有它自己的一套錯誤和怪癖, JavaScript 開發人員需要解決不一致的問題。
Trix 透過處理 contenteditable 來避免這些不一致 作為 I/O 裝置:當輸入進入編輯器時,Trix 轉換該輸入 對其內部文件model進行編輯操作,然後重新渲染 將該檔案放回編輯器中。這讓 Trix 可以完全控制什麼 在每個 keystroke 之後發生,並且根本不需要使用 execCommand。
3 安裝
執行 bin/rails action_text:install
以新增 Yarn 包並複製必要的 migration。此外,您需要為嵌入的影象和其他附件設定 Active Storage。請參閱 Active Storage Overview 指南。
ActionText 使用與 action_text_rich_texts
表的多型關係,以便它可以與所有具有富文字屬性的 models 共享。如果帶有 ActionText 內容的 models 使用 UUID values 作為識別符號,則所有使用 ActionText 屬性的 models 都需要使用 UUID values 作為其唯一識別符號。為 ActionText 生成的 migration 也需要更新以指定 :record
references
行的 type: :uuid
。
安裝完成後,Rails 應用程式應該有以下變化:
-
在您的 JavaScript 入口點中應該同時需要
trix
和@rails/actiontext
。// application.js import "trix" import "@rails/actiontext"
trix
樣式表將與 Action Text 樣式一起包含在您的application.css
檔案中。
4 建立富文字內容
向現有的 model 新增富文字欄位:
# app/models/message.rb
class Message < ApplicationRecord
has_rich_text :content
end
或者在使用以下方法建立新的 model 時新增富文字欄位:
bin/rails generate model Message content:rich_text
NOTE: 您不需要向 messages
表中新增 content
欄位。
然後使用 rich_text_area
在表單中為 model 引用此欄位:
<%# 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
行省略 [內容
檔案](https://raw.githubusercontent.com/basecamp/trix/master/dist/trix.css)。
預設情況下,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
model:
# 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>
的富文字內容
引用 User
實例的簽名 GlobalID 的元素:
<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 <action-text-attachment>
元素渲染整合,一個
班級必須:
- 包括
ActionText::Attachable
module - 實現
#to_sgid(**options)
(透過 [GlobalID::Identification
關注點][global-id] 提供) *(可選)宣告#to_attachable_partial_path
預設情況下,所有 ActiveRecord::Base
後代混入
[GlobalID::Identification
關注][global-id],因此
ActionText::Attachable
相容。
6 避免 N+1 查詢
如果您希望預載入依賴的 ActionText::RichText
model,假設您的富文字欄位名為 content
,您可以使用命名範圍:
Message.all.with_rich_text_content # Preload the body without attachments.
Message.all.with_rich_text_content_and_embeds # Preload both body and attachments.
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 Doc](https://github.com/basecamp/bc3-api/blob/master/sections/rich_text.md )。
回饋
我們鼓勵您幫助提高本指南的品質。
如果您發現任何拼寫錯誤或資訊錯誤,請提供回饋。 要開始回饋,您可以閱讀我們的 回饋 部分。
您還可能會發現不完整的內容或不是最新的內容。 請務必為 main 新增任何遺漏的文件。假設是 非穩定版指南(edge guides) 請先驗證問題是否已經在主分支上解決。 請前往 Ruby on Rails 指南寫作準則 查看寫作風格和慣例。
如果由於某種原因您發現要修復的內容但無法自行修補,請您 提出 issue。
關於 Ruby on Rails 的任何類型的討論歡迎提供任何文件至 rubyonrails-docs 討論區。