ckeditor 3.2.1 → 3.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. data/README.rdoc +136 -0
  2. data/app/controllers/ckeditor_controller.rb +5 -4
  3. data/app/helpers/ckeditor_helper.rb +2 -18
  4. data/app/views/ckeditor/_asset.html.erb +15 -0
  5. data/app/views/ckeditor/files.html.erb +1 -1
  6. data/app/views/ckeditor/images.html.erb +1 -1
  7. data/app/views/layouts/ckeditor.html.erb +0 -1
  8. data/lib/ckeditor.rb +20 -0
  9. data/lib/ckeditor/engine.rb +11 -0
  10. data/lib/ckeditor/formtastic.rb +12 -0
  11. data/lib/ckeditor/middleware.rb +18 -0
  12. data/lib/ckeditor/version.rb +1 -1
  13. data/lib/ckeditor/view_helper.rb +40 -63
  14. data/lib/generators/USAGE +17 -0
  15. data/lib/generators/{ckeditor_generator.rb → ckeditor_core_generator.rb} +2 -7
  16. data/lib/generators/ckeditor_models_generator.rb +41 -0
  17. data/lib/generators/templates/ckeditor.rb +3 -2
  18. data/lib/generators/templates/ckeditor/swfupload/fileprogress.js +2 -20
  19. data/lib/generators/templates/ckeditor/swfupload/swfupload.js +1 -980
  20. data/lib/generators/templates/ckeditor/swfupload/swfupload.queue.js +1 -98
  21. data/lib/generators/templates/ckeditor/swfupload/swfupload.swf +0 -0
  22. data/lib/generators/templates/models/attachment_fu/asset.rb +32 -0
  23. data/lib/generators/templates/models/attachment_fu/attachment_file.rb +24 -0
  24. data/lib/generators/templates/models/attachment_fu/migration.rb +30 -0
  25. data/lib/generators/templates/models/attachment_fu/picture.rb +25 -0
  26. data/lib/generators/templates/models/paperclip/asset.rb +86 -0
  27. data/lib/generators/templates/models/paperclip/attachment_file.rb +40 -0
  28. data/lib/generators/templates/models/paperclip/migration.rb +31 -0
  29. data/lib/generators/templates/models/paperclip/picture.rb +23 -0
  30. metadata +21 -13
  31. data/README.textile +0 -225
  32. data/TODO +0 -3
  33. data/app/views/ckeditor/_file.html.erb +0 -15
  34. data/app/views/ckeditor/_image.html.erb +0 -15
  35. data/lib/ckeditor/file_storage.rb +0 -178
