javaScriptでBloggerにページネーションを実装する
Bloggerにページネーション機能をつけたい。ページネーションとは記事下部にあって、次の記事、前の記事へのリンクを紹介するというブログパーツ。Bloggerのデフォルトのページネーション機能には、以下の画像のように、次の記事・前の記事のリンクのみで記事のタイトルを表示することはできない。
ページネーションで記事タイトルを取得するようにしたい。当記事では、ざっくりログさまの情報120%全面参考にさせていただいています。ざっくりログさま本当にありがとうございます。Display Post Titles in Blogger Page Navigation
公式ヘルプを見ると、Bloggerの文法には、
よし!と思ってテーマのHTMLに記載するとこの通り
次の記事、前の記事として表示してくれない。なんだよもう。olderPageTitle = 前の記事、newerPageTitle = 次の記事 ということ。
※1 Bloggerは、URLに注目すると現在表示している記事の種類を掴める
URLの末尾が.html: 個別記事、pageTypeはItem
URLに label を含む: ラベル一覧ページ pageTypeはIndex
URLに search を含む: 検索結果表示ページ pageTypeはIndex
URLに 2で始まる4桁の数字を含む(ex: 2020): アーカイブページ pageTypeはarchive
※2
getPageTitle(olderLink, setOlderPageTitle)の、
「setOlderPageTitleにjsonを渡してね!だから、jsonを受けてほしい関数を渡すからさ!」
という感じ
※3
つまり、
https://www.themetrial.blogspot.com + /feeds/posts/summary?alt=json-in-script&max-results=1&redirect=false&path=/2020/05/blogger.html
<b:> Bloggerのネイティブ文法では、記事タイトルを取得できない
olderPageUrl: 過去の投稿がある場合、その投稿の URL。ページの種類に応じて表示されます(このリンクはすべてのページにあるとは限りません)。
olderPageTitle: 過去の投稿ページへのリンクのタイトル。
newerPageUrl: 新しい投稿がある場合、その投稿の URL。
newerPageTitle: 新しい投稿ページへのリンクのタイトル。
参考元URL:レイアウト用のデータタグ - Blogger ヘルプ
公式ヘルプを見ると、Bloggerの文法には、
- olderPageTitle
- newerPageTitle
よし!と思ってテーマのHTMLに記載するとこの通り
ちょっとまぎらわしい。記事URLは取得できているので、タイトルを取得するJSコードを書く必要があります。
アクセスカウントされないページネーションコード
ざっくりログさまが上記リンク先の記事で問題があると言っているようにJSでタイトルを取得すると、Bloggerのアクセスカウンターに計上され、次・前のタイトルを取得する度に1PVとしてカウントされてしまいます。
アクセス数を水増ししたいならJSのコードでもいいけどね、そんな不正確なPVデータなんて意味ないしね。アクセスにカウントされないようにするために、ざっくりログさまが書いているようなBloggerAPIを利用したjsonファイルを利用するのがとっても良い方法だと思われます。ざっくりログさま本当にありがとうございます。
アクセス数を水増ししたいならJSのコードでもいいけどね、そんな不正確なPVデータなんて意味ないしね。アクセスにカウントされないようにするために、ざっくりログさまが書いているようなBloggerAPIを利用したjsonファイルを利用するのがとっても良い方法だと思われます。ざっくりログさま本当にありがとうございます。
<script type='text/javascript'>
//<![CDATA[
// except root, labels, search and mobile pages
if (/.+\.html(\?m=0)?$/.test(location.href)) {
var olderLink = document.getElementById('Blog1_blog-pager-older-link');
if (olderLink) {
getPageTitle(olderLink, setOlderPageTitle);
function setOlderPageTitle(data){
setPageTitle(data, olderLink, '', ' »')
};
}
var newerLink = document.getElementById('Blog1_blog-pager-newer-link');
if (newerLink) {
getPageTitle(newerLink, setNewerPageTitle);
function setNewerPageTitle(data){
setPageTitle(data, newerLink, '« ', '')
};
}
// set the page title from feed data
function setPageTitle(data, pageLink, prefix, suffix) {
if (data.feed.entry) {
if (data.feed.entry.length > 0) {
var title = data.feed.entry[0].title.$t;
}
}
if (title) {
pageLink.innerHTML = prefix + title + suffix;
}
}
// get entry data from the feed
function getPageTitle(pageLink, callback) {
var pathname = pageLink.getAttribute('href').replace(location.protocol + '//' + location.hostname, '');
var script = document.createElement('script');
script.src = '/feeds/posts/summary?alt=json-in-script&max-results=1&redirect=false&path='+pathname+'&callback='+callback.name+'';
document.body.appendChild(script);
}
}
//]]>
</script>
コード(自分なり)解説
人様のコードをまるまる転載しておいて解説もクソもないんだけど、自分なりに注釈を入れてみた。<script type='text/javascript'>
if (/.+\.html(\?m=0)?$/.test(location.href)) {
// ※1location.hrefの末尾にhtmlかhtml?m=0か調べる。末尾がhtmlかチェックする。
var olderLink = document.getElementById('Blog1_blog-pager-older-link');
if (olderLink) { // olderLinkが存在するなら。ショートハンド記法
getPageTitle(olderLink, setOlderPageTitle);
//※2関数getPageTitleへ第一引数olderLink, 第2引数へ定義した関数setOlderPageTitleを渡す。
function (data){
// getPageTitle() で、feed.jsonを渡される。dataへ格納。
setPageTitle(data, olderLink, '', ' »') // ^#187; = »
};
}
var newerLink = document.getElementById('Blog1_blog-pager-newer-link');
if (newerLink) {
// newerLinkが存在するなら
getPageTitle(newerLink, setNewerPageTitle);
//関数getPageTitleへ、第一引数newerLink, 第2引数へ定義した関数setNewerPageTitleを渡す。
function setNewerPageTitle(data){
// getPageTitle() で、feed.jsonを渡される。dataへ格納。
setPageTitle(data, newerLink, '« ', '')
};
}
// set the page title from feed data // dataはjsonファイル。$tは添字の名前。
function setPageTitle(data, pageLink, prefix, suffix) {
if (data.feed.entry) {
if (data.feed.entry.length > 0) {
var title = data.feed.entry[0].title.$t;
// jsonファイルの項目、feedの添字entry配列[0]のtitle.$tを取得して、変数titleへ格納
}
}
if (title) {
// 変数titleが存在するなら、
pageLink.innerHTML = prefix + title + suffix;
// suffixは "»" 。 pageLink.innerHTML = ''記事タイトル » となる。
}
}
// get entry data from the feed
function getPageTitle(pageLink, callback) {
var pathname = pageLink.getAttribute('href').replace(location.protocol + '//' + location.hostname, '');
// location.protocol = https: location.hostname = あなたのブログ.blogspot.com
var script = document.createElement('script');
script.src = '/feeds/posts/summary?alt=json-in-script&max-results=1&redirect=false&path='+pathname+'&callback='+callback.name+'';
// ※3 記事pathnameで、その記事のjsonファイルを取得することができる。最後の&callback=あとの関数にjsonデータが渡されることになる。
document.body.appendChild(script);
}
}
//]]>
</script>
※1 Bloggerは、URLに注目すると現在表示している記事の種類を掴める
URLの末尾が.html: 個別記事、pageTypeはItem
URLに label を含む: ラベル一覧ページ pageTypeはIndex
URLに search を含む: 検索結果表示ページ pageTypeはIndex
URLに 2で始まる4桁の数字を含む(ex: 2020): アーカイブページ pageTypeはarchive
※2
getPageTitle(olderLink, setOlderPageTitle)の、
- 第一引数:olderLinkはdomオブジェクト(#Blog1_blog-pager-older-link)
- 第二引数: 関数setOlderPageTitle
「setOlderPageTitleにjsonを渡してね!だから、jsonを受けてほしい関数を渡すからさ!」
という感じ
※3
- script.src = '/feeds/posts/summary?alt=json-in-script&max-results=1&redirect=false&path='+pathname+'&callback='+callback.name+'';
Blogger Data APIが提供するJSON出力形式を使用して、Bloggerベータでホストされているブログからの最近の投稿のリストを表示する方法を示しています。これにより、ブログのパブリックフィードをクエリして、結果のエントリをJSONオブジェクトとして返すことができます。新しいJSONフィードを使用するには、src値が次のスクリプト要素を作成しますこの引用先の情報ってBloggerAPIのものではなくて、GoogleデータAPIのものなんだよね。なんで、BloggerAPIのセクションにない情報なのだろうか(こんらん)。
https://blogname.blogspot.com/feeds/posts/default?alt=json-in-script&callback=myFunc
どこblognameあなたが取得したいブログで、 myFuncJSONオブジェクトが渡されるコールバック関数の名前です。<Google翻訳>
参考URL: Simple example of retrieving JSON feeds from Blogger Data API
- '/feeds/posts/summary?alt=json-in-script&max-results=1&redirect=false&path='+pathname+'&callback='+callback.name+'';
- https://www.themetrial.blogspot.com/feeds/posts/summary?alt=json-in-script&max-results=1&redirect=false&path=/2020/05/blogger.html =
つまり、
https://www.themetrial.blogspot.com + /feeds/posts/summary?alt=json-in-script&max-results=1&redirect=false&path=/2020/05/blogger.html
https://www.themetrial.blogspot.com/feeds/posts/summary?alt=json-in-script&max-results=1&redirect=false&path=/2020/05/blogger.html&callback=callback.name (=関数setOlderPageTitle) ,
受け取っているJsonの内容はどうなっているの?
末尾の&callback=callback.nameを消去して、BloggerのURLの部分(以下太字)を調節以下のように調節し、URLを打ち込むとJsonファイルを受け取ることができる。
https://blogname.blogspot.com/feeds/posts/default?alt=json-in-script&max-results=1&redirect=false&path=特定記事のパス.html
私の場合、一つ前の記事の場合だと以下のようにするとjsonデータをブラウザに表示することができる
https://www.themetrial.blogspot.com/feeds/posts/summary?alt=json-in-script&max-results=1&redirect=false&path=/2020/05/blogger.html
当該部分はこんな感じのデータになる。
"feed": {"entry": ["title": {"type": "text","$t": "Blogger文法<b:loop>でラベルを呼び出す処理はこれを読めばわかる"},]}
jsonデータを受け取り、当該箇所の値を取得して、関数に渡せているのがわかりました。