[MT Hack]修改模板来完成MT的AJAX提交评论

曾经,本站在MT3时代,曾经写过以AJAX提交评论预览 的帖子。

那个也是通过修改模板+自写js实现,没有对MT的源代码进行任何修改,绿色无污染,不影响升级。

后来,通过自己摸索,也实现了 ajax 方式提交评论。但是一直都没有写出教程,今天有点时间。特意写出分享之。

具体效果见本站评论提交(预览和发表)。

言归正传,要实现 ajax 方式首先要定义一系列 js 函数。 由于 本站已经迁移到了 JQuery 平台,所以在改写 mt.js 需要先加入 JQ 支持,即加入:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

然后在 mt.js 添加:

<mt:Ignore>
/*/////////////////////////////////////////////////////////////////////////
//
// Ajax:Comment:Support -- By 路杨
//
/////////////////////////////////////////////////////////////////////////*/
</mt:Ignore>


/* 设置预览/信息框状态函数。*/
function SetPreDivInfo(isshow, str){
var el = $('#comment-preview-comment');
if (!el) return false;
if (!isshow) isshow = 0;
if (!str) str = '<h3><span class="status-indicator">&nbsp;</span> 请等待,评论提交中... </h3>';
if (isshow) { el.html(str).slideDown("slow");}
else { el.slideUp("slow"); /*el.html(''); */}
return true;
}

/* 设置提交按钮和预览按钮状态函数*/
function ChangeCommentBtState(s,pre)
{
// s= 1 , 激活: s=0; 关闭
var f = document['comments_form'];
if (f.preview_button ) {
f.preview_button.disabled = (s == 1) ? false : true;
f.preview_button.className =(s == 1) ? 'action button' : 'action disabled button' ;
}
if (f.post && !pre) {
f.post.disabled = (s == 1) ? false : true ;
f.post.className =(s == 1) ? 'action primary button' :'action disabled button';
mtRequestSubmitted = (s == 1) ? false : true;
}
}
/*关闭预览/信息条,恢复预览、提交按钮可用函数*/
function DoClosePreview() {
SetPreDivInfo(0);
ChangeCommentBtState(1);
return false;
}
/*提交预览、正式提交函数,用来替代MT默认提交函数*/
function EasunNewCommentOnSubmit(f) {
if (!mtRequestSubmitted) { //提交或者预览按钮没有被按下。
mtRequestSubmitted = true;
// disable submit buttons
if (! SetPreDivInfo(1,"")) return true;
ChangeCommentBtState(0);
if (f.armor)
f.armor.value = '<$mt:BlogSitePath encode_sha1="1"$>';
if (f.bakecookie && f.bakecookie.checked)
mtSaveUser(f);

var u = mtGetUser();
if ( !is_preview && ( u && u.is_authenticated ) ) {
// validate session; then submit
mtVerifySession('mtCommentSessionVerifyNew');//新的验证函数,主要是这个函数中有提交数据的动作
return false;
}

EasunPostComment();
return false;
}
return false;
}

/*新的用户信息验证函数,取代原来的mtCommentSessionVerify 函数*/
function mtCommentSessionVerifyNew(app_user) {
// var f = document['comments_form'];
SetPreDivInfo( 1 , '<div style="padding-left:15px;"><blockquote class="msg tip">正在验证登录....请等待 <span class="status-indicator">&nbsp;</span></blockquote></div>' ) ;
if ( app_user && app_user.verified ) {
EasunPostComment(); //f.submit();
} else {
var ss = '您的登录信息已经过期。请您重新登录来发表评论。';
alert(ss);

var s= '<h3>'
s += '抱歉!请重新登录。';
s += '(<a href="#" onclick="return DoClosePreview();" title="点击关闭提示" >关闭提示</a>)</h3>';
s += '<div style="padding-left:15px;"><blockquote class="msg warning">';
s += ss;
s += '</blockquote></div>';
SetPreDivInfo(1,s);
ChangeCommentBtState(1);
mtClearUser();
mtFireEvent('usersignin');
<mt:IfRegistrationRequired>
mtShow('comments-form');
mtHide('comments-open-footer');
</mt:IfRegistrationRequired>
}
}

/* Ajax 提交核心代码 */
function EasunPostComment(){
var f = document['comments_form'];
var str='<h3><span class="status-indicator">&nbsp;</span> 请等待,评论提交中... </h3>';
var respType ='json';
if (f.preview.value =='1' ){
str = '<h3>请等待,预览提交中... <span class="status-indicator">&nbsp;</span></h3>';
respType ='text';
}
SetPreDivInfo( 1 , str );
var url = "<$mt:CGIPath$><$mt:CommentScript$>";
$.post(url,
$.param($("#comments-form").serializeArray())
).success(function(data) {
if (f.preview.value =='1' ) { EasunisPreReturn(data);}
else {EasunisPostReturn(JSON.parse(data));}
}) ;
return false;

}


