toshi-toma blog

主にフロントエンド、作業ログあとは色々なメモ ✍️ 🍅

WYSIWYGエディタ TinyMCEを使った開発

リッチテキストエディタ及びWYSIWYGエディタのライブラリは世の中にたくさんあります。

ourcodeworld.com

最近、TinyMCEというWYSIWYGエディタを使った開発をしました。とても高機能で使いやすく、基本的には無料で利用することができます。

www.tiny.cloud

ドキュメント

ドキュメントは、以下のページを見ることになります。

Documentation | Docs | TinyMCE

ReactプロジェクトへTinyMCEの導入

自分が開発したのは、Reactのプロジェクトだったので、@tinymce/tinymce-reactというパッケージを利用しました。

github.com

導入はとても簡単で、以下の通りに、<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のサイトで会員登録すれば取得できます。

https://www.tiny.cloud/

Approved Domains

Tinyのサイトにログイン後、「Approved Domains」を設定する必要があります。デプロイするドメインを登録する必要があります。 localhostはデフォルトで許可されているので、デプロイするまでその必要性を知りませんでした。

日本語化

エディタのパーツを日本語化することが可能です。

https://www.tiny.cloud/docs/advanced/creating-a-plugin/#languagelocalization

日本語化は、以下のページでjaファイルをダウンロードして、デプロイする際にtinymce/langs/ja.jsとして配置しました。

www.tiny.cloud

あとは<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であれば、無料で利用できます。

www.tiny.cloud

導入もとても簡単で、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を利用します。

www.tiny.cloud

画像選択時に、アプリケーション内の画像選択ダイアログを利用したい場合があります。 その場合は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を利用します。

www.tiny.cloud

このプラグインを利用しないと、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タグがすべて無効化されます。主にセキュリティの目的なので、設定で無効化できる挙動でもありません。

github.com

document_base_url

JavaScriptの読み込みや実行はできませんが、CSSファイルは読み込めます。その際、リンクに相対パスを指定している場合、document_base_urlを指定することで、任意の場所で配布されているファイルにリクエストが可能です。

https://www.tiny.cloud/docs/configure/url-handling/#document_base_url

コンテンツの書き換え

TinyMCEが自動でHTMLの中身を書き換えてしまう場合があります。 基本的に中身を変えてほしくない場合はverify_htmlconvert_urlsをOFFにするのがおすすめです。