ckeditor 3.2.1 → 3.2.3

Sign up to get free protection for your applications and to get access to all the features.
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