Bloggerのコメント欄を改善する
この記事は、既に最新ではありません。最新の関連記事は、「Blogger用の関連記事表示機能:FeedRelatedPosts.js」を使用しています。
「Bloggerに関連記事を表示する」の続きです。
「A Simple Related Posts Widget For Blogger」の問題点
- 関連度が低い
- 完全なランダムの連続から偏ったランダムに修正する
- 複数のラベルで重複している記事の表示確率を上げる
- 重複記事は関連度が高いものと仮定する
- コメントの記載のある記事の表示確率を上げる
- コメントのある記事は、人気があるものと仮定する
- 複数のラベルで重複している記事の表示確率を上げる
- 関連度が良くなったわけではない (´・ω・`)
- 完全なランダムの連続から偏ったランダムに修正する
- 同期読込みのため、ページの読込みをブロックする
- 非同期(async)で読込むように修正する
- 非同期の読込みで、最後のRSSフィードを読込んだ段階で関連記事を出力する
- 表示速度向上
- RSSフィードの記事内容をすべて読込むため、通信量が増える
- 概要のみ読込むように修正する
/feeds/posts/default/
→/feeds/posts/summary/
- 最新の10件のみ読み込む仕様はそのままとする
- 概要のみ読込むように修正する
- 関連記事が1つだとヘッダ部分が表示されない
- 関連記事が1つでもヘッダ部分を表示するように修正する
補足
A Simple Related Posts Widget For Bloggerでは、画像を表示できませんでした。ですが、Customizable Related Posts Widget for Bloggerであれば、画像を表示できるようです。
筆者は、画像表示の必要がなかったため、下記のコードでは非対応です。ですが、RSSフィード上に画像のurlが出力されていることまでは確認しました。画像urlの収集箇所はコメントアウトしてあるため、好みに合わせて修正ください。
修正結果
修正と言いながら、概念は同じでも全取っ替えです。
結果

※FontAwesome部分のみ下記コードと異なります。
style
style#related-posts {
margin: 0.5em 0;
border: 1px solid #aaa;
display: none;
}
#related-posts h4 {
font-size: 1.25em;
font-weight: normal;
color: #fff;
background-color: #888;
margin: 0;
border: none;
}
#related-posts ul {
padding: 0;
list-style-type: none;
background: #f9f9f9;
margin: 0;
}
#related-posts li {
padding: 0;
}
#related-posts li a {
display: block;
text-decoration: none;
padding: 3px 1em 3px 2.5em;
border-bottom: 1px solid #ddd;
}
#related-posts li a:hover {
background: #eee;
}
#related-posts li:last-child a{
border-bottom: none;
}
※BloggerテンプレートなどのCSSに依存します。配置環境毎に修正が必要です。
javascript
javascript(function(root, factory) {
if (!root.RelatedPosts) {
root.RelatedPosts = factory();
}
})(this, function() {
"use strict";
let _this = function RelatedPosts_constructor() {};
let count = 0; // フィード読み込み完了数
let limit = 0; // フィード読み込み予定数
let urls = []; // URL一覧
let titles = []; // タイトル一覧
let current = ''; // 標的ページ
let title = 'RelatedPosts'; // 関連記事タイトル
let maxresults = 5; // 最大関連記事数
// 初期化
_this.init = function RelatedPosts_init(currenturl, head, max) {
current = currenturl;
title = head;
maxresults = max;
};
// フィード数分をカウントする
_this.counter = function RelatedPosts_counter() {
limit++;
};
// 関連記事を書き込む
function RelatedPosts_write() {
// ランダムインデックス生成
let indexs = Array(urls.length);
for (let i=0, r; i<indexs.length; i++) {
r = Math.floor(Math.random() * (i+1));
if (r !== i) indexs[i] = indexs[r];
indexs[r] = i;
}
// 関連一覧の作成(重複要素は、出現しやすい)
let dups = [];
let items = [];
for (let i=0; i<indexs.length && dups.length<maxresults; i++) {
if (dups.indexOf(urls[indexs[i]]) == -1) {
dups.push(urls[indexs[i]]);
items.push('<li><a href="' + urls[indexs[i]] + '">' + titles[indexs[i]] + '</a></li>');
}
}
if (items.length > 0) {
let line = [];
line.push('<h4>' + title + '</h4>')
line.push('<ul>');
for (let i=0; i<items.length; i++) {
line.push(items[i]);
}
line.push('</ul>');
let posts = document.getElementById('related-posts');
posts.insertAdjacentHTML('beforeend', line.join(''));
posts.style.display = 'block';
}
}
// フィードの要素を追加する
_this.add = function RelatedPosts_add(json) {
let m = current.match(/^https?:\/\/(.+$)/);
let http = '';
let https = '';
if (m != null) {
http = 'http://'+m[1];
https = 'https://'+m[1];
}
for (let i=0; i<json.feed.entry.length; i++) {
let entry = json.feed.entry[i];
for (let k=0; k<entry.link.length; k++) {
if (entry.link[k].rel == 'alternate') {
if (!(http == entry.link[k].href || https == entry.link[k].href)) {
if (0 != entry.thr$total.$t) {
// コメントありの時
// 出現確率を上げる
titles.push(entry.title.$t);
urls.push(entry.link[k].href);
}
titles.push(entry.title.$t);
urls.push(entry.link[k].href);
// サムネイル画像
// Bloggerに画像が保存していることが必須
// Googleフォト等で別に画像をロードしている場合、存在しない
//if (entry.media$thumbnail) { imgs.push(entry.media$thumbnail.url); }
//else { imgs.push(''); }
}
break
}
}
}
count++;
if (count == limit) {
RelatedPosts_write();
urls.splice(0, urls.length);
titles.splice(0, titles.length);
}
};
return _this;
});
template
template<b:if cond='data:blog.pageType == "item"'>
<style type='text/css'>
... 上記のstyle
</style>
<script type='text/javascript'>
//<![CDATA[
... 上記のjs
//]]>
</script>
<div id='related-posts'>
<script type='text/javascript'>RelatedPosts.init("<data:post.url/>", "関連記事", 5);</script>
<b:loop values='data:post.labels' var='label'>
<script type='text/javascript'>RelatedPosts.counter();</script>
</b:loop>
<b:loop values='data:post.labels' var='label'>
<script async='async' expr:src='"/feeds/posts/summary/-/" + data:label.name + "?alt=json-in-script&callback=RelatedPosts.add&max-results=10"' type='text/javascript'/>
</b:loop>
</div>
</b:if>
※</article>
の直前などに配置する。
※RelatedPosts.init
の引数でURL、タイトル、関連記事数を指定する。