/*预览回调*/
function EasunisPreReturn(text)
{
if (!text) return;
var s= '<h3>请预览你的评论';
s += '(<a href="#" onclick="return DoClosePreview();" title="点击关闭预览" >关闭预览</a>)</h3>';
s += text;
SetPreDivInfo( 1 , s);
ChangeCommentBtState(1);
mtRequestSubmitted = false;
var f = document['comments_form'];
f.preview.value = '0';
}


/* 正式评论回调*/
function EasunisPostReturn(res_info)
{
var f = document['comments_form'];
if (res_info.msg ) {
var s= '<h3>'
s += (res_info.refr == 1) ? '评论成功!' : (res_info.refr == 2) ? '感谢您的评论' : '抱歉!评论出错了。';
s += '(<a href="#" onclick="return DoClosePreview();" title="点击关闭提示" >关闭提示</a>)</h3>';
s += '<div style="padding-left:15px;">';
s += '<blockquote class="msg ';
s += (res_info.refr == 0) ? 'warning' : 'tip';
s += '">' + res_info.msg;
s += '</blockquote></div>';
SetPreDivInfo( 1 , s);
ChangeCommentBtState(1);
mtRequestSubmitted = false;
f.preview.value = '0';
}
if (res_info.refr == 1) { //成功需要刷新整个页面
location.reload();
}
}

然后定位 mt.js 模板原来的函数:

function mtCommentOnSubmit(f) {
...
}

修改为

function mtCommentOnSubmit(f) {
return EasunNewCommentOnSubmit(f);
}

即取代原来的提交函数。

至此, mt.js 模板修改完成。

接下来。我们来修改  Comment Form  模板, 打开模板,在合适的位置增加 评论预览/Ajax信息返回信息栏。

代码如下:

<div class="comment-preview-comment" style="display:none" id="comment-preview-comment" name="comment-preview-comment"></div>

位置可以在你喜欢的任何地点。 我就加载了评论框上面。 作用是用来显示预览和发表信息后的返回结果。

再下来,我们该修改预览和发表的返回了。

可喜的是MT的这个信息返回依然是模板,所以,我们根本不需要进行代码级别的修改。 直接修改模板即可。

先是 预览模板。 位置在 Templates -> System Templates ->Comment Preview. 直接打开模板,删除所有。只保留如下代码

<$mt:Include module="Comment Detail"$>

保存即可。

再是 "评论响应" 模板, 位置在 Templates -> System Templates ->Comment Response. 直接打开模板,删除所有。替换成为以下代码:

<mt:If name="comment_confirmation">
    <$mt:Var name="state" value="1"$>
    <$mt:Var name="page_title" value="评论成功!"$>
    <$mt:Var name="message" value="<strong>恭喜!</strong> 您的评论发布成功! "$>
<mt:Else name="comment_pending">
    <$mt:Var name="state" value="2"$>
    <$mt:Var name="page_title" value="感谢您的评论"$>
    <$mt:Var name="message" value=" 您的评论已经发布,但是要经过 管理员 后台审核后才会显示,个中原因,请见晾(认证用户和注册用户的评论会直接显示)。<br /> Your comment has been received and held for approval by the blog owner."$>
<mt:Else name="comment_error">
    <$mt:Var name="state" value="0"$>
    <$mt:Var name="divclass" value="warning"$>
    <$mt:Var name="page_title" value="抱歉!评论出错了。"$>
    <mt:SetVarBlock name="message"> 您的评论因为以下原因而发布失败: <$mt:ErrorMessage encode_html="1"$> </mt:SetVarBlock>
</mt:If>

{
"title": "<$mt:Var name="page_title"$>",
"refr": "<$mt:Var name="state"$>",
"msg": "<$mt:Var name="message"$>"
}

保存。


OK,到这里, 所有的教程都完成了。可以重建看看预览和评论的 Ajax效果了。

但是要让结果更友好。别忘了给刚才增加的 HTML 代码增加 CSS哦。

我的 CSS部分如下

.comment-preview-comment {
    margin: 5px 0px;
    padding: 5px 0px;
    border: 1px solid #EEE;
    display: block;
    border-radius: 5px;
}

.comment-preview-comment h3 {
    padding: 0px 25px;
    background: url("/static/images/comment.gif") no-repeat scroll 3px center transparent;
    font-weight: bold;
    font-size: 1em;
}

相信大家的前端技术都很高明。 可以做出更漂亮的界面来 :)

现在重建 Blog吧, 充分享受 ajax 带来的快乐:)