TinyMCEに画像アップロード機能を追加する
はじめに
TinyMCEに画像のアップロード機能を追加した時の備忘録。
目次
環境
- tinymce : 6.0.3
TinyMCEをダウンロードする
自分で契約したサーバなどに設置する場合、https://www.tiny.cloud/get-tiny/ を開き、ページ中ほどにあるDownload TinyMCE Community
のボタンをクリックしてファイルをダウンロードします。
2022/06/20時点で、tinymce_6.0.3.zip
がダウンロードされます。
ダウンロードしたzipファイルを解凍し、中のtinymce
というフォルダを任意の場所にコピーします。
ここでは説明のため、プロジェクトの直下にコピーしています。
1root 2 ┗ tinymce
TinyMCEを設置して確認する
TinyMCEの動作を確認するため、index.htmlを作成し確認します。
1 root 2 ┣ tinymce 3+ ┗ index.html
index.htmlの中身は以下のようになります。
tinymce/tinymce.min.js
ファイルを読み込むtinymce.init()
を実行(オプションのselector
にはtextara
のセレクタを指定する。ここでは#tiny
を指定)
index.html1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4<meta charset="UTF-8"> 5<title>TinyMCE</title> 6<script src="./tinymce/tinymce.min.js"></script> 7<script> 8tinymce.init({ 9 selector: '#tiny', 10}); 11</script> 12</head> 13<body> 14<textarea id="tiny" name="conetnt"></textarea> 15</body> 16</html>
ブラウザを開いて、以下のようにエディタが表示されていれば成功です。
その他のオプションなどは、ドキュメントを参照してください。
TinyMCEを日本語化する
メニューなどを日本語化するために、日本語化ファイルをダウンロードします。
https://www.tiny.cloud/get-tiny/language-packages/ ページを開き、ページをスクロールしてJapanese
と書かれた部分を探し、ダウンロードボタンをクリックしてファイルをダウンロードします。
ja.zip
というファイルがダウンロードされるため、解凍し、中にあるja.js
というファイルを/tinymce/langs/
フォルダにコピーします。
1 root 2 ┣ tinymce 3 ┃ ┗ langs 4+ ┃ ┗ ja.js 5 ┗ index.html
次にTinyMCEのオプションにlanguage: "ja",
を追加します。
1 tinymce.init({ 2 language: "ja", 3 selector: '#tiny', 4 });
ブラウザを再読み込みして、メニューが日本語化されていれば成功です。
画像のアップロード機能を追加する
TinyMCEで画像を扱うために、オプションにplugins: "image",
を追加します。
1 tinymce.init({ 2 language: "ja", 3 plugins: "image", 4 selector: '#tiny', 5 });
以下のようにメニューの挿入に「画像」が追加されます。
「画像」メニューをクリックすると「画像の挿入/編集」ダイアログが表示されます。
ツールバーに画像ボタンを表示するには、オプションにimage
を追加します。
1tinymce.init({ 2 language: "ja", 3 plugins: "image", 4 selector: '#tiny', 5 toolbar: ['undo redo | styles | bold italic | alignleft aligncenter alignright alignjustify | outdent indent | image'] 6 });
すると、以下のようにツールバーにボタンが追加されます。
次に、画像のアップロードは何通りかの方法があるため、お好みの方法で設定してください。
ファイル送信を手動で行う(images_upload_handler)
images_upload_handler: function () {...}
を指定して、アップロード処理を手動で行います。例として、example_upload_handler
という関数を作成してファイルを送信する場合は以下のようになります。
1 tinymce.init({ 2 language: "ja", 3 plugins: "image", 4 selector: '#tiny', 5 images_upload_handler: example_upload_handler, 6 });
「画像の挿入/編集」ダイアログに「アップロード」のメニューが追加されます。この場合、画像をドラッグ&ドロップでアップロードすることができます。
example_upload_handler
の中身の例は以下のようになります。
- サーバのアップロードURLに対して画像ファイルを送信する(ここでは
postAcceptor.php
) - JSONデータ受け取った画像のURLを
resolve
で返す
1const example_upload_handler = (blobInfo, progress) => new Promise((resolve, reject) => { 2 const xhr = new XMLHttpRequest(); 3 xhr.withCredentials = false; 4 xhr.open('POST', 'postAcceptor.php'); 5 6 xhr.onload = () => { 7 if (xhr.status === 403) { 8 reject({ message: 'HTTP Error: ' + xhr.status, remove: true }); 9 return; 10 } 11 12 if (xhr.status < 200 || xhr.status >= 300) { 13 reject('HTTP Error: ' + xhr.status); 14 return; 15 } 16 17 const json = JSON.parse(xhr.responseText); 18 19 if (!json || typeof json.location != 'string') { 20 reject('Invalid JSON: ' + xhr.responseText); 21 return; 22 } 23 24 resolve(json.location); 25 }; 26 27 xhr.onerror = () => { 28 reject('Image upload failed due to a XHR Transport error. Code: ' + xhr.status); 29 }; 30 31 const formData = new FormData(); 32 formData.append('file', blobInfo.blob(), blobInfo.filename()); 33 34 xhr.send(formData); 35});
アップロードできる画像の形式を指定するには、images_file_types: '{画像形式}',
を指定します。jpgとpngだけアップロードさせたい場合は以下のようにカンマで区切って指定します。
1tinymce.init({ 2 language: "ja", 3 plugins: "image", 4 selector: '#tiny', 5 images_upload_handler: example_upload_handler, 6 images_file_types: 'jpg,png', 7});
ファイル送信を手動で行う(file_picker_callback)
file_picker_callback: function () {...}
を指定して、アップロード処理を手動で行います。次の例では、example_picker_callback
という関数を使用してファイルを送信します。
images_upload_handler
との違いは、あちらは画像のみを扱うのに対して、file_picker_callback
は画像以外のファイルも扱うことができます。
1 tinymce.init({ 2 language: "ja", 3 plugins: "image", 4 selector: '#tiny', 5 file_picker_callback: example_picker_callback, 6 });
ソースの横に、ファイル選択のボタンが表示されます。
example_picker_callback
の中身の例は以下のようになります。
- inputを生成し、変更が発生した時にファイルを送信する
- サーバのアップロードURLに対して画像ファイルを送信する(ここではpostAcceptor.php)
- JSONデータ受け取った画像のURLをcallbackで返す
1 2const example_picker_callback = (callback, value, meta) => { 3 const input = document.createElement("input"); 4 input.setAttribute("type", "file"); 5 6 if (meta.filetype === "image") { 7 input.setAttribute("accept", ".png, .jpeg, .jpg, .webp"); 8 } 9 10 input.onchange = function () { 11 var file = this.files[0]; 12 13 const xhr = new XMLHttpRequest(); 14 xhr.withCredentials = false; 15 xhr.open("POST", "postAcceptor.php"); 16 17 xhr.onload = () => { 18 if (xhr.status === 403) { 19 reject({ message: 'HTTP Error: ' + xhr.status, remove: true }); 20 return; 21 } 22 23 if (xhr.status < 200 || xhr.status >= 300) { 24 callback("HTTP Error: " + xhr.status); 25 return; 26 } 27 28 const json = JSON.parse(xhr.responseText); 29 30 if (!json || typeof json.location != 'string') { 31 callback('Invalid JSON: ' + xhr.responseText); 32 return; 33 } 34 35 callback(json.location); 36 }; 37 38 xhr.onerror = () => { 39 reject('Image upload failed due to a XHR Transport error. Code: ' + xhr.status); 40 }; 41 42 const formData = new FormData(); 43 formData.append("file", file, file.name); 44 45 xhr.send(formData); 46 }; 47 48 input.click(); 49}
ファイル送信を自動で行い、アップロード先のURLを指定する場合
オプションにimages_upload_url: "{アップロードURL}"
を指定することで、アップロードURLに対してファイルを送信します。
./postAcceptor.php
というURLに対してファイルを送信する場合は以下のように指定します。
1 tinymce.init({ 2 language: "ja", 3 plugins: "image", 4 selector: '#tiny', 5 images_upload_url: "./postAcceptor.php", 6 });