related postsKhi đặt bút viết bài này (chính xác hơn là đặt tay lên bàn phím) mình băn khoăn không biết có nên viết không. Đây là chủ đề không mới và có thể 1 số bạn không xem xét kỹ code mà chỉ lướt qua tiêu đề rồi cho rằng mình lấy code ở 1 nơi khác rồi xào lại. Ở bài Bài viết liên quan cho Blogger - Related Posts mình có nói thủ thuật được phát triển bởi một blogger người Ấn Độ. Thực ra code ban đầu mình xem ở 1 template tại Btemplates và nó có nhược điểm là vẫn hiển thị tên bài đang xem ở danh sách bài viết liên quan. Khi tình cờ vào blog của Harish mình để ý thấy lỗi này đã được fix và mình cho rằng Harish đã sửa được lỗi đó. Tuy nhiên blog này có viết bài về phân trang và sử dụng code của Abu Farhan nhưng đề bản quyền bởi Harish thì mình tự hỏi điều tương tự có xảy ra với Related Posts?

Quay lại bài viết này. Khi chưa có widget Popular Posts thì ảnh ở feed có kích thước với ảnh trên blog nên mình không quan tâm đến Related Posts with thumbnails vì cho rằng nó làm giảm tốc độ của blog. Hiện nay ảnh ở đây có kích thước 72x72 pixels, vấn đề dung lượng không còn quan trọng và mình bắt đầu thêm hiển thị ảnh. Khi test với bài viết có hơn 2 nhãn mình mới phát hiện ra hình ảnh không còn đúng với bài viết, nguyên nhân do chưa khai báo biến này trong hàm removeRelatedDuplicates (đây là hàm loại bỏ nội dung trùng lặp, khi mà 1 bài viết xuất hiện ở 2 nhãn). Như vậy ở bài Bài viết liên quan cho Blogger - Related Posts lâu nay đã bị lỗi hiển thị ngày tháng đăng bài khi ở bài viết gắn với hơn 1 nhãn. Qua bài viết này mình cũng muốn thông báo và xin lỗi đến những bạn đã áp dụng thủ thuật đó, mình đã update lại code.

Những thủ thuật mình giới thiệu nếu chủ đề không mới thì có nghĩa mình đã thêm một vài tính năng nào đó, Related Posts with thumbnails cũng vậy. Thừa hưởng từ thủ thuật trước là loại bỏ bài viết đang xem ở danh sách bài viết liên quan thì ở bản này mình thêm hình ảnh, ngày tháng đăng bài và số lượng comments trong bài viết đó, đây là những thông tin mà mình cảm thấy cần thiết. Ngoài ra thì mình có thêm 2 tính năng nữa là hiển thị thông báo không có bài viết liên quan (điều này xảy ra khi trong 1 nhãn chỉ có 1 bài viết và bài viết đó cũng chỉ gắn với 1 nhãn) và lựa chọn có hiển thị số lượng comments hay không (dành cho blog chỉ đơn giản như 1 trang tin và không bật commnet hoặc là blog không sử dụng comment mặc định của Blogger).

Ở đây mình giới thiệu 2 kiểu là hiển thị theo hàng dọc và hiển thị theo hàng ngang.

Kiểu 1: Hiển thị Related Posts theo hàng dọc.

