Module: TinyMCEHelper

Defined in:
lib/tiny_mce_helper.rb

Overview

Adds helper methods for generating the TinyMCE initialization script within your views

Constant Summary collapse

OPTIONS_FILE_PATH =

The path to the file which contains all valid options that can be used to configure TinyMCE

"#{Rails.root}/config/tiny_mce_options.yml"
DYNAMIC_OPTIONS =

A regular expression matching options that are dynamic (i.e. they can vary on an integer or string basis)

/theme_advanced_buttons|theme_advanced_container/
@@verbose =
true
@@valid_options =
File.exists?(OPTIONS_FILE_PATH) ? File.open(OPTIONS_FILE_PATH) {|f| YAML.load(f.read)} : []

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.install(options = {}) ⇒ Object

Installs TinyMCE by downloading it and adding it to your application’s javascripts folder.

Configuration options:

  • :version - The version of TinyMCE to install. Default is the latest version.

  • :target - The path to install TinyMCE to, relative to the project root. Default is “public/javascripts/tiny_mce”

  • :force - Whether to install TinyMCE, regardless of whether it already exists on the filesystem.

Versions

By default, this will install the latest version of TinyMCE. You can install a specific version of TinyMCE (if you are using an old API) by passing in the version number.

For example,

TinyMCEHelper.install                      # Installs the latest version
TinyMCEHelper.install(:version => '3.2.2') # Installs version 3.2.2

An exception will be raised if the specified version cannot be found.

Target path

By default, this will install TinyMCE into Rails.root/public/javascripts/tiny_mce. If you want to install it to a different directory, you can pass in a parameter with the relative path from Rails.root.

For example,

TinyMCEHelper.install(:target => 'public/javascripts/richtext')

Conflicting paths

If TinyMCE is found to already be installed on the filesystem, a prompt will be displayed for whether to overwrite the existing directory. This prompt can be automatically skipped by passing in the :force option.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/tiny_mce_helper.rb', line 58

def install(options = {})
  options.assert_valid_keys(:version, :target, :force)
  options.reverse_merge!(:force => false)
  
  version = options[:version]
  base_target = options[:target] || 'public/javascripts/tiny_mce'
  source_path = 'tinymce'
  target_path = File.expand_path(File.join(Rails.root, base_target))
  
  # If TinyMCE is already installed, make sure the user wants to continue
  if !options[:force] && File.exists?(target_path)
    print "TinyMCE already installed in #{target_path}. Overwrite? (y/n): "
    while !%w(y n).include?(option = STDIN.gets.chop)
      print "Invalid option. Overwrite #{target_path}? (y/n): "
    end
    
    return if option == 'n'
  end
  
  require 'open-uri'
  
  # Get the latest TinyMCE version
  unless version
    require 'hpricot'
    
    puts 'Finding latest version of TinyMCE to download...' if verbose
    doc = Hpricot(open('http://sourceforge.net/project/showfiles.php?group_id=103281&package_id=111430'))
    file_element = (doc/'tr[@id^="pkg0_1rel0_"] a').detect {|file| file.innerHTML.to_s =~ /tinymce_([\d_]+).zip$/}
    raise ArgumentError, 'Could not find latest TinyMCE version' if !file_element
    
    version = $1. gsub('_', '.')
  end
  
  file_url = "http://prdownloads.sourceforge.net/tinymce/tinymce_#{version.gsub('.', '_')}.zip?download"
  
  # Download the file
  puts "Downloading TinyMCE-#{version} source from #{file_url}..." if verbose
  open(file_url) do |file|
    file_path = file.path
    
    # Extract and install
    puts "Extracting source from #{file_path}..." if verbose
    
    require 'zip/zip'
    require 'zip/zipfilesystem'
    
    Zip::ZipFile.open(file_path) do |zipfile|
      zipfile.entries.each do |entry|
        if match = /jscripts\/tiny_mce\/(.*)/.match(entry.name)
          FileUtils.mkdir_p("#{target_path}/#{File.dirname(match[1])}")
          entry.extract("#{target_path}/#{match[1]}") { true }
        end
      end
    end
    
    puts 'Done!' if verbose
  end
end

.uninstall(options = {}) ⇒ Object

Uninstalls the TinyMCE installation and optional configuration file

Configuration options:

  • target - The path that TinyMCE was installed to. Default is “public/javascripts/tiny_mce”



121
122
123
124
125
126
127
# File 'lib/tiny_mce_helper.rb', line 121

def uninstall(options = {})
  # Remove the TinyMCE configuration file
  File.delete(OPTIONS_FILE_PATH)
  
  # Remove the TinyMCE installation
  FileUtils.rm_rf(options[:target] || "#{Rails.root}/public/javascripts/tiny_mce")
end

.update_optionsObject

