之前在rails开发中使用了ckeditor作为可视化编辑器,不过感觉ckeditor过于庞大,有很多不需要的功能,而且图片上传功能不好控制不同用户可以互相删除图片,感觉很不好。于是考虑更改可视化编辑器,多方考虑选择了bootstrap3-wysiwyg,但是这个编辑器无法实现图片上传功能,还有换行使用br而不是p标签不是很好。于是考虑自定义完善其功能。
个人原创,版权所有,转载请注明原文出处,并保留原文链接:
https://www.embbnux.com/2015/03/17/rails_use_bootstrap3-wysiwyg_with_carrierwave_picture_upload
一 bootstrap3-wysiwyg安装
这里使用bootstrap-wysihtml5-rails集成到rails中,安装和配置具体见该github.
在gemfile添加: gem ‘bootstrap-wysihtml5-rails‘,bundle install安装。
在app/assets/stylesheets/application.css添加
1
|
*= require bootstrap-wysihtml 5
|
在app/assets/javascripts/application.js里添加
1
2
|
//= require bootstrap-wysihtml5 //= require bootstrap-wysihtml5/locales/zh-CN |
在要使用编辑器的地方添加”class=’wysihtml5′”,比如:
1
|
= f.text_area :content , class : "wysihtml5"
|
然后在js文件里面初始化编辑器:
1
2
3
4
5
6
7
8
9
|
$( '.wysihtml5' ).each( function (i, elem) {
$(elem).wysihtml5({
toolbar: {
"color" : true ,
"size" : 'sm'
},
"locale" : 'zh-CN' ,
});
});
|
这样应该就可以了但是现在没办法实现图片上传,图片只能够插入链接的方式,如下
上传图片功能还是很重要的,幸亏bootstrap3-wysiwyg提供了很好的扩展功能,可以自己实现上传功能.
二 使用carrierwave实现图片上传功能
首先要修改编辑器的图片弹窗,js配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
$(document).ready( function (){
var csrf_token = $( 'meta[name=csrf-token]' ).attr( 'content' );
var csrf_param = $( 'meta[name=csrf-param]' ).attr( 'content' );
var customTemplates = {
image : function (context) {
var locale = context.locale;
var options = context.options;
return "<li>" +
"<div class='bootstrap-wysihtml5-insert-image-modal modal fade' data-wysihtml5-dialog='insertImage'>" +
"<div class='modal-dialog'>" +
"<div class='modal-content'>" +
"<div class='modal-header'>" +
" <a class='close' data-dismiss='modal'>×</a>" +
"<h3>" + locale.image.insert + "</h3>" +
"</div>" +
"<div class='modal-body'>" +
"<div class='upload-picture'>" +
"<form accept-charset='UTF-8' action='/images/upload' class='form-horizontal' id='wysiwyg_image_upload_form' method='post' enctype='multipart/form-data'>" +
"<div style='display:none'>" +
"<input name='utf8' value='✓' type='hidden'></input>" +
"<input name='" + csrf_param + "' value='" + csrf_token + "' type='hidden'></input>" +
"</div>" +
"<div class='form-group'>" +
"<div class='col-xs-9 col-md-10'>" +
"<input value='' accept='image/jpeg,image/gif,image/png' class='form-control' id='wysiwyg_image_picture' name='image[picture]' type='file' required='required'></input>" +
"</div>" +
"<div class='col-xs-3 col-md-2'>" +
"<input class='btn btn-primary' id='wysiwyg_image_submit' name='commit' type='submit' value='上传'></input>" +
"</div>" +
"</div>" +
"</form>" +
"</div>" +
"<div class='form-group'>" +
"<input value='http://' id='bootstrap-wysihtml5-picture-src' class='bootstrap-wysihtml5-insert-image-url form-control' data-wysihtml5-dialog-field='src'>" +
"</div>" +
"<div id='wysihtml5_upload_notice'>" +
"</div>" +
"</div>" +
"<div class='modal-footer'>" +
"<a href='#' class='btn btn-default' data-dismiss='modal'>" + locale.image.cancel + "</a>" +
"<a class='btn btn-primary' data-dismiss='modal' data-wysihtml5-dialog-action='save' href='#'>" + locale.image.insert + "</a>" +
"</div>" +
"</div>" +
"</div>" +
"</div>" +
"<a class='btn btn-sm btn-default' data-wysihtml5-command='insertImage' title='" + locale.image.insert + "' tabindex='-1'><span class='glyphicon glyphicon-picture'></span></a>" +
"</li>" ;
}
};
$( '.wysihtml5' ).each( function (i, elem) {
$(elem).wysihtml5({
toolbar: {
"color" : true ,
"size" : 'sm'
},
"locale" : 'zh-CN' ,
customTemplates: customTemplates
});
});
}) |
这样编辑器图片弹窗就会变成下面这样:
这只是前端view,controller和model层都得再实现
MODEL: Image
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#migration: def change
create_table :images do |t|
t.string :picture
t.string :title , default: 'www.embbnux.com'
t.references :user , index: true
t.timestamps
end
end
#model class Image < ActiveRecord::Base
belongs_to :user
mount_uploader :picture , PictureUploader
validates :user_id , presence: true
validates :title , length: { maximum: 250 }
end |
这里的图片上传使用carrierwave,具体使用请见该github readme
Controller:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#routes post "/images/upload" => "images#upload"
#controller class ImagesController < ApplicationController
before_action :logged_in_user
def upload
@image = current_user.images.build(images_params)
image_url = ""
if @image .save
image_url = "http://" << ENV [ "HOME_URL" ] << @image .picture.url
status = "上传成功!点击插入图片按钮插入."
else
status = "上传失败!"
end
respond_to do |format|
format.json { render :json =>{ :image_url => image_url, :status => status} }
end
end
private
def images_params
params.require( :image ).permit( :picture )
end
end |
这里的controller我使用ajax提交post代码,这样体验比较好,上传成功后把图片的地址传回客户端,自动放在原来的插入图片链接处:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
$( '#wysiwyg_image_upload_form' ).on( 'submit' , function (event){
event.stopPropagation();
event.preventDefault();
$( '#wysiwyg_image_submit' ).val( 'Uploading' );
var wysiwyg_file = $( '#wysiwyg_image_picture' )[0].files[0];
var wysiwyg_formData = new FormData();
wysiwyg_formData.append( 'utf8' , "✓" );
wysiwyg_formData.append(csrf_param, csrf_token);
wysiwyg_formData.append( 'image[picture]' , wysiwyg_file,wysiwyg_file.name);
$.ajax({
url: '/images/upload' ,
type: 'POST' ,
data: wysiwyg_formData,
dataType: 'json' ,
processData: false ,
contentType: false ,
success: function (data, textStatus, jqXHR)
{
$( '#wysiwyg_image_submit' ).val( '上传' );
$( '#wysiwyg_image_picture' ).val( '' );
$( '#bootstrap-wysihtml5-picture-src' ).val(data.image_url);
},
error: function (jqXHR, textStatus, errorThrown)
{
}
});
|
这样上传功能基本就完成了,ajax关键要提供csrf-token参数,其他都没问题
最终效果可以到我开发的网站看: huaborn.com
三 替换br标签为p标签
这个编辑器如果你键盘按回车键,他是自动加入br标签,感觉比较丑,段落之间还是使用p比较好看
无意中发现要是原来文本编辑器里存在<p></p>它换行就会自动添加p标签而不是br标签。
所以最终使用下面代码实现:
1
2
3
4
5
6
7
8
9
10
11
12
|
$( '.wysihtml5' ).each( function (i, elem) {
$(elem).wysihtml5({
toolbar: {
"color" : true ,
"size" : 'sm'
},
"locale" : 'zh-CN' ,
customTemplates: customTemplates
});
var input_text = $(elem).html();
$(elem).html(input_text+ "<p> </p>" );
});
|