Let us say you want to use the Paperclip plugin to process images, and WYSIWYG editor like CKEditor to enter rich text. How do you integrate both, CKEditor and Paperclip? You will need to write a custom file uploader and custom file browser, and connect them to the editor by specifying urls and callback functions.

Well, first you need to install them. Installing Paperclip in your app is simple, just add the gem or plugin and follow the README. Adding a CKEditor to your Rails app without a plugin is easy, too: download it, place all the files of the Zip file in the javascripts/ckeditor sub directory, and write a bit JavaScript code which replaces textareas by CKEditor instances. Connecting CKeditor (at the frontend) to Paperclip (at the backend) is a bit tricky. There are several possibilities:

  1. You can upload the image files traditionally with file upload fields, and paste the links in the CKEditor yourself, manually
  2. You can upload the image files traditionally with file upload fields and offer only a custom filebrowser url for the CKEditor. Then the CKEditor only needs to paste a link to an existing image.
  3. The CKEditor starts the upload. You can offer a custom fileupload url for CKEditor, if you have defined a special function to handle the upload. You can configure CKEditor so that it sends the image file to your application. Your app must store it and give an URL back. CKEditor then uses this URL to paste a link in the text.

The connection between CKEditor and your app are two urls, a custom fileupload url (POST) and a custom filebrowser URL (GET). The first is used to upload an image, the second to browse already available images. These custom browser/uploader urls must be registered at the CKEditor when you instantiate it. You can pass the right URLs by specifying options for the editor, for instance by calling CKEDITOR.replace(elementOrIdOrName, config) with appropriate configuration options that specify the urls. An example would be

load_ckeditor({filebrowserUploadUrl:UploadUrl,filebrowserBrowseUrl:BrowseUrl});

if load_ckeditor is the Javascript functions which replaces the elements with a CKEditor instance:

   function load_ckeditor(options){
     if ($('textarea').length > 0)
     {       
       var data = $('textarea');
       $.each(data, function(i)
       {
         CKEDITOR.replace(data[i].id,options);
       }
       );     
     }
    }      

If you have a class Image < ActiveRecord::Base which uses Paperclip and has_attached_file :data, a suitable controller action for a fileupload url would be

      def upload_image
        @func_num = params["CKEditorFuncNum"]
        @ck_editor = params["CKEditor"]
        if params.include?(:upload)
          data = params.delete(:upload)
          @image = Image.create({:data => data}) if data.present?
        end
        render :layout => false
      end

Your action will receive a parameter CKEditorFuncName which specifies the callback function of the CKEditor.
The corresponding HAML page `upload_image.html.haml` displays the image and calls the CKEditor callback function specified by the parameter:

    - if @image
      = image_tag @image.data.url
      :javascript
        CKEditorFuncNum = #{@func_num};
        function SetUrl( fileUrl )
        {
          window.parent.CKEDITOR.tools.callFunction(CKEditorFuncNum, fileUrl);
        }
        SetUrl("#{ @image.data.url }");

The code for the custom file browser is similar, you only have to display multiple images and call window.opener.CKEDITOR.. instead of window.parent.CKEDITOR.. if an image is selected.

Advertisements