[Rails] Action Text Overview
keywords:action text
Action Text @ Edge RailsGuides
安裝
$ rails action_text:install
使用
Model
# app/models/message.rb
class Message < ApplicationRecord
has_rich_text :content
end
Controller
class MessagesController < ApplicationController
def create
message = Message.create! params.require(:message).permit(:title, :content)
redirect_to message
end
end
View
<%# 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 %>
<%# app/views/messages/show.html.erb %>
<%= @message.content %>
客製化
新增一顆 h2 的按鈕
建立一支 trix_init.js
:
// ./app/javascript/packs/trix_init.js
const trixInit = (e) => {
const trix = e.target;
addSubHeadingButton(trix);
return;
};
function addSubHeadingButton(trix) {
const toolBar = trix.toolbarElement;
// Creation of the sub-heading button
const subHeadingButton = document.createElement('button');
subHeadingButton.innerText = 'h2';
setAttributes(subHeadingButton, {
type: 'button',
class: 'trix-button trix-button--icon trix-button--icon-heading-2',
title: 'subHeading',
tabindex: '-1',
'data-trix-attribute': 'subHeading',
});
// Attachment of the sub-heading button to the toolBar
const headingButton = toolBar.querySelector('[data-trix-attribute="heading1"]');
headingButton.insertAdjacentElement('afterend', subHeadingButton);
// When the sub-heading button is clicked
subHeadingButton.addEventListener('click', () => {
if (trix.editor.attributeIsActive('subHeading')) {
headingButton.setAttribute('disabled', '');
} else {
headingButton.removeAttribute('disabled');
}
});
}
function setAttributes(element, attributes) {
if (!element || !attributes) {
console.warn('Element or attributes is not existed in setAttributes function');
return;
}
Object.entries(attributes).forEach(([key, value]) => {
element.setAttribute(key, value);
});
}
module.exports = trixInit;
接著在 application.js
中去載入 trix_init.js
這支檔案:
// app/javascript/packs/application.js
require('@rails/actiontext');
const Trix = require('trix');
const trixInit = require('./trix_init.js');
// 告訴 Trix 當 attribute 是 subHeading 時,要產生 <h2> 的標籤
Trix.config.textAttributes.subHeading = {
inheritable: true,
tagName: 'h2',
};
// trix-initialize 時執行 trixInit
document.addEventListener('turbolinks:load', function () {
document.addEventListener('trix-initialize', trixInit, false);
});
樣式
trix-toolbar {
// REMOVE:
max-width: 730px;
margin: 0 auto;
.trix-button--icon-heading-1::before {
background-image: url('...');
}
.trix-button--icon-heading-2::before {
background-image: url('...');
}
.trix-button-group,
.trix-button,
.trix-button:not(:first-child) {
border: 0;
}
.trix-button::before {
background-size: 60%;
}
}
.trix-content {
color: #333333;
// REMOVE:
max-width: 730px;
margin: 0 auto;
> div {
font-size: 16px;
line-height: 24px;
letter-spacing: -0.003em;
margin-bottom: 16px;
}
h2 {
font-size: 18px;
margin-bottom: 1rem;
}
ul,
ol {
margin-bottom: 1rem;
padding-left: 40px;
}
a {
color: #007bff;
text-decoration: none;
}
blockquote {
margin-bottom: 2rem;
margin-top: 2rem;
font-style: italic;
color: #7f8c8d;
font-size: 22px;
line-height: 1.5;
}
.attachment {
margin-bottom: 1rem;
}
.attachment-gallery {
> action-text-attachment,
> .attachment {
flex: 1 0 33%;
padding: 0 0.5em;
max-width: 33%;
}
&.attachment-gallery--2,
&.attachment-gallery--4 {
> action-text-attachment,
> .attachment {
flex-basis: 50%;
max-width: 50%;
}
}
}
action-text-attachment {
.attachment {
padding: 0 !important;
max-width: 100% !important;
}
}
}
參考
- ⭐ 在 toolbar 添加功能:What is the best way to extend the toolbar?
- ⭐ Trix Configuration @ Official Github Wiki
- trixUpload.js @ Gist