2012-11-28 19 views
13

我不能工作了如何從CKEditor的情況下抓住編輯的數據,並將其發佈到URL。CKEditor的在線保存/提交

我在尋找的東西這樣的:

http://nightly.ckeditor.com/3995/samples/inlineall.html

,我無法工作,如何改變可以被保存。我可以張貼新編輯的數據被張貼到與元素的ID沿着PHP正在編輯?

與此類似:

editor.on('configLoaded', function(){ 
    // do some stuff 
}); 

我希望我可以做這樣的事情:

editor.on('clickAway', function(e){ 
    id = e.id(); 
    // do some ajax stuff 
}); 

,但我似乎無法找到任何東西,任何地方。

有沒有人制定了如何做到這一點?

謝謝。

回答

27

我敢肯定有很多方法可以退出這個功能,但這裏是我的解決方案。我使用的是Smarty模板引擎,但這種技術也應該適用於vanilla HTML。

首先,這裏有一個名爲 「dog_fleas.tpl」 存儲在我的模板文件中的一些HTML的例子:

<script type="text/javascript" src="/js/ckeditor/ckeditor.js"></script> 
<script type="text/javascript" src="/js/admin/mycms.js"></script> 
<div> 
    <div id="flea-blurb" tpl="/templates/dog_fleas.tpl" contenteditable="true"> 
    <h1>My Dog Has Fleas</h1> 
    <p>This text is editable via the CMS!</p> 
    </div> 
    <p>This text is not editable</p> 
</div> 

的JavaScript(mycms.js)來處理內聯編輯是:

$(document).ready(function() { 

    CKEDITOR.disableAutoInline = true; 

    $("div[contenteditable='true']").each(function(index) { 

     var content_id = $(this).attr('id'); 
     var tpl = $(this).attr('tpl'); 

     CKEDITOR.inline(content_id, { 
      on: { 
       blur: function(event) { 
        var data = event.editor.getData(); 

        var request = jQuery.ajax({ 
         url: "/admin/cms-pages/inline-update", 
         type: "POST", 
         data: { 
          content : data, 
          content_id : content_id, 
          tpl : tpl 
         }, 
         dataType: "html" 
        }); 

       } 
      } 
     }); 

    }); 

}); 

上面的代碼做了幾件事情:

  1. 任何div標籤轉換與屬性CONTENTEDITABLE =「真正的」內聯編輯能夠。
  2. 內容之後被編輯(上模糊),可編輯的元素編號和TPL文件名,和編輯的內容經由AJAX調用發送到服務器。

TPL的屬性是必要的,我的情況,以確定正在編輯的文件。元素ID指定哪個元素被修改。

雖然我的示例只包含一個可編輯區域,但此代碼支持單個文件中的多個可編輯區域。

在服務器端,這是我的PHP代碼。我使用了一個框架,讓我的$此 - > _ POST()函數可能看起來有點不尋常,但希望你的想法:

