This site uses cookies for analytics, personalized content and ads. By continuing to browse this site, you agree to this use.
Author Image Monday, 6 August 2018

Blogger JSON Feed API - Statistics Comments


Trang thống kê bình luận blogger là một ví dụ điển hình cho giới hạn tải feed. Theo đó để tải được bình luận ta sẽ gửi request dạng /feeds/comments/summary hoặc /feeds/comments/default. Con số tối đa cho mỗi lần request là 500. Như vậy có thể thấy khi blog của bạn có trên 500 bình luận, vấn đề sẽ trở nên phức tạp hơn

Một ví dụ tương tự cho feed post đó chính là sitemap, feed post chỉ cho phép tải tối đa 150 bài 1 lần, nên có thể thấy khi blog tầm vài nghìn bài, trang sẽ load rất lâu để get dữ liệu do phải gửi nhiều request với các start-index tăng theo cấp số cộng. Hi vọng trong tương lai blogger sẽ tăng thêm kết quả trả về khi tải feed để dân nghèo đỡ khổ

Quay trở lại bài viết này, không còn trong phạm vi recent comments thường hiển thị số bình luận dưới 500 nữa, nhiệm vụ của ta là phải hiển thị toàn bộ bình luận, bất kể blog có ít hơn hay nhiều hơn 500 comments

Tôi sẽ trình bày sơ qua ý tưởng như sau
  • Tải feed lấy tổng số bình luận của blog (ví dụ 1001)
  • Chia con số đó cho 500 để xác định số lần tải feed (ví dụ 1001 chia 500 được 2 dư 1 khi đó sẽ phải tải 3 lần feed [1-500], [501-1000] và [1001])
  • Tạo một mảng lưu các giá trị start-index (như ví dụ trên mảng sẽ là [1,501,1001], blog càng nhiều bình luận mảng càng lớn và số request gửi càng nhiều)
  • Lần lượt tải feed theo các giá trị start-index trong mảng để lấy dữ liệu và append vào html để hiển thị

Áp dụng cho blogger, trang thống kê này ta thường đặt nó ở chế độ trang tĩnh (bạn tạo 1 trang mới và chuyển qua chế độ HTML nhé)

Tạo 1 div để append dữ liệu vào

<div id="rc-cmt"></div>

Viết tiếp code js bên dưới (đọc kĩ phần comment để xem code làm gì nhé)

<script type='text/javascript'>//<![CDATA[
// Blogger total comments by Hung1001
var listIndexCmt = new Array,
    character = 150, // số lượng kí tự nhận xét muốn hiển thị
    avatar_Size = 50, // kích thước avatar
    time_cmt = "at";

