次の機能を実装します:
ユーザは記事を書くためにtinymceを使います。記事には複数の画像が含まれており、ユーザーは自分のローカルシステムから画像をアップロードします。私はtinymceがAmazon S3にすべての画像をアップロードしたいと思っています。そこで、私はAPIをヒットして画像をアップロードしました。私はtinymceを自動的にアップロードしたくないので、automatic_uploadsを無効にします。TinyMceでuploadImages()を使用していないimage_upload_handler
$scope.tinymceOptions = {
plugins: ['advlist autolink lists link image charmap print preview hr anchor pagebreak',
'searchreplace wordcount visualblocks visualchars code fullscreen',
'insertdatetime media nonbreaking save table contextmenu directionality',
'emoticons template paste textcolor colorpicker textpattern imagetools codesample toc'],
toolbar1: 'undo redo | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | ' +
'bullist numlist outdent indent | link image',
toolbar2: 'print preview media | forecolor backcolor emoticons | codesample help',
image_title: true,
relative_urls: false,
automatic_uploads: false,
file_picker_types: 'image media',
init_instance_callback: function (editor) {
editor.on('GetContent', function (e) {
console.log('Element clicked:', e.target.nodeName);
editor.uploadImages();
});
},
file_picker_callback: function (cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
// Note: In modern browsers input[type="file"] is functional without
// even adding it to the DOM, but that might not be the case in some older
// or quirky browsers like IE, so you might want to add it to the DOM
// just in case, and visually hide it. And do not forget do remove it
// once you do not need it anymore.
input.onchange = function() {
var file = this.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function() {
// Note: Now we need to register the blob in TinyMCEs image blob
// registry. In the next release this part hopefully won't be
// necessary, as we are looking to handle it internally.
var id = 'img_' + (new Date()).getTime();
var blobCache = tinymce.activeEditor.editorUpload.blobCache;
var blobInfo = blobCache.create(id, file, reader.result);
blobCache.add(blobInfo);
// call the callback and populate the Title field with the file name
cb(blobInfo.blobUri(), {title: file.name});
};
};
input.click();
},
images_upload_handler: function (blobInfo, success, failure) {
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', 'http://localhost:8085/api/article/upload/images');
xhr.setRequestHeader('Authorization', 'Bearer g4vk1bhops2lkbe05p6l2gl2m0');
xhr.onload = function() {
var json;
if (xhr.status < 200 || xhr.status >= 300) {
failure('Some error occurred. Please try again later');
return;
}
success(xhr.responseText);
};
formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
}
};
シナリオ1:
automatic_uploadsをオンにすると、画像はタイムスタンプが現在の時刻とこの命名ロジックは、私がfile_picker_callback
で定義されている名前img_timestamp
で正常にアップロードされます。
シナリオ2: 自動アップロードをオフにすると、getContent
がクリックされ、イメージが正常にアップロードされ、S3のイメージ名が表示されたときにuploadImages()
機能を呼び出すイベントを定義しました(より良い方法は見つかりませんでした) /path_to_s3/img_timestamp
であり、tinymceはアップロード直後にS3から画像を取得しようとしています(画像を表示するために、これはtinymceのデフォルトの動作ですが、理由はわかりません)。/path_to_s3/blobTimestamp
のタイムスタンプは現在の時刻です。
img_timestamp
という名前の画像をアップロードするには、tinymceにS3 URLに同じファイル名を追加してください。つまり、このデフォルト動作をすべてオーバーライドできない場合は、/path_to_s3/img_timestamp
です。
コントローラーコード:
$scope.getContent = function() {
console.log('Editor content:', $scope.tinymceModel);
};
HTMLコード:
<form method="post" ng-controller="submitArticleCtrl">
<textarea ui-tinymce="tinymceOptions" ng-model="tinymceModel"></textarea>
<button ng-click="getContent()">Get content</button>
<button ng-click="setContent()">Set content</button>
</form>