@@ -0,0 +1,136 @@
1
+ =Rails CKEditor integration plugin with SWFUpload support
2
+
3
+ CKEditor is a text editor to be used inside web pages. It's a WYSIWYG editor, which means that the text being edited on it looks as similar as possible to
4
+ the results users have when publishing it. It brings to the web common editing features found on desktop editing applications like Microsoft Word and OpenOffice.
5
+
6
+ Because CKEditor is licensed under flexible Open Source and commercial licenses, you'll be able to integrate and use it inside any kind of application.
7
+ This is the ideal editor for developers, created to provide easy and powerful solutions to their users.
8
+
9
+ CKEditor version: 3.2.1 (http://ckeditor.com)
10
+
11
+ SWFUpload version: 2.2.0.1 Core (http://swfupload.org)
12
+
13
+ Rails version: 3.0.0.beta3
14
+
15
+ Demo appication (Rails 2.3.x):
16
+ http://github.com/galetahub/rails-ckeditor-demo-app
17
+
18
+ ==Install
19
+
20
+ ===Rails 3
21
+
22
+ In your appication "Gemfile":
23
+ gem 'ckeditor', '3.2.3'
24
+
25
+ Next step is generate ckeditor js files and configuration file
26
+ Check "config/initializers/ckeditor.rb" for more configuration options:
27
+ rails generate ckeditor_core
28
+
29
+ Generate ckeditor models for file upload support:
30
+ For paperclip:
31
+ rails generate ckeditor_models
32
+
33
+ For attachment_fu:
34
+ rails generate ckeditor_models --backend=attachment_fu
35
+
36
+ Don't forget about migration:
37
+ rake db:migarte
38
+
39
+ ===Rails 2.3.x
40
+
41
+ Install plugin:
42
+ ./script/plugin install git://github.com/galetahub/rails-ckeditor.git
43
+
44
+ Generate ckeditor core files:
45
+ rake ckeditor:install
46
+
47
+ This rake generated file config/ckeditor.yml:
48
+ rake ckeditor:config
49
+
50
+ For attachment_fu option "swf_file_post_name" must be "uploaded_data".
51
+
52
+ ==Usage
53
+
54
+ Basically include this in the page you wish to use the editor in:
55
+ <%= javascript_include_tag :ckeditor %>
56
+
57
+ Then instead of the normal textarea helper from Rails use this one:
58
+ <%= ckeditor_textarea("object", "field", :width => '100%', :height => '200px') %>
59
+
60
+ FormBuilder helper for more usefully:
61
+
62
+ <%= form_for @page do |form| -%>
63
+ ...
64
+ <%= form.cktext_area :notes, :toolbar=>'Full', :width=>'400px', :heigth=>'200px' %>
65
+ ...
66
+ <%= form.cktext_area :content, :swf_params=>{:assetable_type=>'User', :assetable_id=>current_user.id} %>
67
+ ...
68
+ <% end -%>
69
+
70
+ ===Support options
71
+ :cols # Textarea cols (default: 70)
72
+ :rows # Textarea rows (default: 20)
73
+ :width # Editor width (default: 100%)
74
+ :height # Editor height (default: 100%)
75
+ :class # Textarea css class name
76
+ :toolbar # Toolbar name
77
+ :skin # Editor skin
78
+ :language # Editor language (default: I18n.locale)
79
+ :swf_params # SWFUpload additional params (Hash)
80
+ :id # textarea DOM element id
81
+
82
+ For configure ckeditor default options check:
83
+ public/javascripts/ckeditor/config.js
84
+
85
+ This stylesheet use editor for displaying edit area:
86
+ public/javascripts/ckeditor/contents.css
87
+
88
+ ===AJAX
89
+
90
+ To use a remote form you need to call "ckeditor_ajax_script" helper method:
91
+
92
+ <%= form_for @page, :remote => true do |form| -%>
93
+ <%= form.cktext_area("note", "content") %>
94
+ ...
95
+ <%= form.cktext_area("note", "about") %>
96
+ ...
97
+ <%= ckeditor_ajax_script %>
98
+ <% end %>
99
+
100
+ Helper "ckeditor_ajax_script" generate next script (jquery):
101
+
102
+ <script type='text/javascript' charset='UTF-8'>
103
+ $(document).ready(function(){
104
+ $('form[data-remote]').bind("ajax:before", function(){
105
+ for (instance in CKEDITOR.instances){
106
+ CKEDITOR.instances[instance].updateElement();
107
+ }
108
+ });
109
+ });
110
+ </script>
111
+
112
+ ==File uploads
113
+
114
+ We recommend using a paperclip plugin for file storage and processing images. Controller @../rails-ckeditor/app/controllers/ckeditor_controller.rb@ has actions
115
+ for displaying and uploading files. It uses classes Picture and AttachmentFile, who are descendants of the Asset class. So, your project must have these classes.
116
+
117
+ http://github.com/thoughtbot/paperclip
118
+
119
+ For S3 storage look at "../ckeditor/examples/s3"
120
+
121
+ ==Formtastic integration
122
+ Ckeditor detects if your use Formtastic and appends "Ckeditor::CustomFormBuilder".
123
+
124
+ <%= form.input :content, :as => :ckeditor %>
125
+
126
+ ==Middleware
127
+
128
+ Ckeditor appends middleware ("Ckeditor::Middleware") before session store to
129
+ support swf upload with AuthenticityToken.
130
+
131
+ rake middleware
132
+
133
+ ==TODOs
134
+
135
+ 1. Add support for choose filemanager storage
136
+ 2. More integration upload system
@@ -1,10 +1,11 @@
1
1
  class CkeditorController < ApplicationController
2
+ skip_before_filter :verify_authenticity_token, :only => [:create]
2
3
  before_filter :swf_options, :only => [:images, :files, :create]
3
4
  layout "ckeditor"
4
5
 
5
6
  # GET /ckeditor/images
6
7
  def images
7
- @images = Picture.find(:all, :order=>"id DESC")
8
+ @images = Ckeditor.image_model.find(:all, :order=>"id DESC")
8
9
 
9
10
  respond_to do |format|
10
11
  format.html {}
@@ -14,7 +15,7 @@ class CkeditorController < ApplicationController
14
15
 
15
16
  # GET /ckeditor/files
16
17
  def files
17
- @files = AttachmentFile.find(:all, :order=>"id DESC")
18
+ @files = Ckeditor.file_model.find(:all, :order=>"id DESC")
18
19
 
19
20
  respond_to do |format|
20
21
  format.html {}
@@ -27,8 +28,8 @@ class CkeditorController < ApplicationController
27
28
  @kind = params[:kind] || 'file'
28
29
 
29
30
  @record = case @kind.downcase
30
- when 'file' then AttachmentFile.new
31
- when 'image' then Picture.new
31
+ when 'file' then Ckeditor.file_model.new
32
+ when 'image' then Ckeditor.image_model.new
32
33
  end
33
34
 
34
35
  unless params[:CKEditor].blank?
@@ -12,26 +12,10 @@ module CkeditorHelper
12
12
  options[:protocol] = "http://"
13
13
  options[session_key] = CGI.unescape(cookies[session_key])
14
14
 
15
- unless request_forgery_protection_token.nil?
16
- options[request_forgery_protection_token] = CGI.unescape(form_authenticity_token)
15
+ if protect_against_forgery?
16
+ options[request_forgery_protection_token] = form_authenticity_token
17
17
  end
18
18
 
19
19
  url_for(options)
20
20
  end
21
-
22
- def file_image_tag(filename, path)
23
- extname = File.extname(filename)
24
-
25
- image = case extname.to_s
26
- when '.swf' then '/javascripts/ckeditor/images/swf.gif'
27
- when '.pdf' then '/javascripts/ckeditor/images/pdf.gif'
28
- when '.doc', '.txt' then '/javascripts/ckeditor/images/doc.gif'
29
- when '.mp3' then '/javascripts/ckeditor/images/mp3.gif'
30
- when '.rar', '.zip', '.tg' then '/javascripts/ckeditor/images/rar.gif'
31
- when '.xls' then '/javascripts/ckeditor/images/xls.gif'
32
- else '/javascripts/ckeditor/images/ckfnothumb.gif'
33
- end
34
-
35
- image_tag(image, :alt => path, :title => filename, :onerror => "this.src='/javascripts/ckeditor/images/ckfnothumb.gif'", :class => 'image')
36
- end
37
21
  end
@@ -0,0 +1,15 @@
1
+ <div class="FCKThumb">
2
+ <table border="0" cellpadding="0" cellspacing="0" height="100" width="100">
3
+ <tbody>
4
+ <tr>
5
+ <td align="center" valign="middle">
6
+ <%= image_tag(asset.url_thumb, :alt => asset.url_content, :title => asset.filename, :onerror=>"this.src='/javascripts/ckeditor/images/ckfnothumb.gif'", :class=>'image') %>
7
+ </td>
8
+ </tr>
9
+ </tbody>
10
+ </table>
11
+
12
+ <div class="FCKFileName"><%= asset.filename %></div>
13
+ <div class="FCKFileDate"><%= asset.format_created_at %></div>
14
+ <div class="FCKFileSize"><%= number_to_human_size(asset.size, :precision => 2) %></div>
15
+ </div>
@@ -83,7 +83,7 @@
83
83
  <tr>
84
84
  <td style="height: 100%;" id="qu">
85
85
  <div style="overflow:auto; height:550px;" id='container'>
86
- <%= render :partial => "file", :collection => @files %>
86
+ <%= render :partial => "asset", :collection => @files, :as => :asset %>
87
87
  </div>
88
88
  </td>
89
89
  </tr>
@@ -83,7 +83,7 @@
83
83
  <tr>
84
84
  <td style="height: 100%;" id="qu">
85
85
  <div style="overflow:auto; height:550px;" id='container'>
86
- <%= render :partial => "image", :collection => @images %>
86
+ <%= render :partial => "asset", :collection => @images, :as => :asset %>
87
87
  </div>
88
88
  </td>
89
89
  </tr>
@@ -10,7 +10,6 @@
10
10
 
11
11
  <script src="/javascripts/ckeditor/swfupload/mootools-1.2.3-core-yc.js" type="text/javascript"></script>
12
12
  <script src="/javascripts/ckeditor/swfupload/swfupload.js" type="text/javascript"></script>
13
- <script src="/javascripts/ckeditor/swfupload/swfupload.swfobject.js" type="text/javascript"></script>
14
13
  <script src="/javascripts/ckeditor/swfupload/swfupload.queue.js" type="text/javascript"></script>
15
14
  <script src="/javascripts/ckeditor/swfupload/fileprogress.js" type="text/javascript"></script>
16
15
  <script src="/javascripts/ckeditor/swfupload/handlers.js" type="text/javascript"></script>
@@ -47,6 +47,22 @@ module Ckeditor
47
47
  mattr_accessor :file_manager_image_uri
48
48
  @@file_manager_image_uri = "/ckeditor/images"
49
49
 
50
+ mattr_accessor :file_manager_image_model
51
+ @@file_manager_image_model = "Ckeditor::Picture"
52
+
53
+ mattr_accessor :file_manager_file_model
54
+ @@file_manager_file_model = "Ckeditor::AttachmentFile"
55
+
56
+ def self.image_model
57
+ @@image_model ||= @@file_manager_image_model.to_s.constantize
58
+ @@image_model
59
+ end
60
+
61
+ def self.file_model
62
+ @@file_model ||= @@file_manager_file_model.to_s.constantize
63
+ @@file_model
64
+ end
65
+
50
66
  # Default way to setup Ckeditor. Run rails generate ckeditor to create
51
67
  # a fresh initializer with all configuration values.
52
68
  def self.setup
@@ -55,3 +71,7 @@ module Ckeditor
55
71
  end
56
72
 
57
73
  require 'ckeditor/engine'
74
+
75
+ if Object.const_defined?("Formtastic")
76
+ require "ckeditor/formtastic"
77
+ end
@@ -1,10 +1,21 @@
1
1
  module Ckeditor
2
2
  class Engine < ::Rails::Engine
3
+ initializer "ckeditor_engine.add_middleware" do |app|
4
+ app.middleware.insert_before(
5
+ ActionDispatch::Cookies,
6
+ Ckeditor::Middleware,
7
+ app.config.send(:session_options)[:key])
8
+ end
9
+
3
10
  config.after_initialize do
4
11
  ActionView::Base.send :include, Ckeditor::ViewHelper
5
12
  ActionView::Helpers::FormBuilder.send :include, Ckeditor::FormBuilder
6
13
 
7
14
  ActionView::Helpers::AssetTagHelper.register_javascript_expansion :ckeditor => ["ckeditor/ckeditor"]
15
+
16
+ if Object.const_defined?("Formtastic")
17
+ Formtastic::SemanticFormHelper.builder = Ckeditor::CustomFormBuilder
18
+ end
8
19
  end
9
20
  end
10
21
  end
@@ -0,0 +1,12 @@
1
+ module Ckeditor
2
+ class CustomFormBuilder < Formtastic::SemanticFormBuilder
3
+
4
+ private
5
+
6
+ def ckeditor_input(method, options)
7
+ html_options = options.delete(:input_html) || {}
8
+ self.label(method, options_for_label(options)) <<
9
+ self.send(:ckeditor_textarea, sanitized_object_name, method, html_options)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ require 'rack/utils'
2
+
3
+ module Ckeditor
4
+ class Middleware
5
+ def initialize(app, session_key = '_session_id')
6
+ @app = app
7
+ @session_key = session_key
8
+ end
9
+
10
+ def call(env)
11
+ if env['HTTP_USER_AGENT'] =~ /^(Adobe|Shockwave) Flash/
12
+ params = ::Rack::Utils.parse_query(env['QUERY_STRING'])
13
+ env['HTTP_COOKIE'] = [ @session_key, ::Rack::Utils.escape(params[@session_key]) ].join('=').freeze unless params[@session_key].nil?
14
+ end
15
+ @app.call(env)
16
+ end
17
+ end
18
+ end
@@ -2,7 +2,7 @@ module Ckeditor
2
2
  module Version
3
3
  MAJOR = 3
4
4
  MINOR = 2
5
- RELEASE = 1
5
+ RELEASE = 3
6
6
 
7
7
  def self.dup
8
8
  "#{MAJOR}.#{MINOR}.#{RELEASE}"
@@ -2,16 +2,18 @@ module Ckeditor
2
2
  module ViewHelper
3
3
  include ActionView::Helpers
4
4
 
5
- # Example:
5
+ # Ckeditor helper:
6
6
  # <%= ckeditor_textarea("object", "field", :width => '100%', :height => '200px') %>
7
7
  #
8
- # To use a remote form you need to do something like this
9
- # <%= form_remote_tag :url => @options.merge(:controller => @scaffold_controller),
10
- # :before => Ckeditor_before_js('note', 'text') %>
8
+ # Two forms on one page:
9
+ # <%= form_tag "one" %>
10
+ # <%= ckeditor_textarea("object", "field", :id => "demo1") %>
11
+ # <% end %>
12
+ # ...
13
+ # <%= form_tag "two" %>
14
+ # <%= ckeditor_textarea("object", "field", :id => "demo2") %>
15
+ # <% end %>
11
16
  #
12
- # <%= ckeditor_textarea( "note", "text", :ajax => true ) %>
13
- #
14
- # <%= end_form_tag %>
15
17
  def ckeditor_textarea(object, field, options = {})
16
18
  options.symbolize_keys!
17
19
 
@@ -21,9 +23,9 @@ module Ckeditor
21
23
  value = var.send(field.to_sym) if var
22
24
  value ||= options[:value] || ""
23
25
 
24
- id = ckeditor_element_id(object, field)
26
+ element_id = options[:id] || ckeditor_element_id(object, field)
25
27
 
26
- textarea_options = { :id => id }
28
+ textarea_options = { :id => element_id }
27
29
 
28
30
  textarea_options[:cols] = options[:cols].nil? ? 70 : options[:cols].to_i
29
31
  textarea_options[:rows] = options[:rows].nil? ? 20 : options[:rows].to_i
@@ -50,70 +52,45 @@ module Ckeditor
50
52
 
51
53
  output_buffer = ActiveSupport::SafeBuffer.new
52
54
 
53
- if options[:ajax]
54
- textarea_options.update(:name => id)
55
-
56
- output_buffer << tag(:input, { "type" => "hidden", "name" => "#{object}[#{field}]", "id" => "#{id}_hidden"})
57
- output_buffer << ActionView::Base::InstanceTag.new(object, field, self, var).to_text_area_tag(textarea_options)
58
- else
59
- textarea_options.update(:style => "width:#{width};height:#{height}")
55
+ textarea_options.update(:style => "width:#{width};height:#{height}")
60
56
 
61
- output_buffer << ActionView::Base::InstanceTag.new(object, field, self, var).to_text_area_tag(textarea_options)
62
- end
57
+ output_buffer << ActionView::Base::InstanceTag.new(object, field, self, var).to_text_area_tag(textarea_options)
63
58
 
64
- output_buffer << javascript_tag("CKEDITOR.replace('#{object}[#{field}]', {
59
+ output_buffer << javascript_tag("CKEDITOR.replace('#{element_id}', {
65
60
  #{ckeditor_applay_options(ckeditor_options)}
66
61
  });\n")
67
62
 
68
63
  output_buffer
69
64
  end
70
-
71
- def ckeditor_form_remote_tag(options = {})
72
- editors = options[:editors]
73
- before = ""
74
- editors.keys.each do |e|
75
- editors[e].each do |f|
76
- before += ckeditor_before_js(e, f)
77
- end
78
- end
79
- options[:before] = options[:before].nil? ? before : before + options[:before]
80
- form_remote_tag(options)
81
- end
82
-
83
- def ckeditor_remote_form_for(object_name, *args, &proc)
84
- options = args.last.is_a?(Hash) ? args.pop : {}
85
- concat(ckeditor_form_remote_tag(options), proc.binding)
86
- fields_for(object_name, *(args << options), &proc)
87
- concat('</form>', proc.binding)
88
- end
89
- alias_method :ckeditor_form_remote_for, :ckeditor_remote_form_for
90
-
91
- def ckeditor_element_id(object, field)
92
- "#{object}_#{field}_editor"
93
- end
94
-
95
- def ckeditor_div_id(object, field)
96
- id = eval("@#{object}.id")
97
- "div-#{object}-#{id}-#{field}-editor"
98
- end
99
-
100
- def ckeditor_before_js(object, field)
101
- id = ckeditor_element_id(object, field)
102
- "var oEditor = CKEDITOR.instances.#{id}.getData();"
65
+
66
+ def ckeditor_ajax_script(backend = 'jquery')
67
+ javascript_tag("$(document).ready(function(){
68
+ $('form[data-remote]').bind('ajax:before', function(){
69
+ for (instance in CKEDITOR.instances){
70
+ CKEDITOR.instances[instance].updateElement();
71
+ }
72
+ });
73
+ });")
103
74
  end
104
75
 
105
- def ckeditor_applay_options(options={})
106
- str = []
107
- options.each do |k, v|
108
- value = case v.class.to_s.downcase
109
- when 'string' then "'#{v}'"
110
- when 'hash' then "{ #{ckeditor_applay_options(v)} }"
111
- else v
112
- end
113
- str << "#{k}: #{value}"
76
+ protected
77
+
78
+ def ckeditor_element_id(object, field)
79
+ "#{object}_#{field}_editor"
114
80
  end
115
81
 
116
- str.join(',')
117
- end
82
+ def ckeditor_applay_options(options={})
83
+ str = []
84
+ options.each do |k, v|
85
+ value = case v.class.to_s.downcase
86
+ when 'string' then "'#{v}'"
87
+ when 'hash' then "{ #{ckeditor_applay_options(v)} }"
88
+ else v
89
+ end
90
+ str << "#{k}: #{value}"
91
+ end
92
+
93
+ str.join(',')
94
+ end
118
95
  end
119
96
  end