$.ajax({
    url: '/feeds/comments/summary',
    type: 'GET',
    dataType: 'jsonp',
    data: {
        alt: 'json-in-script',
        'max-results': 0, // lấy tổng bình luận nên không cần thiết tải thêm các entry
    },
}).done(function(e) {

    // lấy tổng số bình luận chia cho 500 để tính toán các giá trị start-index
    t = parseInt(e.feed.openSearch$totalResults.$t, 10)

    if (t % 500 == 0) {
        num = (t / 500) - 1 // xử lý cho các index chia hết cho 500 ví dụ 500, 1000, 1500,...chúng vẫn chưa nhảy sang start-index mới
    } else {
        num = Math.floor(t / 500);
    }
    for (var k = 0; k <= num; k++) {
        listIndexCmt.push((500 * k) + 1) // mảng start-index sẽ là [1(=0*500+1),501(=1*500+1),1001(=2*500+1),1501(=3*500+1),2001(=4*500+1),...]
    }

    // Sử dụng jQuery Ajax Queue để call ajax tải feed theo thứ tự trong listIndexCmt, nếu không ajax sẽ call không theo thứ tự dẫn đến bình luận sẽ không sắp xếp từ cũ nhất tới mới nhất

    /*! jQuery Ajax Queue 
     * https://github.com/gnarf37/jquery-ajaxQueue
     */

    (function(e) {
        var r = e({});
        e.ajaxQueue = function(n) {
            function t(r) {
                u = e.ajax(n).done(a.resolve).fail(a.reject).then(r, r)
            }
            var u, a = e.Deferred(),
                i = a.promise();
            return r.queue(t), i.abort = function(o) {
                if (u) return u.abort(o);
                var c = r.queue(),
                    f = e.inArray(t, c);
                return f > -1 && c.splice(f, 1), a.rejectWith(n.context || n, [i, o, ""]), i
            }, i
        }
    })(jQuery);

    // Bình luận cũ nhất sẽ có start-index lớn nhất nên sẽ lặp từ cuối mảng về đầu mảng

    for (var l = listIndexCmt.length - 1; l >= 0; l--) {
        $.ajaxQueue({
            url: '/feeds/comments/summary',
            type: 'GET',
            dataType: 'jsonp',
            data: {
                alt: 'json-in-script',
                'max-results': 500,
                'start-index': listIndexCmt[l]
            },
        }).done(function(json) {
            var r = "";
            for (var i = 0; i < json.feed.entry.length; i++) {
                // lấy ngày đăng bình luận
                a = json.feed.entry[i].published.$t;
                g = a.substring(11, 16) + ", " + a.substring(8, 10) + "/" + a.substring(5, 7) + "/" + a.substring(0, 4)

                // lấy nội dung bình luận 
                if ("content" in json.feed.entry[i]) {
                    b = json.feed.entry[i].content.$t;
                } else {
                    b = json.feed.entry[i].summary.$t;
                }
                if (b.length > character) {
                    b = b.replace(/<\/?[^>]+(>|$)/g, "");
                    b2 = b.substring(0, character);
                    b3 = b2.lastIndexOf(" ");
                    b = b2.substring(0, b3) + " ...";
                }
                // lấy link bình luận
                for (var j = 0; j < json.feed.entry[i].link.length; j++) {
                    if (json.feed.entry[i].link[j].rel == "alternate") {
                        c = json.feed.entry[i].link[j].href;
                        break;
                    };
                };

                // lấy info người bình luận
                d = json.feed.entry[i].author[0].name.$t;
                if (json.feed.entry[i].author[0].uri) {
                    e = json.feed.entry[i].author[0].uri.$t;
                } else {
                    e = "#null";
                }

                // lấy avatar người bình luận
                if (json.feed.entry[i].author[0].gd$image.src) {
                    if (json.feed.entry[i].author[0].gd$image.src == "https://img1.blogblog.com/img/blank.gif" || json.feed.entry[i].author[0].gd$image.src == "https://img1.blogblog.com/img/b16-rounded.gif") {
                        f = "https://i.imgur.com/KA5Fr6Q.png"
                    } else {
                        f = json.feed.entry[i].author[0].gd$image.src.replace("s512-c", "s" + avatar_Size + "-c").replace("s113", "s" + avatar_Size + "-c").replace("s220", "s" + avatar_Size + "-c");
                    }
                } else {
                    f = "https://i.imgur.com/KA5Fr6Q.png"
                }
                r += '<li class="rc-item"><div class="rc-avatar"><a title="View profile" href="' + e + '"><img src="' + f + '"/></a></div><div class="rc-main"><div class="rc-header"><span class="rc-profile"><a title="' + d + '" href="' + e + '">' + d + '</a></span> ' + time_cmt + '&nbsp;<a title="View comment" href="' + c + '"><span class="rc-time">' + g + '</span></a></div><div class="rc-content">' + b + '</div></div></li>';
            };
            $('#rc-cmt').prepend(r)
            r = "";
        })
    };
})
//]]></script>  

Viết css cơ bản (có thời gian bạn tự biến hóa thêm)

#rc-cmt {
    margin: 1em 0;
    padding: 0 1em;
}

#rc-cmt li {
    list-style: none;
    margin: 0 0 1.5em;
    display: block;
    width: 100%;
}

#rc-cmt .rc-avatar {
    float: left;
    margin-right: .5em;
}

#rc-cmt .rc-avatar a img {
    width: 50px;
    height: 50px;
    border-radius: 100%
}

#rc-cmt .rc-main .rc-header {
    margin-bottom: 10px;
}

#rc-cmt .rc-main .rc-header a {
    text-decoration: none;
    cursor: pointer;
    color: #111;
    font-weight: bold
}

#rc-cmt .rc-main .rc-content {
    display: inline-block
}

Cuối cùng xuất bản trang để xem thành quả. Với blog có dưới 500 bình luận bạn sẽ thấy nó giống recent comments không có gì hot, nhưng trên 500 bạn sẽ thấy sức mạnh mà nó mang lại đó


Như vậy qua bài viết này tôi muốn nhấn mạnh tới giới hạn tải feed của blogger, qua đó hướng dẫn bạn cách gửi nhiều request nhờ ajax bằng việc tính toán các giá trị start-index và max-results

Để lại bình luận nếu gặp khó khăn và chúc thành công !
Comments:
Bạn được tự do bày tỏ quan điểm nhưng nghiêm cấm spam
  • Chèn ảnh theo mẫu [img]link[/img]
  • Chèn video Youtube theo mẫu [youtube]link[/youtube]
  • Chèn code theo mẫu [pre]code[/pre]. Lưu ý: mã hóa code trước khi bình luận

  • Quang Thắng 10/11/2018 08:09:00 PM
    Em muốn hiển thị comment gần đây ra ngoài trang chủ thì dùng code này được không a?
    Please wait while i am loading Facebook SDK js