Amit Solanki

Avatar

A Ruby On Rails Programmer from India

How to toggle tinymce editor in rails

TinyMCE is an excellent WYSIWYG editor. The same can be used in rails with this plugin. In many cases, we need to toggle tinymce editor on/off. For this add the following lines to tiny_mce_helper.rb file of your plugin just before javascript_tag tinymce_js line in tiny_mce_init method.

tinymce_js += %Q! function toggleEditor(id) {
    if (\!tinyMCE.getInstanceById(id))
        tinyMCE.execCommand('mceAddControl', false, id);
    else
        tinyMCE.execCommand('mceRemoveControl', false, id);
    }
    !

And you can easily place a link beside your editor to toggle something similar to:

<%= link_to_function "Add/Remove Editor", "toggleEditor('name')" %>

Here name is the name of the textarea/textbox to which you are applying tinymce editor.

Recent releases of tinymce would require to use tinyMCE.get(id) instead of getInstanceById(id) in code above.

Explicitly expiring timed_fragment_cache

One of the available plugins for time based fragment caching is timed_fragment_cache by Richard Livsey. A mirror for the plugin is available here at GitHub.

One of the limitation of the plugin is the inability to explicitly expire fragment cache, specifically in our sweeper. The method expire_fragment just clears the cache file but corresponding meta file which stores the time of expiration remains. You can add the following to your environment.rb to clear the meta file and explicitly expire cache in addition to automatic timed expiration feature offered by plugin.

module ActionController
  module Caching
    module TimedFragment
      def expire_meta_fragment(name)
        expire_fragment(meta_fragment_key(name))
      end
    end
  end
end

Now, in sweepers just call this new method along with expire_fragment method.

class ArticleSweeper < ActionController::Caching::Sweeper
  observe Article # This sweeper is going to keep an eye on the Article model

  # If our sweeper detects that an article was created call this
  def after_save(article)
    expire_cache_for(article)
  end

  # If our sweeper detects that an article was deleted call this
  def after_destroy(article)
    expire_cache_for(article)
  end

  private

  def expire_cache_for(record)
    # Expire the fragments now that we posted a new article entry
    expire_fragment({:controller => 'articles', :action => 'index'})
    expire_meta_fragment({:controller => 'articles', :action => 'index'})
  end
end

Specifying path for tidy rubygem

HTML Tidy is a library used to fix invalid HTML and give the source code a reasonable layout. It was developed by Dave Raggett of W3C, and is now maintained as a Sourceforge project. These are several versions of tidy available for various operating system. But the quickest way(not always easiest) to install on various unix systems are given below.

On debian based OS such as ubuntu, use apt-get to install

apt-get install tidy

On RPM based OS like fedora centOS, use yum to install

yum install tidy

On mac os x, use macports to install

port install tidy

For tidy to be used in ruby, a rubygem is available here. Just fire up gem install tidy to get it installed on your development machine. A nice documentation is provided here for reference.

gem install tidy

Usage:

  require 'tidy'
  Tidy.path = '/usr/lib/tidylib.so'
  html = 'Body'
  xml = Tidy.open(:show_warnings=>true) do |tidy|
    tidy.options.output_xml = true
    puts tidy.options.show_warnings
    xml = tidy.clean(html)
    puts tidy.errors
    puts tidy.diagnostics
    xml
  end
  puts xml

While I was working on tidy on my mac, I noticed the Tidy.path variable explained above did not work for me. I figured out an equivalent path to be used on mac,

  Tidy.path = '/usr/lib/libtidy.A.dylib'

Similar was the case with my production servers hosted on fedora/CentOS, I had to modify my path as

  Tidy.path = '/usr/lib/libtidy-0.99.so.0'

To use both paths on my development and production environment, I modified the line 2 in the example above as

  begin
    Tidy.path = '/usr/lib/libtidy-0.99.so.0'
  rescue LoadError
    Tidy.path = '/usr/lib/libtidy.A.dylib'
  end

Update:
If you’re getting the error:

/opt/ruby/ruby-1.8.6/lib/ruby/gems/1.8/gems/tidy-1.1.2/lib/tidy/tidybuf.rb:40: [BUG] Segmentation fault

Apply the following patch to fix it.

Before you go

Going so soon? May these links be a guide to web enlightenment.