Latest Post

Triển khai dự án PHP, Mysql với Nginx trên Docker Tìm hiểu về HTML – Ưu điểm, nhược điểm và cách hoạt động của HTML

Tiếp theo trong loạt bài viết về Ruby On Rails, hôm nay chúng ta sẽ tìm hiểu cách tích hợp bộ soạn thảo TinyMCE phiên bản 4.x cùng với trình quản lý tệp tin elFinder phiên bản 2.x vào Rails 5.

Bộ soạn thảo TinyMCE

Trong một dự án, nếu bạn muốn quản lý nội dung và mô tả của một sản phẩm hoặc bài viết một cách hiệu quả, bạn cần một bộ soạn thảo để tạo nội dung dễ đọc và trực quan cho người đọc. TinyMCE là một ví dụ về một bộ soạn thảo nội dung WYSIWYG (What You See Is What You Get) mạnh mẽ và đáng tin cậy để giúp bạn thực hiện công việc này.

Bộ soạn thảo TinyMCE

Trình quản lý file elFinder

elFinder là một ứng dụng quản lý tệp và thư mục cực kỳ mạnh mẽ, với nhiều tính năng ấn tượng như tải lên tệp, cắt tệp, và giải nén tệp. Một trong những điểm đặc biệt của elFinder là khả năng tích hợp nó vào bộ soạn thảo TinyMCE. Điều này đặc biệt hữu ích vì việc sử dụng trình quản lý tệp đi kèm với TinyMCE thường đòi hỏi phải trả phí. Vì vậy, sử dụng elFinder là một giải pháp hoàn toàn miễn phí để tích hợp một trình quản lý tệp mạnh mẽ vào ứng dụng của bạn.

Tích hợp TinyMCE và elFinder trong Rails 5

1. Cài đặt TinyMCE Editor và elFilder

– Sửa file Gemfile trong project của Rails 5, thêm dòng sau:

gem 'tinymce-rails'
gem 'el_finder', '1.1.12'

Chạy command bundle để Rails cài đặt  2 gem này. Kết quả sau khi cài đặt:

– Download elFinder ở đây: https://studio-42.github.io/elFinder/

Sau đó giải nén, và copy vào thư mục public/ của project

2. Tích hợp TinyMCE vào Rails 5

– Tạo một controller mới có tên là Media, chạy command sau:

rails g controller Media index

– Sửa file config/routes.rb

# Media route
get     '/admin/media'  => 'media#index', as: :media_management
match   'elfinder'      => 'media#elfinder', via: [:get, :post]

– Update nội dung cho file app/controllers/media_controller.rb

class MediaController < ApplicationController
  skip_before_action :verify_authenticity_token, :only => ['elfinder']

  def index
    render :layout => false
  end

  def elfinder
    rootpath = File.join(Rails.public_path, 'uploads')
    rooturl = '/uploads'

    h, r = ElFinder::Connector.new(
      :root => rootpath,
      :url => rooturl,
      :perms => {
         /^(Welcome|README)$/ => {:read => true, :write => false, :rm => false},
         '.' => {:read => true, :write => true, :rm => true}, # '.' is the proper way to specify the home/root directory.
      },
      :extractors => {
         'application/zip' => ['unzip', '-qq', '-o'], # Each argument will be shellescaped (also true for archivers)
         'application/x-gzip' => ['tar', '-xzf'],
      },
      :archivers => {
         'application/zip' => ['.zip', 'zip', '-qr9'], # Note first argument is archive extension
         'application/x-gzip' => ['.tgz', 'tar', '-czf'],
      },
      :thumbs => true
    ).run(params)

    headers.merge!(h)

    if r.empty?
      (render :nothing => true) and return
    end

    render :json => r, :layout => false
  end
end

Ởfunction elfinder của controller Class MediaController, để trả về dữ liệu cho elFinder.

  • Thư mục quản lý file sẽ đặt ở thư mục public/uploads của project
  • Gem ‘el_finder’ để xứ lý backend cho phần quản lý file. (https://github.com/phallstrom/el_finder)

– Sửa file app/views/media/index.html.rb

<!DOCTYPE html>
<html>
<head>
  <title>File Manager</title>
  <link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/smoothness/jquery-ui.css">
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
  <script type="text/javascript" src="/elfinder/js/elfinder.min.js"></script>
  <script src="/elfinder/js/proxy/elFinderSupportVer1.js" type="text/javascript" charset="utf-8"></script>
  <script type="text/javascript" src="/elfinder/js/i18n/elfinder.de.js"></script><!-- optional -->
  <link rel="stylesheet" type="text/css" media="screen" href="/elfinder/css/elfinder.min.css">
  <link rel="stylesheet" type="text/css" media="screen" href="/elfinder/css/theme.css">
</head>
<body>


<div id="elfinder"></div>

<script type="text/javascript">
  var FileBrowserDialogue = {
    init: function() {
      // Here goes your code for setting your custom things onLoad.
    },
    mySubmit: function (URL) {
      // pass selected file path to TinyMCE
      parent.tinymce.activeEditor.windowManager.getParams().setUrl(URL);
      // close popup window
      parent.tinymce.activeEditor.windowManager.close();
    }
  }

  $().ready(function() {
    var elf = $('#elfinder').elfinder({
      // set your elFinder options here
      url: '/elfinder',  // connector URL
      transport : new elFinderSupportVer1(),

      getFileCallback: function(file) { // editor callback
        // file.url - commandsOptions.getfile.onlyURL = false (default)
        // file     - commandsOptions.getfile.onlyURL = true
        FileBrowserDialogue.mySubmit(file); // pass selected file path to TinyMCE
      }
    }).elfinder('instance');
  });
</script>

</body>
</html>

– Sửa file app/assets/application.js với nội dung như sau:

//= require jquery-3.3.1.slim.min
//= require rails-ujs
//= require tinymce
//= require activestorage
//= require turbolinks
//= require_tree .

$(document).ready(function(){

  tinymce.init({
    selector: "textarea.tinymce",
    plugins: [
        "advlist autolink lists link image charmap print preview anchor",
        "searchreplace visualblocks code fullscreen",
        "insertdatetime media table contextmenu paste"
    ],
    toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
    file_browser_callback : elFinderBrowser
  });

  function elFinderBrowser (field_name, url, type, win) {
    tinymce.activeEditor.windowManager.open({
      file: '/admin/media', // use an absolute path!
      title: 'elFinder 2.0',
      width: 900,
      height: 450,
      resizable: 'yes'
    }, {
      setUrl: function (obj) {
        win.document.getElementById(field_name).value = obj.url;
      }
    });
    return false;
  }  
})

– Cuối cùng là đặt TinyMCE ở vị trí thích hợp trong project

<%= f.text_area :post_content, id: 'form-post_content' , class: 'form-control tinymce', rows: 5  %>

Kết quả sau khi tích hợp thành công:

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *