Labels

Blogger JSON Feed API - Feed Post Labels


Feed post labels có thể coi là con của feed post, thay vì tải tất cả các bài viết nó sẽ lọc bài viết theo label để hiển thị dữ liệu, feed post labels được sử dụng rất phổ biến để tạo các widget hiển thị bài đăng theo nhãn ngoài trang chủ hoặc bài đăng liên quan trong trang bài viết

Tương tự như feed post, feed post labels cũng có 2 dạng
  • /feeds/posts/default/-/label-name?alt=json&max-results=50 
  • /feeds/posts/summary/-/label-name?alt=json&max-results=50 

Dữ liệu được cung cấp tương tự như feed post, thông thường khi build widget cho feed post labels ta thường lấy các loại dữ liệu sau
  • link bài viết
  • số lượt bình luân
  • link dẫn tới khung bình luân
  • đoạn trích ngắn
  • tiêu đề bài đăng
  • tên tác giả
  • ngày tháng đăng bài
  • ảnh thumbnail

Cách lấy như nào thì ở bài viết với feed post tôi đã trình bày rồi nên xin phép không nhắc lại nữa. Bài viết này tôi sẽ demo cho bạn luôn 1 sản phẩm từ feed label post

demo
Ta sẽ lần lượt đi phân tích như sau

Khi thiết kế template ta sẽ thường đặt các mã HTML trong widget cùng với một vài thuộc tính đi kèm để phục vụ cho code js

Ví dụ ở đây tôi sử dụng

<span data-label="Sport" data-no="4"></span>

Khi hiển thị sẽ không có gì, không ảnh hưởng tới bố cục. Trong đó 2 thuộc tính data-label và data-no sẽ là đầu vào người dùng cung cấp lần lượt sẽ là tên label muốn hiển thị và số lượng bài tương ứng. Đương nhiên đây không phải là cách đặt duy nhất, bạn có thể đặt theo ý của mình miễn sao cho code js lấy được 2 giá trị này để load dữ liệu là được

Khi viết hoàn chỉnh đặt vào section > widget sẽ như sau

<div class='featured-box-wrapper row'>
    <b:section class='featured-box' id='featured-box' showaddelement='yes'>
        <b:widget id='HTML777' locked='true' title='Featured' type='HTML' version='1'>
            <b:widget-settings>
                <b:widget-setting name='content'>
                    <![CDATA[<span data-label="Sport" data-no="4"></span>]]></b:widget-setting>
            </b:widget-settings>
            <b:includable id='main'>
                <b:if cond='data:title != &quot;&quot;'>
                    <h2 class='title'><data:title/></h2>
                </b:if>
                <div class='widget-content'>
                    <data:content/>
                </div>
            </b:includable>
        </b:widget>
    </b:section>
</div>

Render sang mã HTML sẽ thu được

<div class='featured-box-wrapper row'>
    <!-- Mã HTML Render ra từ widget -->
    <div class='featured-box section' id='featured-box'>
        <div class='widget HTML' data-version='1' id='HTML777'>
            <h2 class='title'>Featured 1</h2>
            <div class='widget-content'>
                <span data-label="Sport" data-no="4"></span>
            </div>
        </div>
    </div>
</div>

Khi đã có đầu vào rồi ta sẽ thi triển js. Ở đây tôi đã viết comment rất kĩ, bạn chú ý cả selector và đọc từng dòng để hiểu code nhé

