Cách tạo widget hiển thị tổng hợp các dạng bài đăng từ widget popular posts - Trích xuất dữ liệu từ nguồn cấp

Cấu hình chỉnh sửa lại tiện ích bài đăng phổ biến trực tiếp trong chỉnh sửa HTML của chủ đề theme thêm thanh chọn các dạng bài đăng và viết script trích xuất dữ liệu từ nguồn cấp hiển thị các bài đăng theo dạng đã chọn.

Thay vì tạo mỗi widget riêng biệt hiển thị các dạng bài viết khác nhau tại sao bạn không kết hợp tất cả chúng lại thành một từ widget bài đăng phổ biến vì nó là một tiện ích mặc định hiển thị các bài được đọc nhiều nhất và lấy dữ liệu từ server của Blogger.

Đề xuất cho bạn: Hướng dẫn chỉnh sửa tiện ích PopularPosts và FeaturedPost version 2

Cụ thể, trong tiện ích bài đăng phổ biến đã có, chúng ta sẽ chỉnh sửa lại thêm các thẻ HTML bên trong tiện ích thay tiêu đề bằng một thanh chọn tương tự như select kết hợp bên dưới thêm sẵn các thẻ div để trích xuất dữ liệu từ nguồn cấp hiển thị vào các thẻ div này.

Tạo widget hiển thị tổng hợp các dạng bài đăng từ widget popular posts

Hiển thị tổng hợp các dạng bài đăng ở đây bạn cần hiểu ý nghĩa của nó thứ nhất là dạng bài đăng và thứ hai cho dù dạng bài đăng nào cũng hiển thị số bài theo dạng bài đăng đó. Tổng hợp bạn có những dạng bài đăng sau:

  1. Bài đăng phổ biến: popular posts
  2. Bài đăng mới nhất: recent posts
  3. Bài đăng ngẫu nhiên: random posts
  4. Bài đăng mới nhất theo nhãn: label posts
  5. Bài đăng liên quan theo nhãn: related posts
  6. Bài đăng có nhiều bình luận nhất: most comments
  7. Bài đăng có bình luận mới nhất: recent comments

Dữ liệu bài đăng sẽ được trích xuất từ nguồn cấp trong URL feeds ngoài ra có thể trích xuất trực tiếp từ dữ liệu bài đăng tại nhóm trang chỉ mục thông qua phương pháp GET URL bằng HTML, phần này mình sẽ viết hướng dẫn trong bài sau. Còn bài này sử dụng nguồn cấp.

Bài liên quan đến bài này: Trích xuất nội dung bài viết từ nguồn cấp blog

Cách tạo widget tổng hợp các dạng bài đăng từ widget popular posts

Bước 1: Chỉnh sửa tiện ích popular posts

Muốn chỉnh sửa tiện ích popular posts thì lẽ đương nhiên bạn phải đã thêm tiện ích từ trước rồi, chỉnh sửa ở đây là chỉnh sửa trực tiếp trong chỉnh sủa HTML của chủ đề. Với mỗi tiện ích popular posts đã thêm bạn sẽ có được số id của tiện ích theo sau tên tiện ích trong tab Chuyển đến tiện ích của theme ví dụ PopularPosts1, PopularPosts2,v.v..

Công việc của bạn là chuyển đến tiện ích popular posts muốn tích hợp các dạng bài đăng, chẳng hạn như ở đây mình sử dụng tiện ích PopularPosts2, nó có dạng như này

<b:widget id='PopularPosts2' locked='true' title='Bài đăng phổ biến' type='PopularPosts' version='2' visible='true'>
  <b:widget-settings>
    <b:widget-setting name='numItemsToShow'>10</b:widget-setting>
    <b:widget-setting name='showThumbnails'>true</b:widget-setting>
    <b:widget-setting name='showSnippets'>true</b:widget-setting>
    <b:widget-setting name='timeRange'>LAST_WEEK</b:widget-setting>
  </b:widget-settings>
  <b:includable id='main' var='this'>
      <b:include name='widget-title'/>
      <div class='widget-content'>
        <b:loop values='data:posts' var='post'>
          <!--Thẻ dữ liệu bài viết mặc định của tiện ích-->
        </b:loop>
    </div>
  </b:includable>
</b:widget>

Đề xuất cho bạn: Hiển thị view Blog khi tắt hoặc chặn js mặc định

Đầu tiên sẽ thay thẻ tiêu đề tiện ích <b:include name='widget-title'/> bằng thanh chọn dạng bài

