はじめに
こんにちは。kosukein38です。
業務でRails4系のアプリケーションにWYSIEIGエディタを導入する必要があったため、そのライブラリの導入手順やできることについて、まとめておきます。
※知識の整理目的も含まれるため、少々冗長になる可能性があります。適宜読み飛ばしていただければと思います。
こんなのをメールの本文入力フォームに導入します。
対象者
- WYSIEIGエディタが何かということを知りたい方
- Rails4系のアプリケーションにWYSIEIGエディタを導入する方法が知りたい方
Rails6系以降はTrixというWYSIEIGエディタをベースにした、Action Textというリッチテキスト機能が導入されているため、Rails6系以降のアプリケーションに対してはこちらを利用するのが良いかと思います。
結論
gem ckeditor
とその拡張機能を使って、Rails4系アプリケーションにWYSIEIGエディタを導入します
選定まで
そもそもWYSIEIGエディタって?
- WYSIWYG(ウィジウィグ)は、「What You See Is What You Get」の略で、日本語では「見たまま得るもの」と訳されます。これは、コンピュータプログラムやエディタなどのユーザーインターフェースの一形式を指す用語です。
- ユーザーがコンテンツを編集する際に、実際の表示と非常に近い形で編集内容を確認することができるエディタであるため、特別な知識がなくても簡単にHTMLでメール文作成などが行えます。
- メールマガジンの配信機能を実装するにあたり、非エンジニアでも簡単にHTMLを書けるようにするため導入しました。
どんな選択肢がありそう?
まず、工数をかけられないため、gemでRailsアプリケーションに入れられるもWYSIWYGエディタを探しました。調べた限り、以下のような選択肢がありそうです。
- Froala
- Trix
- Summernote
- CKEditor
スター数でみるとTrixがもっとも多く17.8k
ですが、Trixは見出し追加などに改修が必要という情報があったため、次点のCKEditor(スター数2.2k
)を選びました。
リポジトリの改修が近年行われていないのは気になりますが、Rails4系への導入なので大きな問題はないだろうと予想し、こちらに決定しました。
CKeditorの導入方法
インストール
ますは公式のREADMEを読んでみてください。
- CKEditor version 4.x (https://ckeditor.com/ckeditor-4/)
- Rails 5.x, 4.2.x integration
- Files browser
- HTML5 file uploader
- Hooks for formtastic and simple_form forms generators
- Integrated with authorization frameworks CanCanCan and Pundit
CKeditorは2023年8月現在、ver.5系が最新のようですが、このgemで入れられるのは4系になります。また、Railsのバージョンも5系or4系です。
今回導入するRailsアプリには元々画像アップロード機能でCarrierWaveを導入していました。CarrierWave + ActiveRecordの構成でアップローダーモデルの管理を行いたかったので、READMEどおり、Gemfileに以下の記述を追加し、$ bundle install
しました。
gem 'carrierwave'
gem 'mini_magick'
その後、READMEにならい以下のコマンドを実行
$ rails generate ckeditor:install --orm=active_record --backend=carrierwave
そうすると、必要なモデル群やマイグレーションファイルが自動で作られます。
マイグレーションファイルが作られたので、$ rails db:migrate
を実行します。
生成されるckeditor_assetsテーブル
でアップロードされたファイルの情報を管理します。
モデルをautoloadするために、application.rb
に以下を追加します。
※READMEにある記述に加えて、以下のissueにあるような記述を加えないと、本番環境でアセット群を読み込んでくれませんでした。注意してください。
#・・・
config.autoload_paths += %W(#{config.root}/app/models/ckeditor)
config.assets.precompile += Ckeditor.assets
config.assets.precompile += %w(ckeditor/*)
#・・・
Ckeditor::Engineをマウントするために、routes.rbに以下を追加します。
mount Ckeditor::Engine => '/ckeditor'
CDN経由でRailsアプリケーションにエディタを読み込む
以下をまず参照して、CDNで導入できるバージョン(4系)を確認
http://cdn.ckeditor.com/
Ckeditor.setup do |config|
config.cdn_url = '//cdn.ckeditor.com/4.22.1/standard/ckeditor.js'
end
ビューに読み込ませるためにapplication.html.erb
にjavascript_include_tag
を追加
<!DOCTYPE html>
<html>
<head>
# ・・・
<%= javascript_include_tag Ckeditor.cdn_url %>
# ・・・
</head>
# ・・・
ここまでで、基本設定はできていると思います。
CKEditorを導入したいビューファイル中のフォーム内で以下のように記述します。
= form_for @page do |form|
= form.cktext_area :notes, class: 'someclass', ckeditor: { language: 'uk'}
= form.cktext_area :content, value: 'Default value', id: 'sometext'
= cktext_area :page, :info, cols: 40, ckeditor: { uiColor: '#AADC6E', toolbar: 'mini' }
bootstrap-formを使っている場合は以下のように書けるようです。
= bootstrap_form_for resource do |form|
= form.cktext_area :text, ckeditor: { language: 'uk'}
ファイルのアップロード先の修正
CarrierWaveを使っていて、画像ファイルのアップロード先をAmazon S3に指定したい場合は
app/uploaders/ckeditor_attachment_file_uploader.rb
app/uploaders/ckeditor_picture_uploader.rb
今回のRailsアプリにはgem carrierwave-aws
が導入されおり、例えば以下のように追加しています。
class CkeditorPictureUploader < CarrierWave::Uploader::Base
include Ckeditor::Backend::CarrierWave
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :aws
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/ckeditor/pictures/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process scale: [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
version :thumb do
process resize_to_fill: [118, 100]
end
version :content do
process resize_to_limit: [800, 800]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
Ckeditor.image_file_types
end
end
これらのファイル内でパスの設定をしてください。
エディタのカスタマイズ、拡張機能の導入
以下は、エディタ表示を変えたいなどエディタをカスタマイズしたい方、拡張機能を入れたい方はご覧ください。
アセットパスの設定とconfig.js
の作成
CKEditorはckeditor/config.js
ファイルを起点にエディタの設定を行います。
Railsアプリのプリコンパイル対象にするため、config/initializers/assets.rb
に以下を追加します。
Rails.application.config.assets.precompile += %w[ckeditor/config.js]
ここでJavaScriotファイル群の置き場について補足ですが、外部のJavaScriptライブラリを導入しているため、vendor/assets/javascripts
のディレクトリを作成し、その中にファイルを配置します。config.js
はtouchコマンドを使ってこのディレクトリ配下に配置します。
$ touch vendor/assets/javascripts/ckeditor/config.js
このあと、拡張機能のインストールを行いますが、先にconfig.jsの設定ファイルを示します。デフォルトのconfig.js設定を上書きすることで、Editorへの拡張機能や、表示するボタンなど設定することができます。設定の詳細は以下をご覧ください。
https://ckeditor.com/docs/ckeditor4/latest/guide/dev_configuration.html
CKEDITOR.plugins.addExternal( 'fakeobjects', '/assets/ckeditor/plugins/fakeobjects/', 'plugin.js' );
CKEDITOR.plugins.addExternal( 'iframe', '/assets/ckeditor/plugins/iframe/', 'plugin.js' );
CKEDITOR.plugins.addExternal( 'autogrow', '/assets/ckeditor/plugins/autogrow/', 'plugin.js' );
CKEDITOR.editorConfig = function (config) {
config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";
config.filebrowserImageBrowseUrl = "/ckeditor/pictures";
config.filebrowserImageUploadUrl = "/ckeditor/pictures?";
config.filebrowserUploadUrl = "/ckeditor/attachment_files";
config.allowedContent = true;
config.disallowedContent = 'img{width,height}';
config.extraAllowedContent = 'img[width,height]';
config.clipboard_handleImages = false;
config.extraPlugins = 'fakeobjects, iframe, autogrow';
config.iframe_attributes = {
sandbox: 'allow-scripts allow-same-origin allow-popups allow-presentation',
allowfullscreen: '',
loading: 'lazy',
referrerpolicy: 'no-referrer-when-downgrade'
};
config.toolbar = [
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ], items: [ 'Source'] },
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ], items: [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ] },
{ name: 'links', items: [ 'Link', 'Unlink', 'Anchor' ] },
{ name: 'insert', items: [ 'Image', 'Flash', 'Table', 'HorizontalRule', 'SpecialChar', 'Iframe' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] },
'/',
{ name: 'styles', items: [ 'Styles', 'Format', 'Font', 'FontSize' ] },
{ name: 'colors', items: [ 'TextColor', 'BGColor' ] },
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] }
];
}
拡張機能の追加
画像の挿入はデフォルトの機能で対応できますが、他にGoogleMapやYouTubeの埋め込みを行うため<iframe>
タグの挿入もできるようにするという要件がありました。
デフォルトの機能では備わっていないため、iframe
拡張機能を利用します。
拡張機能を利用するために、必要なファイル群を公式サイトからダウンロードします。例えばiframeの場合は以下のページからライブラリをダウンロードし、vendor/assets/javascripts/ckeditor
配下に配置します。
https://ckeditor.com/cke4/addon/iframe
ここで、注意点。ダウンロードすると以下のようなダイアログが表示されます。このAdd-on dependencies
にあるライブラリもダウンロードして、置く必要がありそうです。
iframe
の場合、Dialog
とFake Objects
に依存していますが、どうやらDialogの方はifameのライブラリに含まれているのか、Fake Objects
のみのダウンロードでいけました。その他に、エディタの高さを改行の数に応じて、自動で高さ調整してくれるautogrow
も導入しています。
config.js
の以下の部分が拡張ライブラリの設定部分です。
CKEDITOR.plugins.addExternal( 'fakeobjects', '/assets/ckeditor/plugins/fakeobjects/', 'plugin.js' );
CKEDITOR.plugins.addExternal( 'iframe', '/assets/ckeditor/plugins/iframe/', 'plugin.js' );
CKEDITOR.plugins.addExternal( 'autogrow', '/assets/ckeditor/plugins/autogrow/', 'plugin.js' );
CKEDITOR.editorConfig = function (config) {
//・・・
config.extraPlugins = 'fakeobjects, iframe, autogrow';
//・・・
}
これでGoogleMapやYouTubeの埋め込みなどを可能にするiframeタグの挿入ができるようになります。
おわりに
最後までご覧いただきありがとうございました。
新しいバージョンのRailsを使用している場合は、Action Textを使用すると思いますが、古いバージョンのRailsを使っているプロジェクトの場合は外部JSライブラリから導入することになると思いますので、参考になれば幸いです。
CKEditor4系の使用感は悪くないです。今時の直感的な操作という訳にはいきませんが、拡張機能も豊富にありますし、CMS的なものには必要十分だと思います。