-
Notifications
You must be signed in to change notification settings - Fork 36
Melody Cookbook: Comment pagination with jQuery
- Basic familiarity with JavaScript.
- Basic familiarity with Melody tags.
- Some knowledge of jQuery or a willingness to learn it as you go.
Under the options branch of your theme, add the following two options:
paginate_comments_enable:
label: Enable Comment Pagination
hint: If checked, comments will be paginated.
type: checkbox
tag: 'SampleThemeCommentPaginationEnabled?'
paginate_comments_count:
label: Comments Per Page
hint: If pagination is enabled, this is how many comments appear on one page.
type: text
tag: SampleThemeCommentsPerPage
The first one creates a conditional tag that can be used like this in a theme when you need to do something based on whether or not comments are paginated:
<mt:SampleThemeCommentPaginationEnabled>
<$mt:SampleThemeCommentsPerPage setvar="commentsPerPage"$>
...
<mt:Else>
...
</mt:SampleThemeCommentPaginationEnabled>
You are going to need two templates:
- A module called "Comment Detail."
- A system template named "Comment Listing."
The code for the comment listing template is:
{
"direction": "<mt:Var name="commentDirection">",
"comments": "<mt:Comments sort_order="$commentDirection"><$mt:Include identifier="comment_detail" replace="\","\\" replace='"','\"' strip_linefeeds="1"$></mt:Comments>"
}
Here is a sample for comment detail. It is from the original classic blog templates. It is intended to be an example of how this works, not something for you to copy and paste in its current form.
<div id="comment-<$mt:CommentID$>" class="comment<mt:IfCommentParent> comment-reply</mt:IfCommentParent><mt:IfCommenterIsEntryAuthor> entry-author-comment</mt:IfCommenterIsEntryAuthor>">
<div class="inner">
<div class="comment-header">
<div class="asset-meta">
<span class="byline">
<$mt:CommentAuthorIdentity$>
<mt:IfCommentParent>
<__trans phrase="[_1] replied to <a href="[_2]">comment from [_3]</a>" params="<span class="vcard author"><$mt:CommentAuthorLink$></span>%%<mt:CommentParent><$mt:CommentLink$></mt:CommentParent>%%<mt:CommentParent><$mt:CommentAuthor$></mt:CommentParent>">
<mt:Else>
<span class="vcard author"><$mt:CommentAuthorLink$></span>
</mt:IfCommentParent>
| <a href="<$mt:CommentLink$>"><abbr class="published" title="<$mt:CommentDate format_name="iso8601"$>"><$mt:CommentDate$></abbr></a>
<mt:IfCommentsAccepted>
| <$mt:CommentReplyToLink$>
</mt:IfCommentsAccepted>
</span>
</div>
</div>
<div class="comment-content">
<$mt:CommentBody$>
</div>
</div>
</div>
Save yours files respectively as:
- comment_listing.mtml
- comment_detail.mtml
Add the following MTML to your entry templates to do a basic listing of comments that is ready for pagination.
<mt:SampleThemeCommentPaginationEnabled>
<$mt:SampleThemeCommentsPerPage setvar="commentsPerPage"$>
<mt:Comments lastn="$commentsPerPage">
<$mt:Include identifier="comment_detail"$>
</mt:Comments>
<div id="navigation">
<div class="left">
<a href="#comments" id="a-prev" style="display: none"><__trans phrase="« Older Comments"></a>
</div>
<div class="right">
<a href="#comments" id="a-next" ><__trans phrase="Newer Comments »"></a>
</div>
</div>
<mt:Else>
<mt:Comments>
<$mt:Include identifier="comment_detail"$>
</mt:Comments
</mt:SampleThemeCommentPaginationEnabled>
Performance Tip: The Include tag is used in these samples for readability in this tutorial. You should actually consider copying the contents of the comment detail module into the <mt:Comments/>
loops.
After the conditional block shown above, add the following MTML and JavaScript to your entry template.
<mt:SampleThemeCommentPaginationEnabled>
<script type="text/javascript">
var offset = 0;
var incOffsetBy = <$mt:SampleThemeCommentsPerPage$> ;
function success(data, status, xhr) {
$('ol.commentlist').remove();
$(data.comments).insertAfter( $('#comments') );
}
function error(jqXHR, textStatus, errorThrown) {
alert(textStatus);
}
$(function() {
newer = $('#a-newer').click(function() {
offset += incOffsetBy;
$.ajax({
url: '<$mt:CGIPath$><$mt:CommentScript$>',
data: {
'__mode': 'comment_listing',
'entry_id': <$mt:EntryID$>,
'direction': 'ascend',
'limit': incOffsetBy,
'offset': offset
}
})
.success(success)
.error(error)
.complete(function() {
if ( older.is(':hidden'))
older.show();
if ( $('ol.commentlist li').length < incOffsetBy)
newer.hide();
});
});
older = $('#a-prev').click(function() {
offset -= incOffsetBy;
$.ajax({
url: '<$mt:CGIPath$><$mt:CommentScript$>',
data: {
'__mode': 'comment_listing',
'entry_id': <$mt:EntryID$>,
'direction': 'ascend',
'limit': incOffsetBy,
'offset': offset
}
})
.success(success)
.error(error).complete(function() {
if ( newer.is(':hidden') )
newer.show();
if ( offset <= 0 )
older.hide();
});
});
});
</script>
</mt:SampleThemeCommentPaginationEnabled>
This example utilizes the jQuery 1.5 AJAX API. It will not work with older versions of jQuery.
The mile-in-the-sky view of what this seeks to do is the following:
- Create a reusable JavaScript variable that holds the amount of comments per page. This is to increase publishing performance a little bit.
- Since the success/error scenarios are the same for both links, their event handlers are declare in advance to reuse some code.
- A document-ready listener is bound,
$(function() {});
- In the document-ready-listener, the links are found by jQuery and receive click handlers that execute AJAX calls to the comment_listing mode of the comment script.
- At the end of each AJAX call, jQuery looks at either the offset or the number of comments returned and if necessary, hides one of the links to prevent a user from clicking on it when they should not.