<div class='select-option'>
  <div aria-expanded='false' aria-label='Bài đăng phổ biến' aria-pressed='false'  role='button' tabindex='0'>Bài đăng phổ biến</div>
  <ul aria-hidden='true'>
    <li aria-selected='true' data-type='popular posts' role='tab' tabindex='0'>Bài đăng phổ biến</li>
    <li aria-selected='false' data-item='10' data-type='recent posts' role='tab' tabindex='0'>Bài đăng mới</li>
    <li aria-selected='false' data-item='10' data-type='random posts' role='tab' tabindex='0'>Bài viết đề xuất</li>
    <li aria-selected='false' data-item='10' data-type='most comments' role='tab' tabindex='0'>Thảo luận nhiều</li>
    <li aria-selected='false' data-item='10' data-type='recent comments' role='tab' tabindex='0'>Thảo luận mới</li>
    <li aria-selected='false' data-category='thu-thuat-blogspot' data-item='10' data-type='label posts' role='tab' tabindex='0'>Thủ thuật blogspot</li>
    <li aria-selected='false' data-category='thiet-ke-blogspot' data-item='10' data-type='related posts' role='tab' tabindex='0'>Thiết kế blogspot</li>
  </ul>
</div>

Các thuộc tính bên trong thẻ li sử dụng để trích xuất dữ liệu từ thẻ đó

  • data-item: số bài đăng
  • data-type: dạng bài đăng
  • data-category: nhãn bài đăng

Trong thẻ ul bạn có thể thêm bao nhiêu thẻ li cũng được nhưn cần nhớ

  • Thẻ li đầu tiên là thẻ của bài đăng phổ biến trong đó phải được thêm thuộc tính data-type='popular posts'
  • Các thẻ li tiếp theo có thể thêm bao nhiêu tùy ý nhưng bắt buộc phải có thuộc tính data-item='số bài đăng' và data-type='dạng bài đăng'
  • Với dạng bài theo label cần thêm thuộc tính data-category='tên nhãn bài đăng'

Tiếp theo sẽ chỉnh sửa thẻ div với class="widget-content"

 <div class='widget-content'>
  <b:loop values='data:posts' var='post'>
    <!--Thẻ dữ liệu bài viết mặc định của tiện ích popular posts-->
  </b:loop>
</div>

Bạn sẽ sửa thành như sau:

 <div class='widget-content'>
  <!--thêm thẻ div bao quanh tiện ích popular posts-->
  <div>
    <b:loop values='data:posts' var='post'>
      <!--Thẻ dữ liệu bài viết mặc định của tiện ích popular posts-->
    </b:loop>
  </div>
  <!--Thêm các thẻ div hiển thị dữ liệu tương ứng với số thẻ li-->
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

Cụ thể, trong thẻ ul của thanh chọn dạng bài, bạn thêm bao nhiêu thẻ li thì bên dưới bạn sẽ thâm bấy nhiêu thẻ div tương ứng với số thẻ li đã thêm. Ví dụ bạn thêm 6 thẻ li cộng với thẻ li đầu tiên của tiện ích popular posts tổng cộng bạn có tất cả 7 thẻ li. Như vậy bên trong thẻ div với class='widget-content' bạn sẽ cần thêm 7 thẻ div tương xứng với 7 thẻ li ở trên.

Bước 2: Viết script trích xuất dữ liệu hiển thị theo dạng bài đăng, đặt code trước thẻ đóng </body> yêu cầu theme đã được chèn sẵn link jquery vì code này được viết bằng jqurey.