related posts thumbnails style 1

  • Bước 1: Thêm đoạn mã dưới đây vào trước thẻ ]]></b:skin> trong template của bạn.
    #related-posts{float:left}
    #related-posts ul{margin:0;padding:0;list-style-type:none}
    #related-posts ul li{padding:10px 0}
    #related-posts ul li:hover img{width:42px;height:42px;padding:0}
    #related-posts img{float:left;border:1px solid #BBB;margin-right:10px;width:36px;height:36px;background:#FFF;padding:3px}
    #related-posts h3{margin:0;font-size:16px}
  • Bước 2: Thêm đoạn mã dưới đây vào sau thẻ <div class='post-footer'> trong template của bạn.
    <b:if cond='data:blog.pageType == &quot;item&quot;'>
    <div style='clear:both'/>
    <div id='related-posts'>
    <script type='text/javascript'>var ry='<h2>Bài viết liên quan</h2>';rn='<h2>Không có Bài viết liên quan</h2>';rcomment='Nhận xét';rdisable='Tắt Nhận xét';commentYN='yes';</script>
    <script type='text/javascript'>
    //<![CDATA[
    var dw='';titles=new Array();titlesNum=0;urls=new Array();timeR=new Array();thumb=new Array();commentsNum=new Array();comments=new Array();function related_results_labels(c){for(var b=0;b<c.feed.entry.length;b++){var d=c.feed.entry[b];titles[titlesNum]=d.title.$t;for(var a=0;a<d.link.length;a++){if('thr$total' in d){commentsNum[titlesNum]=d.thr$total.$t+' '+rcomment}else{commentsNum[titlesNum]=rdisable};if(d.link[a].rel=="alternate"){urls[titlesNum]=d.link[a].href;timeR[titlesNum]=d.published.$t;if('media$thumbnail' in d){thumb[titlesNum]=d.media$thumbnail.url}else{thumb[titlesNum]='http://lh4.ggpht.com/_u7a1IFxc4WI/TTjruHJjcfI/AAAAAAAAAk0/i11Oj6i_bHY/no-image.png'};titlesNum++;break}}}}function removeRelatedDuplicates(){var b=new Array(0);c=new Array(0);e=new Array(0);f=new Array(0);g=new Array(0);for(var a=0;a<urls.length;a++){if(!contains(b,urls[a])){b.length+=1;b[b.length-1]=urls[a];c.length+=1;c[c.length-1]=titles[a];e.length+=1;e[e.length-1]=timeR[a];f.length+=1;f[f.length-1]=thumb[a];g.length+=1;g[g.length-1]=commentsNum[a]}}urls=b;titles=c;timeR=e;thumb=f;commentsNum=g}function contains(b,d){for(var c=0;c<b.length;c++){if(b[c]==d){return true}}return false}function printRelatedLabels(a){for(var b=0;b<urls.length;b++){if(urls[b]==a){urls.splice(b,1);titles.splice(b,1);timeR.splice(b,1);thumb.splice(b,1);commentsNum.splice(b,1)}}var c=Math.floor((titles.length-1)*Math.random());var b=0;if(titles.length==0){dw+=rn}else{dw+=ry;dw+='<ul>';while(b<titles.length&&b<20&&b<maxresults){if(commentYN=='yes'){comments[c]=' - '+commentsNum[c]}else{comments[c]=''};dw+='<li><img alt="'+titles[c]+'" src="'+thumb[c]+'"/><div><a href="'+urls[c]+'" rel="nofollow"><h3>'+titles[c]+'</h3></a><span>'+timeR[c].substring(8,10)+'/'+timeR[c].substring(5,7)+'/'+timeR[c].substring(0,4)+comments[c]+'</span></div></li><div style="clear:both"></div>';if(c<titles.length-1){c++}else{c=0}b++}dw+='</ul>'};urls.splice(0,urls.length);titles.splice(0,titles.length);document.getElementById('related-posts').innerHTML=dw};
    //]]>
    </script>
    <b:loop values='data:post.labels' var='label'>
    <script expr:src='&quot;/feeds/posts/default/-/&quot; + data:label.name + &quot;?alt=json-in-script&amp;callback=related_results_labels&quot;' type='text/javascript'/>
    </b:loop>
    <script type='text/javascript'>var maxresults=6;removeRelatedDuplicates();printRelatedLabels('<data:post.url/>');</script>
    </div>
    <div style='clear:both'/>
    </b:if>

Kiểu 2: Hiển thị Related Posts theo hàng ngang.

