Tiếp tục series bài viết về Ruby On Rails, hôm nay vinasupport.com sẽ hướng dẫn các bạn tích hợp bộ soạn thảo TinyMCE 4.x và trình quản lý file elFinder 2.x trong Rails 5.
Bộ soạn thảo TinyMCE
Trong một project, nếu bạn muốn quản lý nội dung, description của 1 sản phẩm hay 1 bài viết thì các bạn cần 1 bộ soạn thảo để mang lại nội dung trực quan hơn cho người đọc. TinyMCE là một bộ soạn thảo nội dung như thế (WYSIWYG editor).
Trình quản lý file elFinder
elFinder là một trình quản lý file và thư mục rất mạnh với các chức năng về upload file, cắt file, giải nén file… Đặc biệt bạn có thể tích hợp nó vào bộ soạn thảo TinyMCE, vì bộ quản lý file đi kèm với TinyMCE để sử dụng thì các bạn phải trả tiền. Vì vậy giải pháp sử dụng elFinder là hoàn toàn miễn phí.
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:
Nguồn: vinasupport.com