<!--// Sử dụng ajax yêu cầu có thư viện jQuery-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">//<![CDATA[
var month_format = [, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"];
var text_cmt = "Bình luận";
var perPage = 10;

$(".featured-box .HTML .widget-content").each(function() { // lặp qua từng widget
    var a1 = $(this).find("span").attr("data-label"), // lấy label name từ thuộc tính data-label
        a2 = $(this).find("span").attr("data-no"), // lấy số bài cần hiển thị để gán cho max-results
        a3 = $(this).parent().attr("id"); // lấy id của widget mục đích để code có thể chạy khi tạo nhiều widget với label name khác nhau
    $.ajax({
        url: "/feeds/posts/default/-/" + a1 + "?alt=json&max-results=" + a2,
        type: "get",
        dataType: "jsonp",
        success: function(e) {
            r = '<div class="featured-wrap">'; // tạo 1 div bao bọc bên ngoài
            for (var n = 0; n < e.feed.entry.length; n++) { // lặp qua từng entry để lấy dữ liệu

                // lấy link bài viết
                for (var s = 0; s < e.feed.entry[n].link.length; s++) {
                    if (e.feed.entry[n].link[s].rel === "alternate") {
                        t = e.feed.entry[n].link[s].href;
                        break
                    }
                }

                // lấy số nhận xét và link nhận xét
                for (var d = 0; d < e.feed.entry[n].link.length; d++) {
                    if ("replies" === e.feed.entry[n].link[d].rel && "text/html" === e.feed.entry[n].link[d].type) {
                        i = e.feed.entry[n].link[d].title;
                        q = e.feed.entry[n].link[d].href;
                        break
                    }
                }
                i = parseInt(i, 10) // chỉ lấy số, bỏ text

                // tạo rẽ nhánh để lấy đoạn trích ngắn áp dụng cho cả /default và /summary
                if ("content" in e.feed.entry[n])
                    l = e.feed.entry[n].content.$t;
                else if ("summary" in e.feed.entry[n])
                    l = e.feed.entry[n].summary.$t;
                else l = "";

                // loại bỏ kí tự đặc biệt và cắt chuỗi
                if (l.length != 0) {
                    l = l.replace(/<\S[^>]*>/g, "");
                    if (l.length > 120) {
                        l2 = l.substring(0, 100);
                        l3 = l2.lastIndexOf(" ");
                        l = l2.substring(0, l3) + ' ...';
                    }
                }

                var f = e.feed.entry[n].title.$t, // lấy tiêu đề bài đăng
                    c = e.feed.entry[n].author[0].name.$t, // lấy tên tác giả
                    h = e.feed.entry[n].published.$t, // lấy thời gian đăng bài
                    o = h.substring(0, 4), // cắt chuỗi lấy năm
                    p = h.substring(5, 7), // cắt chuỗi lấy tháng
                    u = h.substring(8, 10), // cắt chuỗi lấy ngày
                    m = month_format[parseInt(p, 10)] + " " + u + ", " + o; // định dạng lại thời gian
                // xử lý thumbnail và resize
                if ("media$thumbnail" in e.feed.entry[n]) { // nếu bài viết có thumbnail
                    d = e.feed.entry[n].media$thumbnail.url.replace("s72-c", "s1600");
                } else {
                    // nếu không có thì dùng ảnh thay thế
                    d = "https://3.bp.blogspot.com/-Yw8BIuvwoSQ/VsjkCIMoltI/AAAAAAAAC4c/s55PW6xEKn0/s1600-r/nth.png"
                }
                // tạo div và truyền dữ liệu
                r += '<div class="featured-inner"><div class="featured-thumb"><a class="featured-img" href="' + t + '" style="background:url(' + d + ') no-repeat center center;background-size: cover"></a></div><div class="featured-header"><h3 class="featured-title"><a href="' + t + '">' + f + '</a></h3><div class="featured-meta"><span class="featured-auth">' + c + '</span>&nbsp;<span class="featured-time">' + m + '</span>&nbsp;<span class="featured-cmt"><a href="' + q + '">' + i + "&nbsp;" + text_cmt + '</span></a></div><div class="featured-summary">' + l + '</div></div></div>'
            }
            r += "</div>";

            $(".featured-box .HTML .widget-content").each(function() {
                if ($(this).parent().attr("id") == a3) {
                    // chèn search label vào tiêu đề
                    $(this).prev("h2").wrapInner('<a href="/search/label/' + a1 + "?&amp;max-result=" + perPage + '"></a>')
                    $(this).html(r)
                } // kiểm tra nếu đúng id thì append mã html vào
            })
        }
    })
});
//]></script>

1 chút css để hiển thị giống demo (chưa responsive nhé)

.featured-box-wrapper,
.featured-inner:nth-child(4n+5) {
    clear: both;
}

.featured-inner {
    float: left;
    margin: 0 15px 0 0;
    width: calc(95% / 4);
}

.featured-thumb {
    width: 100%;
    height: 200px;
    overflow: hidden;
}

.featured-img {
    width: 100%;
    height: 100%;
    display: block;
}

.featured-title {
    margin: 15px 0;
    height: 44px;
    overflow: hidden;
}

.featured-title a {
    color: #000;
    cursor: pointer;
    font-weight: bold;
    text-decoration: none;
    font-size: 17px;
}

.featured-thumb a:hover {
    -webkit-transform: scale(1.1) rotate(-1.5deg);
    -moz-transform: scale(1.1) rotate(-1.5deg);
    -ms-transform: scale(1.1) rotate(-1.5deg);
    -o-transform: scale(1.1) rotate(-1.5deg);
    transform: scale(1.1) rotate(-1.5deg);
    -webkit-transition: all .25s ease;
    -moz-transition: all .25s ease;
    -ms-transition: all .25s ease;
    -o-transition: all .25s ease;
    transition: all .25s ease;
}

.featured-meta {
    margin: 0 0 10px;
    font-size: 14px;
}

.featured-summary {
    margin-bottom: 20px;
}

.featured-auth::before {
    font-family: fontawesome;
    content: '\f2c0';
    margin: 0 5px 0 0
}

.featured-time::before {
    font-family: fontawesome;
    content: '\f017';
    margin: 0 5px 0 3px
}

.featured-cmt a {
    color: #000;
    text-decoration: none
}

.featured-cmt::before {
    font-family: fontawesome;
    content: '\f0e6';
    margin: 0 5px 0 3px
}

Như đã đề cập khi đã lấy được dữ liệu bạn có thể làm bất kì thứ gì mình muốn nhờ sử dụng html kết hợp với css, bài viết không có mục đích chia sẻ tiện ích mà chủ yếu là hướng dẫn bạn cách làm, để bạn làm chủ được code html, js, css trên trang của mình cũng như có thể tự tin thiết kế các tiện ích theo ý thích

 Để lại bình luận nếu gặp khó khăn nhé ! Good luck
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

    1. Bạn Hoàng Văn cho mình hỏi code java mình đặt trước thẻ nào nhĩ, nó báo lỗi thì phải còn mình đặt trong widget thì css không load bài đăng thì vẫn hiển thị không biết mình làm sai chỗ nào nhĩ, chúc bạn sức khỏe

      Trân trọng!

      ReplyDelete