3.22.2026

Mẹo làm Blog với JSON: Mục lục bài viết theo từng thể loại



Bạn mến,

Sau đây tôi sẽ giới thiệu với bạn cách làm một Mục lục bài viết theo từng thể loại.



Cũng cùng mẹo đó nhưng hiển thị trên cột chính:




Trước tiên, theo dõi bài này Cách sửa mã nguồn của Blogger, nhất là ở mục B.4.

Sau đó, chèn dòng lệnh này vào giữa bất kỳ hai thẻ widgets.


<b:widget id='HTML50' locked='false' title='Contents By Category' type='HTML'>
<b:includable id='main'>
<!-- *****************http://hoctro.blogspot.com*****Dec,2006****************** -->
<!-- <b:if cond='data:blog.pageType == "item"'> -->
  <!-- only display title if it's non-empty -->
  <b:if cond='data:title != ""'>
    <h2 class='title'><data:title/></h2>
  </b:if>

  <div class='widget-content'>
<div id='data2006'/>
<script type='text/javascript'>
var homeUrl2 = "hoctro.blogspot.com";
var labels = ["Killer Hacks","Simple Hacks",
 "3 Column Templates", "Ajax Hacks","Custom Widgets", "Hacking Techniques"];

function listEntries2(json) {
  var ul = document.createElement('ul');

  for (var i = 0; i &lt; json.feed.entry.length; i++) {
    var entry = json.feed.entry[i];
    var alturl;

    for (var k = 0; k &lt; entry.link.length; k++) {
      if (entry.link[k].rel == 'alternate') {
        alturl = entry.link[k].href;
        break;
      }
    }
    var li = document.createElement('li');
    var a = document.createElement('a');
    a.href = alturl;

    var txt = document.createTextNode(entry.title.$t);
    a.appendChild(txt);
    li.appendChild(a);
    ul.appendChild(li);
  }

  for (var l = 0; l &lt; json.feed.link.length; l++) {
    if (json.feed.link[l].rel == 'alternate') {
      var raw = json.feed.link[l].href;
      var label = raw.substr(homeUrl2.length+21);
      var k;
      for (k=0; k&lt;20; k++)
      label = label.replace("%20", " ");
      var txt = document.createTextNode(label);
      var h = document.createElement('h4');
      h.appendChild(txt);
      var div1 = document.createElement('div');
      div1.appendChild(h);
      div1.appendChild(ul);
      document.getElementById('data2006').appendChild(div1);
    }
  }
}

function search2(query, label) {

var script = document.createElement('script');
script.setAttribute('src', 'http://' + query + '/feeds/posts/default/-/' + label +
'?alt=json-in-script&amp;callback=listEntries2');
script.setAttribute('type', 'text/javascript');
document.documentElement.firstChild.appendChild(script);
}

for (var i=0; i &lt; labels.length; i++) 
  if (labels[i])search2(homeUrl2, labels[i]);
</script>
  </div>

  <b:include name='quickedit'/>
<!-- </b:if> -->
</b:includable>
</b:widget>



Sau đó, bạn cần thay đổi đôi chút để blogger lấy dữ liệu từ trang blog của bạn.

Thay vào những chỗ in đậm tên của blog bạn, và các nhãn bạn cần hiển thị:


var homeUrl2 = "hoctro.blogspot.com";
var labels = ["Killer Hacks","Simple Hacks",
 "3 Column Templates", "Ajax Hacks","Custom Widgets", "Hacking Techniques"];


Dòng thứ hai thực chất là một mảng (array) trong đó các thành tố (nhãn - labels của bạn) nằm trong ngoặc kép, và cách nhau bằng những dấu phẩy.

Lưu Ý:

1. Cách làm trên thực hiện rất thành công trên trang tiếng Anh của tôi cũng như các trang tiếng Anh, Pháp khác, nhưng khi sử dụng các thứ tiếng ngoài bảng ASCII thì lại không dùng được! Vì, tôi dùng data từ JSON feedback để lấy label, các data này encoding dưới dạng ASCII. Để trick Blogger, tôi phải làm thêm labels không có dấu.


Chúc bạn thành công!

Hoctro
12/13/06

5 comments:

Hogashi said...

Em có ý kiến thế này về việc các trình duyệt nó mã hóa các nhãn tiếng Việt.
Nếu ta không thể nào giải mã được thì tại sao ta không sử dụng luôn cái mảng labels đã có?
Tuy cách làm của em hơi ngốc nghếch nhưng em thấy nó hiển thị vẫn tốt.
Anh thử vào trang http://beta-hogashi.blogspot.com/ xem thử xem ;)

Hoctro said...

Hề hề, đâu có đơn giản như vậy? JSON data khi nó quay trở về có khi dài khi ngắn, khi hoctro lảm thử với data ngay trong site hoctro.blogspot.com thì nó trả về lung tung cả lên. Vấn đề là ở chỗ cái callback nó không cho tham số (parameter) đi kèm, nên mình không có rinh theo cái label được.

Hồng coi lại code hoctro đưa nhé, bên trang tiếng Anh có sửa rất nhiều để data trả về đồng bộ với label.

Chúc vui vẻ nhé

Hogashi said...

Cám ơn anh nhé, em đã lên trang tiếng Anh của anh xem rồi.
Em không hiểu ở chỗ vì sao đôi khi các bài lại không trùng với nhãn của nó. Lần đầu tiên thử đoạn code này em cứ ngỡ trình duyệt hiển thị sai vì có lúc đúng lúc không đúng. Anh có thể giải thích dùm em không?
Em biết là callback gọi về một hàm nó không cho mình tham số ngoài cái json. Vì thế em đã sử dụng một biến toàn cục lưu giá trị là 0. Em đã thay đoạn mã:

      var label = raw.substr(homeUrl.length+21);
      var k;
      for (k=0; k < 20; k++)
      label = label.replace("%20", " ");

thành

      var label = labels[x];
      x++;

Biến x là biến toàn cục mà em đã khởi tạo. Như thế giá trị của label sẽ phụ thuộc vào mảng labels mà mình đã khởi tạo chứ không phụ thuộc vào địa chỉ url trả về.
Hiện nay thì em vẫn chưa thấy bug của đoạn mã trên, nếu anh phát hiện được thì cũng nói với em nhé. Như thế cũng giúp em có thêm 1 chút kinh nghiệm ^^

Hoctro said...

@Hồng:

Lần trước hoctro bị sai là vì dùng 2 lần cái document.getElementById, mà do nhiều labels, nên giữa hai câu gọi đó cái khác xen vào. Thường thì tựa hiện lên trước rồi data hiện lên sau. Lỗi này đã chỉnh xong.

Gọi hàm local cũng OK nhưng không bảo đảm là data trả về đúng, vì có cái nhanh cái chậm. THí dụ ta có câu gọi json data gồm 99 posts của data[0], thí dụ nó về sau data[1], tức nhiên nó lấy label của data[1], trong khi data[1] lại lấy nhãn của thằng data[0]. Not good.

Chúc vui nhé

Hogashi said...

Cám ơn anh đã giải thích nhé ^^
Còn về vấn đề dữ liệu của các nhãn thì em chưa nghĩ đến, để em xem lại vậy.