// Get the posted parameters 
    $new_content = $this->_POST('content'); 
    $content_id = $this->_POST('content_id'); 
    $tpl_filename = $this->_POST('tpl'); 

    // Get the contents of the .tpl file to edit 
    $file_contents = file_get_contents(APPPATH . 'views' . $tpl_filename); 

    // create revision as a backup in case of emergency 
    $revised_filename = str_replace('/', '.', $tpl_filename); 
    $revised_filename = ltrim ($revised_filename, '.'); 
    file_put_contents(APPPATH . 'views/templates/revisions/' . $revised_filename . '.' . time(), $file_contents); 

    // Prepare to match the DIV tag 
    // Credit to: http://stackoverflow.com/questions/5355452/using-a-regular-expression-to-match-a-div-block-having-a-specific-id 
    $re = '% # Match a DIV element having id="content". 
     <div\b    # Start of outer DIV start tag. 
     [^>]*?    # Lazily match up to id attrib. 
     \bid\s*+=\s*+  # id attribute name and = 
     ([\'"]?+)   # $1: Optional quote delimiter. 
     \b' . $content_id . '\b  # specific ID to be matched. 
     (?(1)\1)   # If open quote, match same closing quote 
     [^>]*+>   # remaining outer DIV start tag. 
     (     # $2: DIV contents. (may be called recursively!) 
      (?:    # Non-capture group for DIV contents alternatives. 
      # DIV contents option 1: All non-DIV, non-comment stuff... 
      [^<]++   # One or more non-tag, non-comment characters. 
      # DIV contents option 2: Start of a non-DIV tag... 
      | <   # Match a "<", but only if it 
      (?!   # is not the beginning of either 
       /?div\b # a DIV start or end tag, 
      | !--  # or an HTML comment. 
      )   # Ok, that < was not a DIV or comment. 
      # DIV contents Option 3: an HTML comment. 
      | <!--.*?-->  # A non-SGML compliant HTML comment. 
      # DIV contents Option 4: a nested DIV element! 
      | <div\b[^>]*+> # Inner DIV element start tag. 
      (?2)   # Recurse group 2 as a nested subroutine. 
      </div\s*>  # Inner DIV element end tag. 
     )*+    # Zero or more of these contents alternatives. 
     )     # End 2$: DIV contents. 
     </div\s*>   # Outer DIV end tag. 
     %isx'; 

    if (preg_match($re, $file_contents, $matches)) 
    { 
     $content_to_replace = $matches[0]; 

     $replacement_content = $content_to_replace; 

     // Replace the inner content of $replacement_content with $new_content 
     $replacement_content = preg_replace('/(<div(?:.*?)>)(?:.*)(<\/div>)/msi',"$1" . $new_content . "$2", $replacement_content); 

     // Now replace the content_to_replace with $replacement content in the HTML 
     $new_file_contents = str_replace($content_to_replace, $replacement_content, $file_contents); 

     // write out the new .tpl file 
     file_put_contents(APPPATH . 'views' . $tpl_filename, $new_file_contents); 
    } 

上面的PHP代碼基本上是加載HTML,定位DIV用正確的ID,然後更換與內容div標籤標籤的內容通過Ajax調用發送了下來。 HTML然後被重新保存到服務器。我還包含一些代碼來存儲備份修訂,以防萬一事情發生嚴重錯誤。

我意識到正則表達式並不總是最好的解決方案。就我而言,很難使用PHP Dom對象模型,因爲我的HTML內容不是有效的HTML。如果你的系統比我的簡單,你可以考慮使用Dom對象模型。

我希望這有助於!

+0

謝謝!我正在尋找如何解決這個問題的ajax請求。您的解決方案非常適合我的採用。 – Dave

0

使用@ clone45的上述答案並對其進行修改。該數據將被保存在按鈕Save中,並且只有在進行了一些更改後才能進行新舊數據比較。

覆蓋內嵌編輯器的現有保存按鈕,並僅包含在@ clone45的答案的提示部分。

<script> 

CKEDITOR.disableAutoInline = true; 
$("div[contenteditable='true']").each(function(index) { 
    var content_id = $(this).attr('id'); 
    var tpl = $(this).attr('tpl'); 
    var oldData = null; 
    CKEDITOR.inline(content_id, { 
     on: { 
      instanceReady: function(event) { 
       //get current data and save in variable 
       oldData = event.editor.getData(); 
       // overwrite the default save function 
       event.editor.addCommand("save", { 
        modes: { 
         wysiwyg: 1, 
         source: 1 
        }, 
        exec: function() { 
         var data = event.editor.getData(); 
         //check if any changes has been carried out 
         if (oldData !== data) { 
          oldData = data; 
          $.ajax({ 
            type: 'POST', 
            url: 'process.php', 
            data: { 
             content: data, 
             content_id: content_id, 
             tpl: tpl 
            } 
           }) 
           .done(function(data) { 
            alert('saved'); 
           }) 
           .fail(function() { 
            alert('something went wrong'); 
           }); 
         } else 
          alert('looks like nothing has been changed'); 
        } 
       }); 
      } 
     } 
    }); 
}); 

</script> 

希望這有助於!