railsでckeditor5のmarkdown pluginを導入する
オープンソースのWYSIWYGエディタであるCKEditor5をマークダウンエディタとしてRailsに導入する
https://ckeditor.com/ckeditor-5/
以下のpluginを利用する https://ckeditor.com/docs/ckeditor5/latest/features/markdown.html
前提条件、webpackerの4系を利用しています
CKEditorのpluginを利用するためにnpmパッケージを諸々インストール
yarn add @ckeditor/ckeditor5-autoformat @ckeditor/ckeditor5-basic-styles @ckeditor/ckeditor5-block-quote @ckeditor/ckeditor5-dev-utils @ckeditor/ckeditor5-dev-webpack-plugin @ckeditor/ckeditor5-editor-classic @ckeditor/ckeditor5-essentials @ckeditor/ckeditor5-heading @ckeditor/ckeditor5-image @ckeditor/ckeditor5-link @ckeditor/ckeditor5-list @ckeditor/ckeditor5-markdown-gfm @ckeditor/ckeditor5-paragraph @ckeditor/ckeditor5-theme-lark raw-loader style-loader
CKEditorを利用するためにwebpackの設定を変更する必要がある まずloader用のファイルを2つ作成
config/webpack/loaders/ckeditor-css.js
const { styles } = require( '@ckeditor/ckeditor5-dev-utils' ); module.exports = { test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/, use: [ { loader: 'style-loader', options: { injectType: 'singletonStyleTag' } }, { loader: 'postcss-loader', options: styles.getPostCssConfig( { themeImporter: { themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' ) }, minify: true } ) }, ] }
config/webpack/loaders/ckeditor-svg.js
module.exports = { test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/, use: [ 'raw-loader' ] }
config/webpack/environment.jsに追記
const { environment } = require('@rails/webpacker') const railsErbLoader = require('./loaders/rails-erb-loader'); environment.loaders.prepend('rails-erb-loader', railsErbLoader) // ここから追記 const ckeditorSVG = require('./loaders/ckeditor-svg') const ckeditorCSS = require('./loaders/ckeditor-css') const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' ) environment.plugins.prepend('CKEditor',new CKEditorWebpackPlugin({ language: 'ja' }) ) environment.loaders.append('ckeditorCSS', ckeditorCSS) environment.loaders.append('ckeditorSVG', ckeditorSVG) const cssLoader = environment.loaders.get('css'); cssLoader.exclude = /(\.module\.[a-z]+$)|(ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css)/ const fileLoader = environment.loaders.get('file'); fileLoader.exclude = /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/ // ここまで追記 module.exports = environment
これで利用する準備は出来たので実際に使ってみる 適当なテキストエリアのフォームを作成
= content_for :head do = javascript_pack_tag 'document' .container #js-editor = simple_form_for([@group, @entry], html: {class: 'js-entry-form'}) do |f| = f.error_notification = f.input_field :content, class: 'js-entry-form-content', style: 'display: none' = f.submit
app/javascript/packs/document.js にCKEditor用のjavascriptファイルを作成
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'; import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials'; import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat'; import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'; import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote'; import Heading from '@ckeditor/ckeditor5-heading/src/heading'; import Image from '@ckeditor/ckeditor5-image/src/image'; import Link from '@ckeditor/ckeditor5-link/src/link'; import List from '@ckeditor/ckeditor5-list/src/list'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; // https://ckeditor.com/docs/ckeditor5/latest/features/markdown.html import GFMDataProcessor from '@ckeditor/ckeditor5-markdown-gfm/src/gfmdataprocessor'; // Simple plugin which loads the data processor. function Markdown(editor) { editor.data.processor = new GFMDataProcessor(); } $(window).on("load", function () { const $textarea = $('.js-entry-form-content'); let content = $textarea.val(); ClassicEditor .create(document.querySelector('#js-editor'), { plugins: [ Markdown, Essentials, Autoformat, Bold, Italic, BlockQuote, Heading, Image, Link, List, Paragraph ], toolbar: [ 'heading', '|', 'alignment', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' ] }) .then(editor => { editor.setData(content) editor.model.document.on('change:data', () => { $textarea.val(editor.getData()) }) }) .catch(error => { console.error(error); }); });
pluginは必要に応じて追加、削除してください
これでこんな感じのフォームが作成できた