related posts thumbnails style 2

  • Bước 1: Thêm đoạn mã dưới đây vào trước thẻ ]]></b:skin> trong template của bạn.
    #related-posts{float:left}
    #related-posts ul{margin:5px 0;width:524px;padding:0;list-style-type:none}
    #related-posts ul li{position:relative;float:left;border:0 none;margin-right:11px;width:76px}
    #related-posts ul li:hover{z-index:98}
    #related-posts ul li:hover img{border:3px solid #BBB}
    #related-posts ul li:hover div{position:absolute;top:40px;left:10px;margin-left:0;width:200px}
    #related-posts ul li img{border:3px solid #DDD;width:70px;height:70px;background:#FFF}
    #related-posts ul li div{position:absolute;z-index:99;margin-left:-999em}
    #related-posts ul li .title{border:1px solid #CCC;background:#FFF;padding:5px 10px}
  • Bước 2: Thêm đoạn mã dưới đây vào sau thẻ <div class='post-footer'> trong template của bạn.
    <b:if cond='data:blog.pageType == &quot;item&quot;'>
    <div style='clear:both'/>
    <div id='related-posts'>
    <script type='text/javascript'>var ry='<h2>Bài viết liên quan</h2>';rn='<h2>Không có Bài viết liên quan</h2>';rcomment='Nhận xét';rdisable='Tắt Nhận xét';commentYN='yes';</script>
    <script type='text/javascript'>
    //<![CDATA[
    var nothumb='http://lh4.ggpht.com/_u7a1IFxc4WI/TTjruHJjcfI/AAAAAAAAAk0/i11Oj6i_bHY/no-image.png';dw='';titles=new Array();titlesNum=0;urls=new Array();time=new Array();thumb=new Array();commentsNum=new Array();comments=new Array();function related_results_labels(c){for(var b=0;b<c.feed.entry.length;b++){var d=c.feed.entry[b];titles[titlesNum]=d.title.$t;for(var a=0;a<d.link.length;a++){if('thr$total' in d){commentsNum[titlesNum]=d.thr$total.$t+' '+rcomment}else{commentsNum[titlesNum]=rdisable};if(d.link[a].rel=="alternate"){urls[titlesNum]=d.link[a].href;time[titlesNum]=d.published.$t;if('media$thumbnail' in d){thumb[titlesNum]=d.media$thumbnail.url}else{thumb[titlesNum]=nothumb};titlesNum++;break}}}}function removeRelatedDuplicates(){var b=new Array(0);c=new Array(0);e=new Array(0);f=new Array(0);g=new Array(0);for(var a=0;a<urls.length;a++){if(!contains(b,urls[a])){b.length+=1;b[b.length-1]=urls[a];c.length+=1;c[c.length-1]=titles[a];e.length+=1;e[e.length-1]=time[a];f.length+=1;f[f.length-1]=thumb[a];g.length+=1;g[g.length-1]=commentsNum[a]}}urls=b;titles=c;time=e;thumb=f;commentsNum=g}function contains(b,d){for(var c=0;c<b.length;c++){if(b[c]==d){return true}}return false}function printRelatedLabels(a){for(var b=0;b<urls.length;b++){if(urls[b]==a){urls.splice(b,1);titles.splice(b,1);time.splice(b,1);thumb.splice(b,1);commentsNum.splice(b,1)}}var c=Math.floor((titles.length-1)*Math.random());var b=0;if(titles.length==0){dw+=rn}else{dw+=ry;dw+='<ul>';while(b<titles.length&&b<20&&b<maxresults){if(commentYN=='yes'){comments[c]=' - '+commentsNum[c]}else{comments[c]=''};dw+='<li><a href="'+urls[c]+'" rel="nofollow"><img alt="'+titles[c]+'" src="'+thumb[c]+'"/></a><div class="title"><a href="'+urls[c]+'" rel="nofollow"><h3>'+titles[c]+'</h3></a><span>'+time[c].substring(8,10)+'/'+time[c].substring(5,7)+'/'+time[c].substring(0,4)+comments[c]+'</span></div></li>';if(c<titles.length-1){c++}else{c=0}b++}dw+='</ul>'};urls.splice(0,urls.length);titles.splice(0,titles.length);document.getElementById('related-posts').innerHTML=dw};
    //]]>
    </script>
    <b:loop values='data:post.labels' var='label'>
    <script expr:src='&quot;/feeds/posts/default/-/&quot; + data:label.name + &quot;?alt=json-in-script&amp;callback=related_results_labels&quot;' type='text/javascript'/>
    </b:loop>
    <script type='text/javascript'>var maxresults=6;removeRelatedDuplicates();printRelatedLabels('<data:post.url/>');</script>
    </div>
    <div style='clear:both'/>
    </b:if>

maxresults là số bài viết liên quan được hiển thị, mình đặt là 6. Mặc định số lượng comments sẽ được hiển thị, nếu bạn không muốn hãy thay ký tự yes màu tím thành ký tự khác, no chẳng hạn. Số lượng bài viết ở mỗi nhãn được tải về từ feed lấy theo mặc định là 25 bài mới nhất, nếu nhiều hơn mình nghĩ sẽ làm chậm tốc độ blog.

Về CSS cũng như bao thủ thuật khác mình không chú trọng đến giao diện mà quan tâm đến việc hiển thị trên các trình duyệt nhiều hơn. Ngoài ra mặc dù thông tin hiển thị bằng Javascript nhưng mình vẫn thêm thẻ alt cho ảnh, tiêu đề đặt trong cặp thẻ H3 và thuộc tính rel=nofollow cho thẻ liên kết. Mình nhận thấy Google vẫn hiển thị thông tin viết bởi Javascript trong kết quả tìm kiếm.