WYSIWYGエディタ TinyMCEを使った開発
リッチテキストエディタ及びWYSIWYGエディタのライブラリは世の中にたくさんあります。
最近、TinyMCEというWYSIWYGエディタを使った開発をしました。とても高機能で使いやすく、基本的には無料で利用することができます。
ドキュメント
ドキュメントは、以下のページを見ることになります。
Documentation | Docs | TinyMCE
ReactプロジェクトへTinyMCEの導入
自分が開発したのは、Reactのプロジェクトだったので、@tinymce/tinymce-react
というパッケージを利用しました。
導入はとても簡単で、以下の通りに、<Editor>
コンポーネントを利用するだけです。
import { Editor } from "@tinymce/tinymce-react"; const App = () => { const [doc, setDoc] = useState(""); const onChange = (value) => { setDoc(value); }; return ( <Editor initialValue={doc} apiKey={process.env.REACT_APP_TYNY_MCE_API_KEY} init={{ height: 800, menubar: false, branding: false, }} onEditorChange={onChange} /> ); };
API Key
<Editor>
コンポーネントには、apiKey
を渡す必要があります。
API Keyは、Tinyのサイトで会員登録すれば取得できます。
Approved Domains
Tinyのサイトにログイン後、「Approved Domains」を設定する必要があります。デプロイするドメインを登録する必要があります。
localhost
はデフォルトで許可されているので、デプロイするまでその必要性を知りませんでした。
日本語化
エディタのパーツを日本語化することが可能です。
https://www.tiny.cloud/docs/advanced/creating-a-plugin/#languagelocalization
日本語化は、以下のページでja
ファイルをダウンロードして、デプロイする際にtinymce/langs/ja.js
として配置しました。
あとは<Editor>
のlanguageを指定すればOKです。
<Editor initialValue={doc} apiKey={process.env.REACT_APP_TYNY_MCE_API_KEY} init={{ height: 800, menubar: false, branding: false, language: "ja", }} onEditorChange={onChange} />
プラグイン
TinyMCEの魅力の一つに豊富なプラグインがあります。Open source plugins
であれば、無料で利用できます。
導入もとても簡単で、plugins
プロパティに組み込みたいプラグイン名を配列で指定するだけです。
const App = () => { const [doc, setDoc] = useState(""); const onChange = (value) => { setDoc(value); }; return ( <Editor initialValue={doc} apiKey={process.env.REACT_APP_TYNY_MCE_API_KEY} init={{ height: 800, menubar: false, branding: false, language: "ja", plugins: ["fullscreen", "link", "table", "lists"], }} onEditorChange={onChange} /> ); };
ツールバー
表示するツールバーの機能もtoolbar
プロパティで指定することができます。こちらは文字列で指定します。|
はツールバー上での区切りUIの指定です。
const App = () => { const [doc, setDoc] = useState(""); const onChange = (value) => { setDoc(value); }; return ( <Editor initialValue={doc} apiKey={process.env.REACT_APP_TYNY_MCE_API_KEY} init={{ height: 800, menubar: false, branding: false, language: "ja", toolbar: "undo redo | formatselect | fontsizeselect | bold italic", }} onEditorChange={onChange} /> ); };
画像の指定
エディタ内での画像指定にはImage Plugin
を利用します。
画像選択時に、アプリケーション内の画像選択ダイアログを利用したい場合があります。
その場合はfile_picker_callback
を利用すると実現できます。このcallbackはTinyMCE上で画像選択UIのクリック時に発火します。
第一引数のcallback
に任意のURLを渡すと、それがエディタ上に挿入されます。
なので、無理やりですが、callback関数をstateに保持しておき、ダイアログを表示、ダイアログで画像選択時にstateで保持したcallback関数に選択したURLを渡して実行する。といったアプローチで実現することができました。
const App = () => { const [doc, setDoc] = useState(""); const onChange = (value) => { setDoc(value); }; return ( <Editor initialValue={doc} apiKey={process.env.REACT_APP_TYNY_MCE_API_KEY} init={{ height: 800, menubar: false, branding: false, language: "ja", toolbar: "undo redo | formatselect | fontsizeselect | bold italic", file_picker_callback: function(callback, value, meta) { if (meta.filetype === "image") { // 任意の処理 } }, }} onEditorChange={onChange} /> ); };
Full Page Plugin
基本的には、ブログ記事のエディタのような使われ方が多いですが、Webページ(HTML)を編集するエディタとしても利用できます。
そういった場合に、Full Page Plugin
を利用します。
このプラグインを利用しないと、HTML文字列をエディタに渡しても、head
要素などが消されてしまい、body
の中しか編集できないようになっています。
このプラグインを利用することで、head
要素などがそのまま組み込まれた状態で編集することができます。
ただし、いくつか注意点があります。
body_id, body_class
TinyMCE上では、html
要素やbody
要素はTinyMCEが生成するものに書き換えられてしまいます。
なのでbody
要素に特定の属性を指定していたHTML文字列を渡しても、エディタ上では、その属性が消えてしまいます。
body
要素のclassやidは以下の設定で、追加することが可能です。なので、事前にHTML文字列をパースして、idとclassを抜き出してエディタに設定として渡すといった対応が必要な場合があります。
https://www.tiny.cloud/docs/configure/content-appearance/#body_id https://www.tiny.cloud/docs/configure/content-appearance/#body_class
JavaScript無効化
TinyMCE上では、script
タグがすべて無効化されます。主にセキュリティの目的なので、設定で無効化できる挙動でもありません。
document_base_url
JavaScriptの読み込みや実行はできませんが、CSSファイルは読み込めます。その際、リンクに相対パスを指定している場合、document_base_url
を指定することで、任意の場所で配布されているファイルにリクエストが可能です。
https://www.tiny.cloud/docs/configure/url-handling/#document_base_url
コンテンツの書き換え
TinyMCEが自動でHTMLの中身を書き換えてしまう場合があります。
基本的に中身を変えてほしくない場合はverify_html
とconvert_urls
をOFFにするのがおすすめです。