讓Rails版的FCKEditor支持動態設置上傳目錄
一個多用戶的系統,上傳圖像文件等,希望不同用戶的圖像上傳到它專有的目錄里。我最初查到在PHP版的FCKEditor是通過設置$Config('UserFilesPath')來實現,但Rails版的FCKEditor沒有此項設置(搜索UserFilesPath關鍵字后做出此判斷)。接著,我查看了FCKEditor關鍵的fckeditor_controller.rb的源代碼,似乎它并不支持此項設置。再看javaeye是怎么用FCKEditor的,發現它放棄了FCKEditor的上傳功能。google了半天,除了那些轉來轉去的相同內容的帖子之外(搞不懂有了google之后,怎么還會有人費勁去轉帖別人的文章),一點營養也沒有。在JavaEye發了個求助帖,沒人理 :-( 。 傳說中高手云集的JavaEye,其Rails版塊真是冷清,給人陰颼颼的感覺。沒辦法,自己改源代碼吧。
另外,它前面的常量UPLOADED_ROOT也沒用了,可以刪掉。
2. 在上面的代碼中params[:uploaded]是關鍵,它就是我們動態定義的上傳目錄。該值來自于FCKEditor的一些html頁面,它是通過get參數傳入的。修改browser.html文件(如下粗體部份),在它的url請求中把我們定義目錄加入到get參數列中,這樣它就可以傳到fckeditor_controller.rb里了。
var?sServerPath?=?GetUrlParam(?'ServerPath'?)?;
if?(?sServerPath.length?>?0?)
????oConnector.ConnectorUrl?+=?'ServerPath='?+?escape(?sServerPath?)?+?'&'?;
var?sUploaded?=?GetUrlParam(?'uploaded'?)?;
if?(?sUploaded.length?>?0?)
????oConnector.ConnectorUrl?+=?'uploaded='?+?escape(?sUploaded?)?+?'&'?;
oConnector.ResourceType????????=?GetUrlParam(?'Type'?)?;
oConnector.ShowAllTypes????????=?(?oConnector.ResourceType.length?==?0?)?;
3.? 上面的GetUrlParam(?'uploaded'?) 的值來自于fckcustom.js。修改fckcustom.js(如下粗體部份),把uploaded加入到get參數列中。
4. 上面FCKConfig.uploaded的值來自于fckeditor.rb。在fckeditor.rb中加入一句(如下粗體所示)。
5.不過上面oFCKeditor.Config['uploaded']的值要傳到fckcustom.js的FCKConfig.uploaded里,還需要修改fckeditorcode_gecko.js和fckeditorcode_ie.js(這兩個文件對javascript進行了壓縮處理,修改起來較難操作)。我是參考了oFCKeditor.Config['CustomConfigurationsPath'] 這個參數的載入實現,才找到這種鳥不生蛋的地方。搜索這兩個文件的關鍵字CustomConfigurationsPath,找到如下一行,然后加入一個else if判斷(如下粗體所示)。
6.最后在fckeditor.rb里的#{options[:path]}來自于我們前臺的view了。如下粗體所示,把標準的fckeditor_textarea新增加了一個參數,其中params[:user_id]是把用戶的ID值做為目錄名。這樣就實現了動態改變FCKEditor的上傳目錄。
修改完后需要重啟WEB服務,最后別忘記把public/javascripts/fckeditor和vendor/plugins/fckeditor/public/javascripts同步一下,原因見http://www.tkk7.com/chengang/archive/2007/09/24/147867.html
文/陳剛 www.chengang.com.cn 轉載請保留出處
1.修改fckeditor_controller.rb,把它那幾個private方法修改如下:??
??private
??def?current_directory_path
????base_dir?=?"#{RAILS_ROOT}/public"
????#TODO?在創建用戶時,就建立好目錄。這時可以去掉這部份代碼,提高運行效率。
????("#{params[:uploaded]||UPLOADED}/#{params[:Type]}").split('/').each?do?|s|
????next?if?s==''
????????base_dir?+=?'/'?+?s
????????Dir.mkdir(base_dir,0775)?unless?File.exists?(base_dir)
????end
????
????check_path("#{base_dir}#{params[:CurrentFolder]}")
??end
??
??def?upload_directory_path
????uploaded?=?@request.relative_url_root.to_s+"#{params[:uploaded]||UPLOADED}/#{params[:Type]}"
????"#{uploaded}#{params[:CurrentFolder]}"
??end
??
??def?check_file(file)
????#?check?that?the?file?is?a?tempfile?object
????unless?"#{file.class}"?==?"Tempfile"?||?"#{file.class}"?==?"StringIO"
??????@errorNumber?=?403
??????throw?Exception.new
????end
????file
??end
??
??def?check_path(path)
????exp_path?=?File.expand_path?path
????if?exp_path?!~?%r[^#{File.expand_path(RAILS_ROOT)}/public#{params[:uploaded]||UPLOADED}]
??????@errorNumber?=?403
??????throw?Exception.new
????end
????path
??end
??private
??def?current_directory_path
????base_dir?=?"#{RAILS_ROOT}/public"
????#TODO?在創建用戶時,就建立好目錄。這時可以去掉這部份代碼,提高運行效率。
????("#{params[:uploaded]||UPLOADED}/#{params[:Type]}").split('/').each?do?|s|
????next?if?s==''
????????base_dir?+=?'/'?+?s
????????Dir.mkdir(base_dir,0775)?unless?File.exists?(base_dir)
????end
????
????check_path("#{base_dir}#{params[:CurrentFolder]}")
??end
??
??def?upload_directory_path
????uploaded?=?@request.relative_url_root.to_s+"#{params[:uploaded]||UPLOADED}/#{params[:Type]}"
????"#{uploaded}#{params[:CurrentFolder]}"
??end
??
??def?check_file(file)
????#?check?that?the?file?is?a?tempfile?object
????unless?"#{file.class}"?==?"Tempfile"?||?"#{file.class}"?==?"StringIO"
??????@errorNumber?=?403
??????throw?Exception.new
????end
????file
??end
??
??def?check_path(path)
????exp_path?=?File.expand_path?path
????if?exp_path?!~?%r[^#{File.expand_path(RAILS_ROOT)}/public#{params[:uploaded]||UPLOADED}]
??????@errorNumber?=?403
??????throw?Exception.new
????end
????path
??end
另外,它前面的常量UPLOADED_ROOT也沒用了,可以刪掉。
2. 在上面的代碼中params[:uploaded]是關鍵,它就是我們動態定義的上傳目錄。該值來自于FCKEditor的一些html頁面,它是通過get參數傳入的。修改browser.html文件(如下粗體部份),在它的url請求中把我們定義目錄加入到get參數列中,這樣它就可以傳到fckeditor_controller.rb里了。
var?sServerPath?=?GetUrlParam(?'ServerPath'?)?;
if?(?sServerPath.length?>?0?)
????oConnector.ConnectorUrl?+=?'ServerPath='?+?escape(?sServerPath?)?+?'&'?;
var?sUploaded?=?GetUrlParam(?'uploaded'?)?;
if?(?sUploaded.length?>?0?)
????oConnector.ConnectorUrl?+=?'uploaded='?+?escape(?sUploaded?)?+?'&'?;
oConnector.ResourceType????????=?GetUrlParam(?'Type'?)?;
oConnector.ShowAllTypes????????=?(?oConnector.ResourceType.length?==?0?)?;
3.? 上面的GetUrlParam(?'uploaded'?) 的值來自于fckcustom.js。修改fckcustom.js(如下粗體部份),把uploaded加入到get參數列中。
//?CHANGE?FOR?APPS?HOSTED?IN?SUBDIRECTORY
FCKRelativePath?=?'';
//?DON'T?CHANGE?THESE
FCKConfig.LinkBrowserURL?=?FCKConfig.BasePath?+?'filemanager/browser/default/browser.html?Connector='+FCKRelativePath+'/fckeditor/command';
FCKConfig.ImageBrowserURL?=?FCKConfig.BasePath?+?'filemanager/browser/default/browser.html?uploaded='+FCKConfig.uploaded+'&Type=Image&Connector='+FCKRelativePath+'/fckeditor/command';
FCKConfig.FlashBrowserURL?=?FCKConfig.BasePath?+?'filemanager/browser/default/browser.html?uploaded='+FCKConfig.uploaded+'&Type=Flash&Connector='+FCKRelativePath+'/fckeditor/command';
FCKConfig.LinkUploadURL?=?FCKRelativePath+'/fckeditor/upload';
FCKConfig.ImageUploadURL?=?FCKRelativePath+'/fckeditor/upload?Type=Image&uploaded='+FCKConfig.uploaded;
FCKConfig.FlashUploadURL?=?FCKRelativePath+'/fckeditor/upload?Type=Flash&uploaded='+FCKConfig.uploaded;
FCKConfig.AllowQueryStringDebug?=?false;
FCKConfig.SpellChecker?=?'SpellerPages';
//?ONLY?CHANGE?BELOW?HERE
FCKConfig.SkinPath?=?FCKConfig.BasePath?+?'skins/silver/';
FCKConfig.AutoDetectLanguage?=?false?;
FCKConfig.DefaultLanguage?=?'zh-cn'?;
FCKConfig.FontNames?=?'微軟雅黑;宋體;黑體;隸書;楷體_GB2312;Arial;Comic?Sans?MS;Courier?New;Tahoma;Times?New?Roman;Verdana'?;
FCKConfig.ToolbarSets["Simple"]?=?[
????['Source','-','FitWindow','Preview','-','Templates'],
????['PasteText','PasteWord'],
????['Undo','Redo','Find','Replace'],
????'/',
????['RemoveFormat','Bold','Italic','Underline','StrikeThrough'],
????['OrderedList','UnorderedList','Outdent','Indent'],
????['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],
????????['TextColor','BGColor'],
????['Link','Unlink','Anchor'],
????['Image','Flash','Table','Rule','Smiley'],
????'/',
????['Style','FontFormat','FontName','FontSize']
]?;
FCKRelativePath?=?'';
//?DON'T?CHANGE?THESE
FCKConfig.LinkBrowserURL?=?FCKConfig.BasePath?+?'filemanager/browser/default/browser.html?Connector='+FCKRelativePath+'/fckeditor/command';
FCKConfig.ImageBrowserURL?=?FCKConfig.BasePath?+?'filemanager/browser/default/browser.html?uploaded='+FCKConfig.uploaded+'&Type=Image&Connector='+FCKRelativePath+'/fckeditor/command';
FCKConfig.FlashBrowserURL?=?FCKConfig.BasePath?+?'filemanager/browser/default/browser.html?uploaded='+FCKConfig.uploaded+'&Type=Flash&Connector='+FCKRelativePath+'/fckeditor/command';
FCKConfig.LinkUploadURL?=?FCKRelativePath+'/fckeditor/upload';
FCKConfig.ImageUploadURL?=?FCKRelativePath+'/fckeditor/upload?Type=Image&uploaded='+FCKConfig.uploaded;
FCKConfig.FlashUploadURL?=?FCKRelativePath+'/fckeditor/upload?Type=Flash&uploaded='+FCKConfig.uploaded;
FCKConfig.AllowQueryStringDebug?=?false;
FCKConfig.SpellChecker?=?'SpellerPages';
//?ONLY?CHANGE?BELOW?HERE
FCKConfig.SkinPath?=?FCKConfig.BasePath?+?'skins/silver/';
FCKConfig.AutoDetectLanguage?=?false?;
FCKConfig.DefaultLanguage?=?'zh-cn'?;
FCKConfig.FontNames?=?'微軟雅黑;宋體;黑體;隸書;楷體_GB2312;Arial;Comic?Sans?MS;Courier?New;Tahoma;Times?New?Roman;Verdana'?;
FCKConfig.ToolbarSets["Simple"]?=?[
????['Source','-','FitWindow','Preview','-','Templates'],
????['PasteText','PasteWord'],
????['Undo','Redo','Find','Replace'],
????'/',
????['RemoveFormat','Bold','Italic','Underline','StrikeThrough'],
????['OrderedList','UnorderedList','Outdent','Indent'],
????['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],
????????['TextColor','BGColor'],
????['Link','Unlink','Anchor'],
????['Image','Flash','Table','Rule','Smiley'],
????'/',
????['Style','FontFormat','FontName','FontSize']
]?;
4. 上面FCKConfig.uploaded的值來自于fckeditor.rb。在fckeditor.rb中加入一句(如下粗體所示)。
??????javascript_tag(?"var?oFCKeditor?=?new?FCKeditor('#{id}',?'#{width}',?'#{height}',?'#{toolbarSet}');\n"+
??????????????????????"oFCKeditor.BasePath?=?\"#{base_path}\"\n"+
??????????????????????"oFCKeditor.Config['CustomConfigurationsPath']?=?'../../fckcustom.js';\n"+
??????????????????????"oFCKeditor.Config['uploaded']?=?'#{options[:path]}';\n"+
??????????????????????"oFCKeditor.ReplaceTextarea();\n")?????????????????????????
??????????????????????"oFCKeditor.BasePath?=?\"#{base_path}\"\n"+
??????????????????????"oFCKeditor.Config['CustomConfigurationsPath']?=?'../../fckcustom.js';\n"+
??????????????????????"oFCKeditor.Config['uploaded']?=?'#{options[:path]}';\n"+
??????????????????????"oFCKeditor.ReplaceTextarea();\n")?????????????????????????
5.不過上面oFCKeditor.Config['uploaded']的值要傳到fckcustom.js的FCKConfig.uploaded里,還需要修改fckeditorcode_gecko.js和fckeditorcode_ie.js(這兩個文件對javascript進行了壓縮處理,修改起來較難操作)。我是參考了oFCKeditor.Config['CustomConfigurationsPath'] 這個參數的載入實現,才找到這種鳥不生蛋的地方。搜索這兩個文件的關鍵字CustomConfigurationsPath,找到如下一行,然后加入一個else if判斷(如下粗體所示)。
if?(D=='CustomConfigurationsPath')?FCKConfig[D]=E;else?if?(D=='uploaded')?FCKConfig[D]=E;else?if?(E.toLowerCase()=="true")?this.PageConfig[D]=true;
6.最后在fckeditor.rb里的#{options[:path]}來自于我們前臺的view了。如下粗體所示,把標準的fckeditor_textarea新增加了一個參數,其中params[:user_id]是把用戶的ID值做為目錄名。這樣就實現了動態改變FCKEditor的上傳目錄。
<%=fckeditor_textarea(:topic,?:content,?:ajax?=>?true,?:toolbarSet?=>?'Simple',?:height?=>?'400px',? :path?=>?"/uploads/#{params[:user_id]}")?%>
修改完后需要重啟WEB服務,最后別忘記把public/javascripts/fckeditor和vendor/plugins/fckeditor/public/javascripts同步一下,原因見http://www.tkk7.com/chengang/archive/2007/09/24/147867.html
posted on 2007-09-26 10:13 陳剛 閱讀(4304) 評論(5) 編輯 收藏 所屬分類: Rails&Ruby