<script>//<![CDATA[
  window.addEventListener('load',function(){
    var div=$('.select-option>div'),
      ul=$('.select-option>ul'),
      cate=$('.select-option li'),
      item=$('#PopularPosts2 .widget-content>div')
    function load_script(i){
      i=$(this).index()
      var cate_type=$(this).attr('data-type')
      if(cate_type!='popular posts')var r=Number($(this).attr('data-item'))
      if($(this).attr('data-category')!=null)var cate_name=$(this).attr('data-category')
      else cate_name=''
      if(cate_type=='recent posts')var cate_url='/feeds/posts/default'
      else if(cate_type=='label posts')cate_url='/feeds/posts/default/-/'+cate_name
      else if(cate_type=='random posts')cate_url='/feeds/posts/summary?alt=json&max-results=0'
      else if(cate_type=='related posts')cate_url='/feeds/posts/summary/-/'+cate_name+'?alt=json&max-results=0'
      else if(['recent comments','most comments'].includes(cate_type))cate_url='/feeds/posts/summary?alt=json&max-results=150'
      else cate_url=''
      function get_data(e){
        if(e.feed.entry){
          for(var t=0;t<e.feed.entry.length;t++){
            var entry=e.feed.entry[t]
            <!--Lấy nội dung từ nguồn cấp-->
            var contents=''
            $(item[i]).append(contents)
          }
        }
      }
      if(cate_type=='random posts'){
        $.get(cate_url,function(data){
          if(data.feed){
            var a=data.feed.openSearch$totalResults.$t
            if(a<r)r=a
            let arr=[]
            do{
              let num=Math.floor(Math.random()*a)
              arr.push(num)
              arr=arr.filter((item, index)=>{
                return arr.indexOf(item)===index
              })
            }while(arr.length<r)
            arr.forEach(function(m){
              m+=1
              $.ajax({type:'GET',url:'/feeds/posts/default',data:{'alt':'json','start-index':m,'max-results':1},dataType:'jsonp',success:get_data})
            })
          }
        },'jsonp')
      }else if(cate_type=='related posts'){
        $.get(cate_url,function(data){
          if(data.feed){
            var a=data.feed.openSearch$totalResults.$t
            if(a<r)r=a
            let arr=[]
            do{
              let num=Math.floor(Math.random()*a)
              arr.push(num)
              arr=arr.filter((item,index)=>{
                return arr.indexOf(item)===index
              })
            }while(arr.length<r)
            arr.forEach(function(m){
              m+=1
              $.ajax({type:'GET',url:'/feeds/posts/default/-/'+cate_name,data:{'alt':'json','start-index':m,'max-results':1},dataType:'jsonp',success:get_data})
            })
          }
        },'jsonp')
      }else if(['recent posts','label posts'].includes(cate_type)){
        $.ajax({type:'GET',url:cate_url,data:{'alt':'json','max-results':r},dataType:'jsonp',success:get_data})
      }else if(cate_type=='most comments'){
        $.get(cate_url,function(data){
          if(data.feed){
            var arr=[],f=0
            for(var k=0;k<data.feed.entry.length;k++){
              var entry=data.feed.entry[k]
              if('thr$total' in entry){
                if(entry.thr$total.$t>0){
                  arr.push(entry.thr$total.$t+':'+k)
                }
              }
            }
            arr.sort(function(b,c){
              b=b.substr(0,b.indexOf(':'))
              c=c.substr(0,c.indexOf(':'))
              return c-b
            })
            f=(arr.length>r)?r:f=arr.length
            arr=arr.slice(0,f)
            arr.forEach(function(m){
              m=m.substr(m.indexOf(':')+1,m.length)
              m=Number(m)+1
              $.ajax({type:'GET',url:'/feeds/posts/default',data:{'alt':'json','start-index':m,'max-results':1},dataType:'jsonp',success:get_data})             
            })
          }
        },'jsonp')
      }else if(cate_type=='recent comments'){
        $.get(cate_url,function(data){
          if(data.feed){
            var arr=[],f=0
            for(var k=0;k<data.feed.entry.length;k++){
              var entry=data.feed.entry[k]
              if('thr$total' in entry){
                if(entry.thr$total.$t>0){
                  arr.push(entry.thr$total.$t+':'+k)
                }
              }
            }
            f=(arr.length>r)?r:f=arr.length
            arr=arr.slice(0,f)
            arr.forEach(function(m){
              m=m.substr(m.indexOf(':')+1,m.length)
              m=Number(m)+1
              $.ajax({type:'GET',url:'/feeds/posts/default',data:{'alt':'json','start-index':m,'max-results':1},dataType:'jsonp',success:get_data})             
            })
          }
        },'jsonp')
      }
    }
    $(cate).one('click',load_script)
    $(div).click(function(e){
      e.stopPropagation()
      $(this).attr('aria-expanded',function(i,attr){return attr=='true'?'false':'true'})
      $(this).attr('aria-pressed',function(i,attr){return attr=='true'?'false':'true'})
      $(this).parent().find('ul').attr('aria-hidden',function(i,attr){return attr=='true'?'false':'true'})
      $(this).parent().find('ul').toggleClass('visible')
    })
    $('html').click(function(){
      $(div).attr({'aria-expanded':'false','aria-pressed':'false'})
      $(ul).removeClass('visible').attr('aria-hidden','true')
    })
    $(cate).click(function(i){
      i=$(this).index()
      $(this).attr('aria-selected','true')
      $(cate).not($(this)).attr('aria-selected','false')
      $(div).attr('aria-label',$(this).text()).html($(this).text())
      $(ul).removeClass('visible')
      $(item[i]).fadeIn()
      $(item).not($(item[i])).fadeOut()
    })
  })
