WYSIWYG(うぃじうぃぐ)
2021.02.02
こんにちわ。Webエンジニアの陰山です。
今回は真面目に技術ブログを書いてみます。
みなさん、WYSIWYG(うぃじうぃぐ)ってご存知ですか?
知らず知らずのうちにお世話になっている方、実はすごく多いんじゃないかと思います!
WYSIWYG(うぃじうぃぐ)
WYSIWYG(うぃじうぃぐ)とは?
WYSIWYGとは、見たままを出力するという意味で、「What You See Is What You Get」の頭文字をとったものです。
WYSIWYGエディタは、編集画面に表示される見た目と同じものが、ブラウザや印刷結果として得られるようなアプリケーションのことです。
例えば Wordpress に代表される Web CMS や、Microsoft Word などもその一つと言えます。
Web開発案件をやっていると、Wordpress は使いたくないんだけど、コンテンツ編集画面だけ使いたい、ということがあります。
そんな時には WYSIWYG が候補に上がるのですが、今回その実装でハマったのでご紹介しますね!
この記事が役に立ちそうな方
・HTML, CSS, Javascript でコーディングし始めの方
・NPMでライブラリをインストールしたことがある方
・非同期通信のフロント側/バック側の実装に興味がある方
・WYSIWYG 案件に直面している方
要件
さて今回の要件は
・簡単なテキスト装飾がしたい
・画像アップロードがしたい
・画像のサイズ変更を簡単にしたい
というものです。
実現可能な WYSIWYG いくつかありますが、今回は 老舗WYSIWYG「CKEditor」の最新版 CKEditor5 を採用します。
CKEditor は、無料ライセンスでも商用利用が可能です。ただし無料ライセンスでは一部機能が使えないので注意してください。
CKEditor
というわけでまずはインストール。
→Instllation
いくつかインストール方法が用意されています。
この時の私は、まさかNPMでテキトーにやって画像アップロードでハマるとは、知る由もなかったのです。。
ドキュメントは、読むべし。
(あたりまえ)
でも実は、簡単なテキスト装飾がサクッとやりたいだけなら、ドキュメント流し読みで テキトーにやっても多分大丈夫です。とりあえず動きます。とりあえずヨシ!(ダメ)
ここから、画像アップロードをはじめとする標準機能以上のことがしたい場合、プラグインのインストールが必要になります。
このプラグインが、後付けで足していけばいいというものではないことに注意が必要なのです。
それを認識しないまま、
@import しては、「そのライブラリは重複してるよ!」
@import を消しては、「そんなコンテナ名は知らないよ!」
を繰り返していた頃が僕にもありました。。。
さて、どうするかというと、ポイントは2つありました。
1. インストールするスクリプト生成
2. 画像アップロード後の処理が必要
まずは1つ目、スクリプト生成。
「えっ、NPMインストールでいいんじゃないの?」
そう思われた方、そうですよね!そう思いますよね!!
でもそれじゃダメなんです。
プラグインを使いたい場合、後付けで @import したらスクリプトが重複してしまうみたいです。
専用のプロジェクトを立てて、使いたいプラグインを含めたビルドを行う必要があります。
開発環境等についてはドキュメントをご参考ください。
→Installing plugins(しつこい)
ざっくりと手順としては
1. Git で新プロジェクトとしてクローン
git clone -b stable https://github.com/ckeditor/ckeditor5
2. 必要なプラグインを有効にして
3. ビルドする
yarn run build
4. できた javascript を、元プロジェクトにコピペして script タグで読み込む
5. 実行部分を書く
次はポイントの2つ目、
画像アップロード後の処理
です。
画像のアップロードには非同期通信が使われているため、裏っかわで Form からファイルを受け取って任意のディレクトリに保存する機能が必要です。
CKEditor5 にその機能が組み込まれていると勝手に思っていたのですが、自分で書く必要があります。
ドキュメントに出てくる「エンドポイント」がそれにあたり、スクリプトの "uploadUrl" に設定します。
賢明なみなさんは、この "uploadUrl" をアップロード後のファイルの保存ディレクトリだと思って
uploadUrl: '/uploads',
とかテキトーに設定しては、いけませんよ。。
そうこうして最終的にできたコードがこちら!
HTML
create.html
<form enctype="multipart/form-data" method="post" action="insert.php">
<textarea id="editor">
</form>
<script src="./js/ckeditor.js"></script>
<script>
ClassicEditor.create( document.querySelector( '#editor' ), {
ckfinder: {
uploadUrl: '/ajax/ck-image/image.php',
options: {
resourceType: 'Images'
}
}
} )
.then( editor => {
window.editor = editor;
} )
.catch( error => {
console.error( 'There was a problem initializing the editor.', error );
} );
</script>
6行目の "./js/ckeditor.js" が、自分でビルドしたカスタムスクリプトです。
読み込むライブラリはこれだけです!
エンドポイントのPHP
上記HTMLの10行目で指定しています。
/ajax/ck-image/image.php
<?php
$uploads_dir = '/uploads';
foreach ($_FILES["upload"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["upload"]["tmp_name"][$key];
// basename() で、ひとまずファイルシステムトラバーサル攻撃は防げるでしょう。
// ファイル名についてのその他のバリデーションも、適切に行いましょう。
$name = basename($_FILES["upload"]["name"][$key]);
move_uploaded_file($tmp_name, "$uploads_dir/$name");
echo json_encode([
"uploaded" => true,
"url" => "$uploads_dir/$name"
]);
}
}
?>