Updates the list of possible configuration options that can be used when initializing the TinyMCE script. These are always installed to the application folder, config/tiny_mce_options.yml. If this file does not exist, then the TinyMCE helper will not be able to verify that all of the initialization options are valid.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/tiny_mce_helper.rb', line 134

def update_options
  require 'hpricot'
  require 'open-uri'
  require 'yaml'
  
  puts 'Downloading configuration options from TinyMCE Wiki...' if verbose
  doc = Hpricot(open('http://wiki.moxiecode.com/index.php/TinyMCE:Configuration'))
  options = (doc/'a[@title*="Configuration/"]/').collect {|option| option.to_s}.sort
  options.reject! {|option| option =~ DYNAMIC_OPTIONS}
  
  File.open(OPTIONS_FILE_PATH, 'w') do |out|
    YAML.dump(options, out)
  end
  puts 'Done!' if verbose
end

Instance Method Details

#javascript_include_tiny_mceObject

Generates the javascript include for TinyMCE. For example,

javascript_include_tiny_mce

will generate:

<script type="text/javascript" src="/javascripts/tiny_mce/tiny_mce.js"></script>


249
250
251
# File 'lib/tiny_mce_helper.rb', line 249

def javascript_include_tiny_mce
  javascript_include_tag tiny_mce_file_name
end

#javascript_include_tiny_mce_if_usedObject

Conditionally includes the TinyMCE javascript file if the variable



255
256
257
# File 'lib/tiny_mce_helper.rb', line 255

def javascript_include_tiny_mce_if_used
  javascript_include_tiny_mce if using_tiny_mce?
end

#tiny_mce(*args) ⇒ Object

Generate the TinyMCE. Any arguments will be passed to tiny_mce_init_script.



230
231
232
# File 'lib/tiny_mce_helper.rb', line 230

def tiny_mce(*args)
  javascript_tag tiny_mce_init_script(*args)
end

#tiny_mce_file_nameObject

The name of the TinyMCE javascript file to use. In development, this will use the source (uncompressed) file in order to help with debugging issues that occur within TinyMCE. In production, the compressed version of TinyMCE will be used in order to increased download speed.



238
239
240
# File 'lib/tiny_mce_helper.rb', line 238

def tiny_mce_file_name
  Rails.env == 'development' ? 'tiny_mce/tiny_mce_src' : 'tiny_mce/tiny_mce'
end

#tiny_mce_init_script(options = @tiny_mce_options) ⇒ Object

Create the TinyMCE initialization scripts. The default configuration is for a simple theme that replaces all textareas on the page. For example, the default initialization script will generate the following:

tinyMCE.init({
  'mode' : 'textareas',
  'theme' : 'simple'
});

Customizing initialization options

To customize the options to be included in the initialization script, you can pass in a hash to tiny_mce_init_script. For example,

tiny_mce_init_script(
  :theme => 'advanced',
  :editor_selector => 'rich_text',
  :content_css => '/stylesheets/tiny_mce_content.css',
  :editor_css => '/stylesheets/tiny_mce_editor.css',
  :auto_reset_designmode => true
)

will generate:

tinyMCE.init({
  'mode' : 'textareas',
  'theme' : 'advanced',
  'editor_selected' : 'rich_text',
  'content_css' : '/stylesheets/tiny_mce_content.css'
});

Validating options

If additional options are passed in to initialize TinyMCE, they will be validated against the list of valid options in TinyMCEHelper#valid_options. These options are configured in the file config/tiny_mce_options.yml. You can generate this file by invoke the rake task tiny_mce:update_options.



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/tiny_mce_helper.rb', line 193

def tiny_mce_init_script(options = @tiny_mce_options)
  options ||= {}
  options.stringify_keys!.reverse_merge!(
    'mode' => 'textareas',
    'theme' => 'simple'
  )
  
  # Check validity
  plugins = options['plugins']
  options_to_validate = options.reject {|option, value| plugins && plugins.include?(option.split('_')[0]) || option =~ DYNAMIC_OPTIONS}
  options_to_validate.assert_valid_keys(@@valid_options) if @@valid_options && @@valid_options.any?
  
  init_script = 'tinyMCE.init({'
  
  options.sort.each do |key, value|
    init_script += "\n#{key} : "
    
    case value
      when String, Symbol, Fixnum
        init_script << "'#{value}'"
      when Array
        init_script << "'#{value.join(',')}'"
      when TrueClass
        init_script << 'true'
      when FalseClass
        init_script << 'false'
      else
        raise ArgumentError, "Cannot parse value of type #{value.class} passed for TinyMCE option #{key}"
    end
    
    init_script << ','
  end
  
  init_script.chop << "\n});"
end

#using_tiny_mce?Boolean

Is TinyMCE being used?

Returns:

  • (Boolean)


152
153
154
# File 'lib/tiny_mce_helper.rb', line 152

def using_tiny_mce?
  @uses_tiny_mce
end