Giới thiệu với bạn tiện ích mới nhất: "Bài Viết Liên Quan".
Hãy cắt dán vào một HTML widget trong trang thiết kế để coi nó có chạy hay không.
Tôi có làm thử một cái, dùng chính đoạn mã mà tôi viết dưới đây, vào trang Anh ngữ của tôi, thì nó chạy ngay http://hoctro.blogspot.com/2010/08/testing-of-new-related-articles-widget.html . Trang Hoctro Việt cũng có tiện ích này.
Nếu bạn đã lắp các "Bài Liên Quan" widget trước của tôi, bạn cứ tự nhiên lắp tiếp cái này, chứ đừng bỏ cái kia vội. Cái mới này chỉ cần một bước cài đặt thôi, mà sau khi cài đặt xong ta có thể chuyển nó sang chỗ mới dễ dàng, không như cái cũ.
Như bạn thấy, cái tiện ích này tạo ra một dòng mã gồm những từ khóa/nhãn của trang đang xem, sau đó nó gửi lên Google, và được kết quả trả về gần sát nhất những gì bạn muốn tìm. Các kết quả này do google tìm kiếm trong trang của bạn mà thôi. Ta thấy cách này hệt như khi ta muốn tìm một bài viết nào đó trên Google http://www.google.com/ .
Theo thiển ý, đây là widget sát ý nhất với ý nghĩa "bài liên quan", vì nó đăng lên những bài giống với những từ khóa mà ta tìm nhất. tiện ích trước tôi viết không làm được điều này, vì nó chỉ trả về những kết quả mới nhất của từng nhãn trong trang mà thôi, những bài hay nhất mà xưa thì sẽ không được hiện ra. Ta đã dùng giải thuật "page ranking" của Google lần này để tìm các bài liên quan nhất.
Tôi sẽ đăng tiếp một bài viết tiếp theo về những động lực để làm tiện ích, giải thích cấu trúc mã, và những chỉnh sửa khác. Có nhiều cách như dùng CSS để chỉnh màu sắc, font chữ, hiện thêm dòng ngắn giới thiệu (snippet) hay không, v.v.
Chúc bạn thành công,
Thân mến,
Hoctro
8/16/2010
***
7/29/2026 Update; Tôi nhờ Claude Sonnet 5 sửa code để tiện ích này chạy tiếp. Nó làm xong trong vòng 10 phút. Thật kinh ngạc!!!! Code dưới đây là của nó, viết lại từ code cũ của tôi.
<!-- ===================================================================
Bài Viết Liên Quan — bản nâng cấp 2026
Thay Google AJAX Search API (đã ngừng hoạt động 11/2014) bằng
feed JSON theo nhãn của chính Blogger. Không cần API key.
Dựa trên ý tưởng gốc: Hoctro, "Related Articles - Take 5", 8/2010
https://hoctroviet.blogspot.com/2010/08/tien-ich-moi-viet-lien-quan-related.html
=================================================================== -->
<div id="hoctro-related-wrap">
<div id="hoctro-related-results">Đang tải bài viết liên quan…</div>
</div>
<style>
#hoctro-related-wrap { margin: 24px 0; }
#hoctro-related-heading { font-size: 1.05em; font-weight: bold; margin-bottom: 8px; }
#hoctro-related-results { font-size: 0.95em; }
#hoctro-related-results ul { list-style: none; margin: 0; padding: 0; }
#hoctro-related-results li { padding: 4px 0; border-bottom: 1px dotted #ccc; }
#hoctro-related-results li:last-child { border-bottom: none; }
#hoctro-related-results a { text-decoration: none; }
#hoctro-related-results a:hover { text-decoration: underline; }
#hoctro-related-results .hr-thumb { display:inline-block; width:16px; height:16px; vertical-align:middle; margin-right:6px; border-radius:2px; }
</style>
<script>
(function () {
'use strict';
var MAX_LABELS_TO_QUERY = 4; // số nhãn tối đa sẽ dò feed (giới hạn số request)
var MAX_RESULTS_SHOWN = 8; // số bài liên quan tối đa hiển thị
var callbackCounter = 0;
var pendingRequests = 0;
var collected = []; // {title, href, thumb}
var seenHrefs = {};
var currentHref = location.href.split('#')[0].split('?')[0];
function baseUrl() {
return location.protocol + '//' + location.host;
}
function escapeHtml(s) {
return String(s)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"');
}
// Bài đang xem chỉ có "liên quan" trên trang từng bài (item page).
// Blogger đặt class "item-page" hoặc <body> có data khác nhau tùy theme,
// nên cách chắc ăn nhất là: chỉ chạy nếu tìm thấy đúng 1 khối bài viết
// và có ít nhất 1 link nhãn trên trang.
function getCurrentLabels() {
var labels = [];
var seen = {};
// Các theme Blogger khác nhau đặt link nhãn ở những nơi/class khác nhau;
// dò theo thứ tự, dùng bộ chọn đầu tiên khớp được.
var selectors = [
'.post-labels a',
'.post-footer-line .labels a',
'a[rel="tag"]',
'a[href*="/search/label/"]'
];
for (var s = 0; s < selectors.length; s++) {
var links = document.querySelectorAll(selectors[s]);
if (links.length) {
for (var i = 0; i < links.length; i++) {
var href = links[i].getAttribute('href') || '';
var m = href.match(/\/search\/label\/([^?&#\/]+)/);
if (m) {
var label = decodeURIComponent(m[1].replace(/\+/g, ' '));
if (!seen[label]) { seen[label] = true; labels.push(label); }
} else if (!href) {
var text = (links[i].textContent || '').trim();
if (text && !seen[text]) { seen[text] = true; labels.push(text); }
}
}
break; // bộ chọn đầu tiên có kết quả là đủ, không dò tiếp
}
}
return labels;
}
function renderResults() {
var box = document.getElementById('hoctro-related-results');
var heading = document.getElementById('hoctro-related-heading');
if (!collected.length) {
box.innerHTML = '<em>Không tìm thấy bài viết liên quan.</em>';
return;
}
var html = '<ul>';
for (var i = 0; i < Math.min(collected.length, MAX_RESULTS_SHOWN); i++) {
var item = collected[i];
var thumb = item.thumb
? '<img class="hr-thumb" src="' + escapeHtml(item.thumb) + '" alt="">'
: '';
html += '<li>' + thumb + '<a href="' + escapeHtml(item.href) + '">' + escapeHtml(item.title) + '</a></li>';
}
html += '</ul>';
box.innerHTML = html;
heading.style.display = '';
}
function handleFeed(feed) {
pendingRequests--;
var entries = (feed && feed.feed && feed.feed.entry) ? feed.feed.entry : [];
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
var href = '';
for (var l = 0; l < entry.link.length; l++) {
if (entry.link[l].rel === 'alternate') { href = entry.link[l].href; break; }
}
if (!href || href === currentHref || seenHrefs[href]) continue;
seenHrefs[href] = true;
collected.push({
title: entry.title && entry.title.$t ? entry.title.$t : '(không có tiêu đề)',
href: href,
thumb: entry.media$thumbnail ? entry.media$thumbnail.url : ''
});
}
if (pendingRequests === 0) renderResults();
}
function queryLabel(label) {
pendingRequests++;
var cbName = 'hoctroRelatedCB_' + (callbackCounter++);
window[cbName] = function (feed) {
handleFeed(feed);
delete window[cbName];
};
var src = baseUrl() + '/feeds/posts/default/-/' + encodeURIComponent(label) +
'?alt=json-in-script&max-results=6&callback=' + cbName;
var script = document.createElement('script');
script.src = src;
script.async = true;
document.body.appendChild(script);
}
function init() {
var labels = getCurrentLabels();
if (!labels.length) {
document.getElementById('hoctro-related-results').innerHTML =
'<em>Bài này chưa gắn nhãn nên không thể tìm bài liên quan.</em>';
return;
}
labels = labels.slice(0, MAX_LABELS_TO_QUERY);
for (var i = 0; i < labels.length; i++) queryLabel(labels[i]);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
</script>


13 comments:
-ngày phía trước bài hát theo danh sách(top 100-1959) là reference của video phải không?Sao mình tìm không thấy tương đồng gì hết bên youtube nên xem đại.Thích 2 bài đầu tiên phim "Alvin &the chipmund",con trai thích bài này lắm,xem phim mà ba mẹ con cứ cười tí tởn khoái chí!
"Smokes get in your eyes" quá hay mà hình như cũng là nhạc nền của phim nào đó hay sao mình ko nhớ.
Post tốc độ chóng mặt luôn,bài đầu tiên còn chưa nghe hết và nghe quá nhiều bài có trên 20 năm mới gặp lại cảm giác cứ như đoàn viên người thân bao năm xa cách.
Càng ngày càng bị dụ dỗ là sao?
Bạn chơi ác ghê!Đồ xấu tính!
Chơi quê gì vậy bạn? không hiểu gì hết. Tui đang từ từ load #1 hits các năm 1959 tới 2000, tới 1973 rồi. Nguồn lấy từ đây:
http://en.wikipedia.org/wiki/List_of_Hot_100_number-one_singles_of_1960_%28U.S.%29
Chúc vui,
cốc cốc có ông chủ ở nhà ko?
Hôm qua,viết entry bên word copy và paste qua blog sao nó ko chịu lưu và bắt phải xoá hiển thị html rồi mình làm theo thì paste được nhưng các tilte đổi qua màu tím và gạch chân nhìn từa lưa hết trơn.Đang ở trong nhà bạn(nhà âm nhạc) vừa nghe nhạc vừa doing housework.
Thân!
Hi Leaqua, viết mấy thứ này trên Word không có work. Thường thì tui viết & edit trên notepad rồi thêm link trong Blogger.
Chúc vui,
Hi bạn, post nhạc có người thích nghe là tui zui rồi, chúc vui nhé, từ từ mình viết lại chord của Free As a Bird và các lời bình tại sao nó hay.
Have a great week Donald Duck!
you remove clip Lefevre đi-Johnny Halliday á!Không xem được báo user đã remove rồi!
DD
thanks! Đã sửa lại rồi Leaqua.
Thank you vì có nhận xét hay! Mà bài đó ở đâu??? Mình tìm hoài không thấy!
bài đó ở list 100 - 1959!
hai bài đầu tiên.
Nhận xét nào của mình cũng từ hay trở lên hết?!
Cám ơn nhiều đã sửa rồi.
Ủa, nhận xét hay cũng không được ha?
khen thì mắc cỡ, mà không khen thì hờn mát,già rồi tráí tính trái nết,rõ khổ,tui là dị đó!
Bài liên quan là tiện ích để người xem liền mạch chủ đề đang quan tâm. Với thủ thuật mới này, Tít bài xuất hiện theo kiểu bài ngẫu nhiên, phần tóm tắt nó hiện bên dưới link liên quan rất lộn xộn. Mình vãn dùng widget cũ của Học trò, đặt nhãn không dấu. Ổn và nhanh, một lần nữa cảm ơn bạn nhiều!
Hi anh Trần Hùng,
Cái cũ cũng hay, mà cái mới vì đang thử nên cũng chưa biết độ tin cậy ra sao. Anh nói cũng đúng, việc "related" nay giao phó hoàn toàn cho Google, nên nhiều khi bài trật lất!
Để hoctro tìm cách mix giữa hai cái cũ mới xem sao.
Thân,
Post a Comment