//]]></script>

Bài liên quan: Làm thế nào để tối ưu trang tải nhanh khi tải URL nguồn cấp?

Công việc của bạn cần code lấy dữ liệu từ nguồn cấp trng hàm function get_data, viết như thế nào thì bạn cần tham khảo bài liên quan mình đã đề cập ở trên.

function get_data(e){
  if(e.feed.entry){
    for(var t=0;t<e.feed.entry.length;t++){
      var entry=e.feed.entry[t]
      <!--Lấy nội dung từ nguồn cấp-->
      var contents=''
      $(item[i]).append(contents)
    }
  }

Vấn đề bạn sẽ ráp các thẻ trong var contents='' như thế nào? Thì đơn giản nhất không phải code thêm css nữa bạn cứ lấy theo bố cục bài đăng của tiện ích popular posts mà đưa vào thôi. Lấy ví dụ bố cục một bài hiển thị trong tiện ích popular posts như sau:

<div class="post">
  <!--ảnh-->
  <div class="item-thumbnail">
    <a href="" title="">
      <img alt="" class="" src=""/>
    </a>
  </div>
  <!--tiêu đề-->
  <div class="item-title">
    <a href="" title=""></a>
  </div>
  <div class="item-meta">
    <!--tên nhãn-->
    <span class="item-label"><span>
    <!--ngày xuất bản-->
    <span class="item-date"><span>
  </div>
  <!--đoạn trích tóm tắt-->
  <div class="item-snippet"></div>
</div>

Thì bạn sẽ ráp vào như sau:

var contents='<div class="post"><div class="item-thumbnail"><a href="" title=""><img alt="" class="" src=""/></a></div><div class="item-title"><a href="" title=""></a></div><div class="item-meta"><span class="item-label"><span><span class="item-date"><span></div><div class="item-snippet"></div></div>'

Bước 3: Code css tham khảo cho giao diện thanh chọn đặt trước thẻ đóng </head>

<b:if cond='data:widgets.PopularPosts'>
<b:tag name='style'>/* <![CDATA[ */
.select-option{position:relative}
.select-option>div{background:#f5f8fa;margin-bottom:15px;border:1px solid;border-color:#e6ecf0;padding:0 13px;border-radius:4px;line-height:36px}
.select-option>div:after{content:'';width:8px;height:8px;overflow:hidden;border:1px solid #2d2d2d;border-top:1px solid transparent;border-left:1px solid transparent;position:absolute;box-sizing:border-box;right:17px;transition:all .2s ease-out}
.select-option>div[aria-pressed=false]:after{top:13px;-ms-transform:rotate(45deg);transform:rotate(45deg)}
.select-option>div[aria-pressed=true]:after{top:18px;-ms-transform:rotate(-135deg);transform:rotate(-135deg)}
.select-option>div:focus,.select-option>div[aria-pressed=true]{border-color:#66afe9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}
.select-option>ul{background:#fff;position:absolute;top:40px;z-index:10;max-height:300px;width:100%;overflow:hidden;overflow-y:auto;border:1px solid rgba(0,0,0,0.12);border-radius:4px;box-shadow:0 2px 10px 0 rgba(0,0,0,0.3)}
.select-option>ul:not(.visible){visibility:hidden;opacity:0;transition:visibility 0.3s linear,opacity 0.3s linear;}
.select-option li{line-height:36px;padding:0 15px}
.select-option li:not(:focus):not(:active):hover{background:#fff9e7}
.select-option li:focus,.select-option li:active,.select-option li[aria-selected=true]{background:#E4F0F6}
.select-option>div:focus,.select-option li:focus{outline:none!important}
@media(min-width:1025px){.select-option>div:hover,.select-option li:hover{cursor:pointer}}
/* ]]> */</b:tag>
</b:if>

Bài sau mình hướng dẫn trích xuất dữ liệu bài đăng bằng phương pháp get url trực tiếp thay vì sử dụng nguồn cấp.

Thêm đánh giá

Trở thành người đầu tiên bình luận cho bài viết này!