Tích hợp TinyMCE free với API tùy biến thêm icon add photo và thư viện

  1. Truy cập vào trang https://www.tiny.cloud/ để đăng ký tài khoản, sau khi điền các thông tin thì có thể copy API
  2. Vào menu https://www.tiny.cloud/my-account/integrate/#html tích hợp
  3. Vào approved domains để thêm domain tích hợp https://www.tiny.cloud/my-account/domains/

Sau khi có key API và biết cách tích hợp có thể tham khảo code bên dưới

<!–  Place the first <script> tag in your HTML’s <head> –>
<script src=“https://cdn.tiny.cloud/1/4rr7wzk5q1a0x…….vpcl5ymqaic6yrki0l2qk7/tinymce/7/tinymce.min.js” referrerpolicy=“origin”></script>
<!– Place the following <script> and <textarea> tags in your HTML’s <body> –>
<script>tinymce.init({
  selector: ‘textarea’,
  images_upload_url: ‘act/admincp/blog?type=upload_image’,  
  automatic_uploads: true,    
  file_picker_types: ‘image’,
  plugins: [
    ‘anchor’, ‘autolink’, ‘charmap’, ‘codesample’, ’emoticons’, ‘image’, ‘link’, ‘lists’, ‘media’, ‘searchreplace’, ‘table’, ‘visualblocks’, ‘wordcount’,
    ‘checklist’, ‘mediaembed’, ‘casechange’, ‘export’, ‘formatpainter’, ‘pageembed’, ‘a11ychecker’, ‘tinymcespellchecker’, ‘permanentpen’, ‘powerpaste’, ‘advtable’, ‘advcode’, ‘editimage’, ‘advtemplate’, ‘ai’, ‘mentions’, ‘tinycomments’, ‘tableofcontents’, ‘footnotes’, ‘mergetags’, ‘autocorrect’, ‘typography’, ‘inlinecss’, ‘markdown’,
    ‘importword’, ‘exportword’, ‘exportpdf’, ‘fullscreen’
  ],
  toolbar: ‘fullscreen undo redo | blocks fontfamily fontsize | bold italic underline strikethrough | link image deleteimage filemanager media table mergetags | addcomment showcomments | spellcheckdialog a11ycheck typography | align lineheight | checklist numlist bullist indent outdent | emoticons charmap | removeformat’,
  tinycomments_mode: ’embedded’,
  tinycomments_author: ‘Author name’,
  mergetags_list: [
    { value: ‘First.Name’, title: ‘First Name’ },
    { value: ‘Email’, title: ‘Email’ },
  ],
  ai_request: (request, respondWith) => respondWith.string(() => Promise.reject(‘See docs to implement AI Assistant’)),
  exportpdf_converter_options: { ‘format’: ‘Letter’, ‘margin_top’: ‘1in’, ‘margin_right’: ‘1in’, ‘margin_bottom’: ‘1in’, ‘margin_left’: ‘1in’ },
  exportword_converter_options: { ‘document’: { ‘size’: ‘Letter’ } },
  importword_converter_options: { ‘formatting’: { ‘styles’: ‘inline’, ‘resets’: ‘inline’, ‘defaults’: ‘inline’ } },
 
  file_picker_callback: function(callback, value, meta) {
    var input = document.createElement(‘input’);
    input.setAttribute(‘type’, ‘file’);
    input.setAttribute(‘accept’, ‘image/*’);
   
    input.onchange = function() {
      var file = input.files[0];
      var formData = new FormData();
      formData.append(‘file’, file);
 
      fetch(‘act/admincp/blog?type=upload_image’, {
        method: ‘POST’,
        body: formData
      })
      .then(response => response.json())
      .then(data => {
        if (data.location) {
          callback(data.location);
        } else {
          alert(‘File upload failed’);
        }
      });
    };
   
    input.click();
  },
 
  setup: function (editor) {
     
 
editor.ui.registry.addButton(‘filemanager’, {
    icon: ‘gallery’,  
    tooltip: ‘File manager gallery’,
    onAction: function () {
        editor.windowManager.openUrl({
            title: ‘File Manager’,  
            url: <?=$this->config[‘url’]?>/blog?type=filemanager&page=1′,  
            width: 800,  
            height: 600,  
            buttons: [
                {
                    text: ‘Close’,
                    type: ‘cancel’,  
                    onclick: ‘close’
                }
            ]
        });
    }
});
    editor.on(‘ObjectSelected’, function(e) {
      if (e.target.nodeName === ‘IMG’) {
 
        var deleteButton = document.createElement(‘button’);
        deleteButton.textContent = ‘Delete Image’;
        deleteButton.addEventListener(‘click’, function() {
          var imgSrc = e.target.src;
          if (confirm(‘Are you sure you want to delete this image?’)) {
 
            fetch(`/blog?type=upload_image&delete=${encodeURIComponent(imgSrc)}`)
              .then(response => response.json())
              .then(data => {
                if (data.success) {
                  alert(‘File deleted’);
                  e.target.remove();  
                } else {
                  alert(‘Failed to delete file’);
                }
              });
          }
        });
 
        editor.ui.registry.addButton(‘deleteImage’, {
          text: ‘Delete Image’,
          onAction: function () {
            deleteButton.click();
          }
        });
      }
    });
  }
});
function checkAndSubmitnews()
{
    if ($(“#post_title”).val() == “”)
    {
        alert(‘Pls enter title’);
        $(‘.err’).html(‘ <div class=”alert alert-block alert-danger”>Pls enter title</div> ‘);
        return;
    }
    if ($(“#post_thumb”).val() == “”)
    {
        alert(‘Pls enter URL thumb’);
        $(‘.err’).html(‘ <div class=”alert alert-block alert-danger”>Pls enter URL thumb</div> ‘);
        return;
    }  
    if ($(“#post_tags”).val() == “”)
    {
        alert(‘Pls choose language’);
        $(‘.err’).html(‘ <div class=”alert alert-block alert-danger”>Pls choose language</div> ‘);
        return;
    }      
 
    $(“#loadings”).show();      
    $(“#form-post”).submit();
}
</script>