目前ckeditor本身是可以通过js直接配置的,也就是说无关后台语言,拷贝过来就可以直接使用。但是之所以还要通过第三方插件整合CKeditor是因为一般需要文本编辑的时候肯定会包含图片的,正常情况下图片上传是需要走后台的,而官方的CKfinder本身是要收费的,所以需要一个第三方插件将CKeditor和一个图片上传的功能整合起来,这里我采用的插件是galetahub的CKeidtor插件。

【1】install CKeditor

在Gemfile中配置CKeditor插件

 //Gemfile
gem "paperclip"
gem 'ckeditor'
gem 'responders'

这里需要引入三个插件,paperclip、ckeditor和responders,其中paperclip是一个图片上传插件,ckeditor就不多说了,responders提供了一些response模块可以简化代码,在ckeditor和paperclip衔接的模块需要依赖,所以也要安装。 执行命令安装插件 $ bundle install

【2】Add table to your database

执行如下命令生成migration以及models文件 rails g ckeditor:install --orm=active_record --backend=paperclip 命令成功后会在你的db/migration目录下生成一个ckeditor_assets文件,执行 $ rake db:migrate 自动化建立ckeditor_assets表,这个表是用来存储你再进行文本编辑时上传的图片的。 之前的命令,除了生成migration文件外还会在models目录下创建一个ckeditor目录,目录下会有三个实体,查看可以发现一个是asset实体,另外两个分别是文件和图片的实体,大体可以知道这个是ckeditor插件用来自动维护上传的图片和文件所需的models,你可以修改has_attached_file 来定义文件存放的路径,默认情况下是存放在public/ckeditor_assets目录下的。 到目前为止初始化工作就差不多了。

【3】final work

接下来做一些资源文件的配置。 首先创建我们将会用到的一些js文件,在app/assets/javascripts目录下创建ckeditor文件夹并创建一个config.js文件(这里config.js文件有点长不方便阅读,完整的代码我就放在最后的附录里了。)

if (typeof(CKEDITOR) != 'undefined') {
    CKEDITOR.editorConfig = function(config) { 
		//... some config here
	};
}

之后在application.js中引入这个文件,同时引入ckeditor的初始化文件

//= require ckeditor/init
//= require ckeditor/config

采用这种方式的话就不需要在application.html.erb中引入ckeditor.js并写初始化js代码了。 这个时候可以在_form中使用ckeditor了。

<%= f.cktext_area :content, :class => 'class_name', :ckeditor => {:language => 'zh-cn', :toolbar => 'Full' } 

这里你可以用symbol配置语言和工具栏,你也可以用config.js默认配置的选项。 这样你就可以用ckeditor进行编辑并存储为html代码了,最后说明下显示的时候如何将html代码渲染成图文到页面

 <%= raw(@message.content) %>

在你要显示的内容前用raw方法转换下就ok了。

【4】附录

####app/assets/javascript/ckeditor/config.js

/*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
if (typeof(CKEDITOR) != 'undefined') {
    CKEDITOR.editorConfig = function(config) {
        // Define changes to default configuration here. For example:
        config.language = 'zh-cn';
        // config.uiColor = '#AADC6E';
        /* Filebrowser routes */
        // The location of an external file browser, that should be launched when "Browse Server" button is pressed.
        config.filebrowserBrowseUrl = "/ckeditor/attachment_files";

        // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Flash dialog.
        config.filebrowserFlashBrowseUrl = "/ckeditor/attachment_files";

        // The location of a script that handles file uploads in the Flash dialog.
        config.filebrowserFlashUploadUrl = "/ckeditor/attachment_files";

        // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Link tab of Image dialog.
        config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";

        // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Image dialog.
        config.filebrowserImageBrowseUrl = "/ckeditor/pictures";

        // The location of a script that handles file uploads in the Image dialog.
        config.filebrowserImageUploadUrl = "/ckeditor/pictures";

        // The location of a script that handles file uploads.
        config.filebrowserUploadUrl = "/ckeditor/attachment_files";

        config.allowedContent = true;

        // Rails CSRF token
        config.filebrowserParams = function() {
            var csrf_token, csrf_param, meta, metas = document.getElementsByTagName('meta'),
            params = new Object();

            for (var i = 0; i < metas.length; i++) {
                meta = metas[i];

                switch (meta.name) {
                case "csrf-token":
                    csrf_token = meta.content;
                    break;
                case "csrf-param":
                    csrf_param = meta.content;
                    break;
                default:
                    continue;
                }
            }

            if (csrf_param !== undefined && csrf_token !== undefined) {
                params[csrf_param] = csrf_token;
            }

            return params;
        };

        config.addQueryString = function(url, params) {
            var queryString = [];

            if (!params) {
                return url;
            } else {
                for (var i in params) queryString.push(i + "=" + encodeURIComponent(params[i]));
            }

            return url + ((url.indexOf("?") != -1) ? "&": "?") + queryString.join("&");
        };

        // Integrate Rails CSRF token into file upload dialogs (link, image, attachment and flash)
        CKEDITOR.on('dialogDefinition',
        function(ev) {
            // Take the dialog name and its definition from the event data.
            var dialogName = ev.data.name;
            var dialogDefinition = ev.data.definition;
            var content, upload;

            if (CKEDITOR.tools.indexOf(['link', 'image', 'attachment', 'flash'], dialogName) > -1) {
                content = (dialogDefinition.getContents('Upload') || dialogDefinition.getContents('upload'));
                upload = (content == null ? null: content.get('upload'));

                if (upload && upload.filebrowser && upload.filebrowser['params'] === undefined) {
                    upload.filebrowser['params'] = config.filebrowserParams();
                    upload.action = config.addQueryString(upload.action, upload.filebrowser['params']);
                }
            }
        });

        // Toolbar groups configuration.
        config.toolbar = [{
            name: 'document',
            groups: ['mode', 'document', 'doctools'],
            items: ['Source']
        },
        {
            name: 'clipboard',
            groups: ['clipboard', 'undo'],
            items: ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo']
        },
        // { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ], items: [ 'Find', 'Replace', '-', 'SelectAll', '-', 'Scayt' ] },
        // { name: 'forms', items: [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] },
        {
            name: 'links',
            items: ['Link', 'Unlink', 'Anchor']
        },
        {
            name: 'insert',
            items: ['Image', 'Flash', 'Table', 'HorizontalRule', 'SpecialChar']
        },
        {
            name: 'paragraph',
            groups: ['list', 'indent', 'blocks', 'align', 'bidi'],
            items: ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock']
        },
        '/', {
            name: 'styles',
            items: ['Styles', 'Format', 'Font', 'FontSize']
        },
        {
            name: 'colors',
            items: ['TextColor', 'BGColor']
        },
        {
            name: 'basicstyles',
            groups: ['basicstyles', 'cleanup'],
            items: ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat']
        }];

        config.toolbar_mini = [{
            name: 'paragraph',
            groups: ['list', 'indent', 'blocks', 'align', 'bidi'],
            items: ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock']
        },
        {
            name: 'styles',
            items: ['Font', 'FontSize']
        },
        {
            name: 'colors',
            items: ['TextColor', 'BGColor']
        },
        {
            name: 'basicstyles',
            groups: ['basicstyles', 'cleanup'],
            items: ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat']
        },
        {
            name: 'insert',
            items: ['Image', 'Table', 'HorizontalRule', 'SpecialChar']
        }];
    };
}