CKEditor and Rails

One reason I really enjoy working with Ruby/Rails is because of the Gems. When you want to integrate a Rails app with some 3rd party utilities, it’s pretty likely that you can find existing Gems doing just that for you (80-20 rule here of course).

I need to integrate CKEditor with my Rails app. Guess what? There’s a ckeditor gem for it! Just follow the VERY good readme to get it installed. For a Rails 3.2 app, you literally just need to add 2 lines or 3 lines of code to have it all set up …

Add it to your Gemfile, and bundle install it

gem 'ckeditor', '3.7.1'

If you want to handle uploads from the editor, stick the following into your ruotes.rb. I didn’t do this myself, because I’m only after text editing.

mount Ckeditor::Engine => "/ckeditor"

Next, in your app’s javascript manifest file, add the following line

//= require ckeditor/init

At this point, it’s done and working (this is the 80% rule)! However for what I needed (the 20%), I did some customisation.

I’m using the awesome simple_form, so I created a little helper method in my application_helper.rb

def rich_text_editor(form, attr)
  form.input(attr, as: :ckeditor, input_html: { class: 'string', customConfig: asset_path('ckeditor_config.js') }).html_safe
end

As you can see, I load a custom ckeditor_config.js. It basically gives me a custom tool bar. Oh! Don’t forget to add ckeditor_config.js to config.assets.precompile list in application.rb.

CKEDITOR.editorConfig = function( config )
{
  config.toolbar = 'MyToolbar';

  config.toolbar_MyToolbar =
      [
        ['Bold', 'Italic','Underline', '-', 'NumberedList', 'BulletedList'],
        ['UIColor','TextColor','BGColor'],
        ['Link', 'Unlink','Anchor'],
        ['Maximize', 'ShowBlocks','-','Source'],
        ['Paste','PasteText','PasteFromWord','-','SpellChecker']
      ];
};

Now, in any of my view files, I use the helper method like this

= simple_form_for @object do |f|
  = rich_text_editor f, :description

All good! Yes, all good on development… Deploy it to staging, it fails miserably. Why? Asset Pipeline again! For Heroku hosted apps (staging and production), I’m using an S3 asset_host for static assets. The CKEditor init script tries to load it from the app’s domain instead…

After reading the ckeditor init script, it’s very easy to fix! Rename the javascript manifest file to application.js.erb, so that we can use Ruby code. Make the manifest require self and add some voodoo to set the CKEDITOR_BASEPATH.

//= require_self
// ...
// your other requires, make sure require_self comes before requiring ckeditor/init
//= require ckeditor/init

(function() {
  <% if Rails.env.production? %>
    window['CKEDITOR_BASEPATH'] = "http://<%= ENV['FOG_DIRECTORY'] %>.s3.amazonaws.com" + "/assets/ckeditor/";
  <% end %>
}).call(this);

That’s it! Why I use ENV['FOG_DIRECTORY'] in the basepath? See my previous posts(1 and 2) for details.

Sweet, all good.

Published: 2012-07-15
blog comments powered by Disqus