虽然打成Gem的富文本编辑不少,但我喜欢的一个木有。
勉强用的话,我会选ckeditor,但是它「太大,麻烦,颜值低」。
我喜欢的是这样的编辑器是长这样的:
wangeditor
rubygems中有个老版本,一年多没有跟新了,给作者发邮件,提issue都没有回复。不排除加班那啥的可能。
所以,每次使用,我都得
- 下载js
- require
- 写html和js
心累。
一直想写自己写一个Gem,把上面的123全都躲开。
但是技能树一直没有点到,找到的教程又多是简单介绍一下,完全不肯深入,给我带来了好几次从入门到放弃的体验。
今天,放弃的所谓的「未知解释未知」,直接选择了有逼格的(不要脸的)模仿(抄袭),像吃奥利奥一样「抄一抄,改一改,点一点」,终于终于弄出了wangeditor_rails。
得到的结论就是,我不愧是一个山寨大国里面的人。没有好的教材,没有找到老师,抄袭绝逼是学习的好方法。书抄百遍,其义自见。
下面记录一下,写Gem的步骤,一来备忘,二来看看是不是有谁会搜到。
创建Gem的框架
我没有是用bundle,而是使用的rails生成Gem的框架
rails plugin new Gem的名字
使用rails生成有一个好处,它会自动在test目录生成一个dummy的rails项目并在这个项目中引用你写得Gem。
下载wangEditor.js
直接
yarn init
yarn install wangeditor
填写.gemspec文件
这个文件是Gem的说明呀,git repo呀,什么的,设置一下就OK
创建生成器
生成器就是平时我们敲rails g XXX的那个东西
使用devise,simple_form的使用,我们都使用过。
创建的这个生成器的目的就是当敲入rails g wangeditor_rails:install
的时候,将wangEditor.js拷贝到app/assets/javascripts中
# lib/generators/wangeditor/install/install_generator.rb
module Wangeditor
class InstallGenerator < Rails::Generators::Base
┆ JAVASCRIPTS_FILE = "app/assets/javascripts/wangEditor.js"
┆ source_root File.expand_path("../../../../../", __FILE__)
┆ def copy_javascripts
copy_file 'node_modules/wangeditor/release/wangEditor.js', JAVASCRIPTS_FILE
┆ end
end
end
创建表单Helper
这样在代码是为了在view中使用<%= f.wangeditor :content %>
# lib/wangeditor_rails/helper.rb
module WangeditorRails
module Helper
def wangeditor(name, method, options = {})
content = options[:object][method]
id = options[:id] || "#{name}_#{method}"
name = "#{name}[#{method}]"
#puts options
output_buffer = ActiveSupport::SafeBuffer.new
output_buffer << hidden_area(id, content, name)
output_buffer << display_area(id, content)
output_buffer << javascript_tag(create_scripts(id))
end
def hidden_area(id, content, name)
content_tag :div, text_area_tag(id, content, name: name), style: 'display: none;'
end
def display_area(id, content)
unless content.nil?
content = sanitize content
end
content_tag(:div, content, id: "#{id}_editor")
end
def create_scripts(id)
"var E = window.wangEditor
var editor = new E('##{id}_editor')
editor.customConfig.onchange = function (content) {
document.getElementById('#{id}').value = content
}
editor.create()"
end
end
module Builder
def wangeditor(method, options = {})
@template.send("wangeditor", @object_name, method, objectify_options(options))
end
end
end
绑定SimpleForm调用
这样在代码是为了在view中使用<%= f.input :content, as: :wangeditor %>
# lib/wangeditor_rails/simple_form.rb
module WangeditorRails
module SimpleForm
class WangeditorInput < ::SimpleForm::Inputs::Base
def input(wrapper_options)
@builder.wangeditor(attribute_name, input_html_options)
end
end
end
end
::SimpleForm::FormBuilder.map_type :wangeditor, :to => WangeditorRails::SimpleForm::WangeditorInput
在rails引用
上面写得表单方法不能直接使用,需要往rails里「注册」一下
# lib/wangeditor_rails/engine.rb
require "wangeditor_rails"
require "rails"
module WangeditorRails
class Engine < Rails::Engine
initializer "wangeditor_rails.helper_and_builder" do
ActiveSupport.on_load :action_view do
ActionView::Base.send(:include, WangeditorRails::Helper)
ActionView::Helpers::FormBuilder.send(:include, WangeditorRails::Builder)
end
end
initializer "wangeditor_rails.simple_form" do
require "wangeditor_rails/simple_form" if Object.const_defined?("SimpleForm")
end
end
end
在Gem核心文件中引用
# lib/wangeditor_rails.rb
require 'wangeditor_rails/engine'
require 'wangeditor_rails/helper'
module WangeditorRails
end
网友评论