Tôi chắc rằng có rất nhiều cách để kéo giảm giá này, nhưng đây là giải pháp của tôi. Tôi đang sử dụng Smarty Template Engine, nhưng kỹ thuật này cũng sẽ hoạt động với vani HTML.
Trước hết, đây là một ví dụ về một số HTML được lưu trữ trong tập tin mẫu của tôi có tên là "dog_fleas.tpl":
<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>
Các javascript (mycms.js) để xử lý các chỉnh sửa nội tuyến là:
$(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"
});
}
}
});
});
});
Đoạn mã trên thực hiện một vài điều:
- Nó chuyển đổi bất kỳ thẻ div với contenteditable thuộc tính = "true" để inline-edit có thể.
- Sau khi nội dung được chỉnh sửa (làm mờ), id phần tử có thể chỉnh sửa, tên tệp tpl và nội dung đã chỉnh sửa được gửi đến máy chủ thông qua cuộc gọi ajax.
Thuộc tính tpl là cần thiết trong trường hợp của tôi để xác định tệp đang được chỉnh sửa. Id phần tử chỉ định yếu tố nào đã được sửa đổi.
Mặc dù ví dụ của tôi chỉ chứa một vùng có thể chỉnh sửa, mã này hỗ trợ nhiều vùng có thể chỉnh sửa trong một tệp.
Ở phía máy chủ, đây là mã PHP của tôi. Tôi đang sử dụng một khuôn khổ, vì vậy $ tôi đây -> _ POST() chức năng có thể trông hơi khác thường, nhưng hy vọng bạn sẽ có được ý tưởng:
// 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);
}
Mã PHP trên là cơ bản nạp HTML, định vị div với id thích hợp, sau đó thay thế nội dung của thẻ div đó bằng nội dung được gửi qua cuộc gọi ajax. HTML sau đó được lưu lại vào máy chủ. Tôi cũng bao gồm một số mã để lưu trữ các bản sửa đổi sao lưu chỉ trong trường hợp mọi thứ đi sai lầm khủng khiếp.
Tôi nhận thấy rằng cụm từ thông dụng không phải lúc nào cũng là giải pháp tốt nhất. Trong trường hợp của tôi, thật khó sử dụng Mô hình đối tượng DOM của PHP vì nội dung HTML của tôi không phải là HTML hợp lệ. Bạn có thể xem xét sử dụng Mô hình đối tượng Dom thay vì nếu hệ thống của bạn đơn giản hơn hệ thống của tôi.
Tôi hy vọng điều này sẽ hữu ích!
Cảm ơn bạn! Tôi đã tìm cách bắn một yêu cầu ajax cho việc này. Giải pháp của bạn là hoàn hảo cho việc áp dụng của tôi. – Dave