にほんブログ村 小説ブログへ
小説ランキング
PVアクセスランキング にほんブログ村

カウント付きのいいねボタンに変更

2025/09/18

Bloggerのカスタマイズ

こことは別にブログを作った。
それで思ったわけだ。現状の押すだけの「いいねボタン」から、横にカウント数の表示される物にしようかと。今までにそれに関する他人様の記事は読んでいたが、面倒がって設置していなかったのだ。
この際だから、やってみよう!

というわけで、むーなかさんのページを参考にしてみる。

まずは書かれれていた通りに設置してみたが、ボタン機能は動くがSVGのアイコンが表示されない。試行錯誤したが、Blogger側ボタンアイコンの定義を以下の通りにSVGのタグで囲めばよかった。
<!--ボタンアイコンの定義-->
<svg style='display:none' xmlns='http://www.w3.org/2000/svg'>
  <defs>
<symbol id='like' viewBox='0 0 122.88 106.16'>
   (  途中省略  )
L4.43,63.63z' fill='DarkSlateBlue'/></symbol>
</defs></svg>
あとはGoogleスプレッドシートとGASを使う。しかし説明通りに指定するとPCのURLとモバイル(主にスマホ)のURLが違うため、別々にカウント集計される。
モバイルではURL末尾に ?m=1 のパラメーターが付くのだ。別々のカウントという事は、つまり同じ記事でも、PC表示とモバイル表示ではカウント数が違ってしまう。
これはいかん。このカウント数を共通にしたい!

PCとモバイル、カウント数を共通にする


しばらくBlogger側とGASをあれこれしてみたが、挫折。いっそ生データ(ログ)を加工すればいいでない? と思い、以下となる。スプレッドシートは、新たなプロジェクトとして作成した。

Googleスプレッドシート。新しい空白のスプレッドシートを作る。最初はシート1しかないので、シート3まで作成する。
シート1 は、そのまま。
シート2 のA1、B1には適当に列ヘッダの名前を入れる。なんでもいい。
 A2に、以下を入力。入力するとB2には count とテキストが入る。
 すべてのURLからパラメーターを抜いて、降順で並べる。
=QUERY(ARRAYFORMULA(IF(LEN('シート1'!B:B),SUBSTITUTE('シート1'!B:B,"?m=1",""),)),"select Col1, count(Col1) where Col1 is not null group by Col1 order by count(Col1) desc",0)
シート2の入力

シート3 のA1、B1もシート1と同様に列名を入れる。
 A2に以下を入力。すべてのURLにパラメーターを付けて、降順で並べる。
=QUERY(ARRAYFORMULA(IF(LEN('シート1'!B:B),SUBSTITUTE('シート1'!B:B,"?m=1","") & "?m=1",)),"select Col1, count(Col1) where Col1 is not null group by Col1 order by count(Col1) desc",0)

シート3の入力

それが済んだら、拡張機能>Apps Script を選択(Google Apps Script=GAS)。Apps Scriptが新しいタブで開かれる。
最初の function〜 のコードは削除して、以下を貼る。
GAS
/*いいね送信用POST*/
function doPost(e) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
  sheet.insertRowBefore(1);
  sheet.getRange(1,1).setValue((new Date).toLocaleString('ja-JP'));
  sheet.getRange(1,2).setValue(e.parameter.titleURL);
}
 
/*いいね数検索用GET*/
function doGet(e) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const titleURL = e.parameter.titleURL;

  // シート2(PC集計)とシート3(モバイル集計)
  const pcSheet = ss.getSheets()[1];
  const mobileSheet = ss.getSheets()[2];

  let likeCount = getLikeCountFromSheet(pcSheet, titleURL);

  if (likeCount === null) {
    likeCount = getLikeCountFromSheet(mobileSheet, titleURL);
  }

  if (likeCount === null) {
    likeCount = 0;
  }

  const obj = { titleURL, likeCount };
  return ContentService
           .createTextOutput(JSON.stringify(obj))
           .setMimeType(ContentService.MimeType.JSON);
}

// 補助関数:指定シートからカウントを探す
function getLikeCountFromSheet(sheet, titleURL) {
  const lastRow = sheet.getLastRow();
  if (lastRow < 2) return null;

  const titleArray = sheet.getRange(2,1,lastRow-1,1).getValues().flat();
  const likeArray  = sheet.getRange(2,2,lastRow-1,1).getValues().flat();

  const idx = titleArray.indexOf(titleURL);
  return (idx >= 0) ? likeArray[idx] : null;
}

シート1がログになり、記事ページが読み込まれた時(表示された時)に、URLをシート2から検索、無ければシート3を検索、それでも無い場合に0を返す形。
シート1と2のあたいは同じだから、PCとモバイル、いいね数のカウンタは共通となる。

初めてのデプロイの時


ドライブにプロジェクトを保存、デプロイ>新しいデプロイ
新しいデプロイで種類の選択>ウェブアプリ
設定で実行ユーザーは自分、アクセスできるユーザーは全員。
初めてのデプロイの時は、アクセスを承認、自分のGoogleアカウントが表示されるから選択する。その後は、画像通り。
デプロイ初めての時1
Advanced を押す
デプロイ初めての時2
Go to *********のプロジェクト(unsafe) を押す
デプロイ初めての時3
Allowを押す
デプロイされたウェブアプリのURLをコピー。これをBloggerのHTML編集内のコードで使うから、どこかにペーストしとけばいい。まあ忘れてもデプロイの管理で表示できるけど。

PNG画像でボタンを作る


しかしながら、PC(私はMacだ)での表示確認はできても、モバイルでの確認はAndroid端末しかない。日本で、スマートフォン端末比率ほぼ半分のiPhoneが確認できない。
私のiPod touch( iOS 9.3.5)では古すぎてSVGは表示されず、ボタンは反応もしない。
なんか、くやしい。ので、今まで使っていたPNG画像でボタンを作る事にした。画像はフリーアイコンかどっかで入手してる。
Bloggerの テーマ>HTMLを編集 で開かれたHTML画面。もちろんバックアップはとってくれ。責任は持てんぞ。
CSS  <head>内に追記してもいいし、</head>以下に<style>タグ付けて貼ってもいい。
/* ここから、いいねボタン*/
   .like-mark-buttons {
          width: 450px;
          margin: 4em auto;
          display: flex;
          justify-content: center;
          max-width: 100%;
        }
        .like-mark-buttons div {
          text-align: center;
          font-size: 2.4rem;
          display: block;
          padding-top: 12px;
          line-height: 1;
          border-radius: 5px;
          height: 55px;
          width: 55px;
          color: #fff;
        }

    #likeBtn {
     display: block;
	 background-color: #a9a9a9;
     border: none;
     border-radius: 8px;
     padding: 10px 12px;
     font-size: medium;
     color:ffffff;
     transition: background-color 0.3s ease;
     align-items: center;
	 cursor: pointer;
       }
    #likeBtn:hover {transform: scale(1.1);}

	/* ボタン内の画像 */
    button#likeBtn img {
    height: 26px; /* 画像のサイズ調整 */
    vertical-align: middle;
    margin-right: 10px;
  }
   /* カウンタのスタイル */
        #like-span {
        user-select: none;
        display: flex;
        align-items: center;
        margin-left: 1em;
		color: #000;
        }

        @media (max-width: 600px ) {
          .like-mark-buttons {
            width: 100%;
          }
          .like-mark-buttons div {
            padding-top: 12px;
          }
        }

吹き出し型のツールチップも付ける


ついでに吹き出し型のツールチップも付けた。このページを参考に。
 HTMLとCSSだけで作るツールチップ
/* ツールチップ設定 */
.tooltip {
  position: relative;}/* ツールチップの位置の基準に */
 /* ツールチップのテキスト */
.tooltip-text {
   opacity: 0; /* はじめは隠しておく */
   visibility: hidden; /* はじめは隠しておく */
   position: absolute; /* 絶対配置 */
   left: 20%; /* 親に対して中央配置 */
   transform: translateX(-50%); /* 親に対して中央配置 */
   top: -50px; /* 親要素上からの位置 */
   display: inline-block;
   padding: 5px; /* 余白 */
   white-space: nowrap; /* テキストを折り返さない */
   font-size: 1.2rem; /* フォントサイズ */
   line-height: 1.3; /* 行間 */
   background: #333; /* 背景色 */
   color: #fff; /* 文字色 */
   border-radius: 3px; /* 角丸 */
   transition: 0.3s ease-in; /* アニメーション */
  }

 /* ホバー時にツールチップの非表示を解除 */
.tooltip:hover .tooltip-text {
    opacity: 1;
    visibility: visible;
}
/*ツールチップを吹き出しに*/
.tooltip-text:before {
	content: '';
	position: absolute;
	bottom: -7px; /* 位置を調整 */
	left: 50%;
	margin-left: -7px;
	width: 14px;
	height: 14px;
	background-color: #333;
	/* box-shadowで三角形に見せる */
	transform: rotate(45deg);
	box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2); /* 影をつけて立体感を出す */
}

で、ボタン表示部は、アドセンス広告1より下部とした。これね。
<!-- アドセンス広告1.end -->
            </div>
            <div class='post-body' id='single-content'>         
              <data:post.body/>
              <div style='clear: both;'/> <!-- clear for photos floats -->
            </div>

HTMLとjavascript
<!--いいねボタン表示部-->
 <div class='like-mark-buttons'>
  <form action='GASウェブアプリのURL' method='POST' name='likePostData' style='display:none' target='hidden_iframe'>
	<input expr:value='data:post.title + &quot; | &quot; + data:post.url' id='titleURL' name='titleURL' readonly='readonly' type='text'/>
       <iframe name='hidden_iframe'/>
   </form>

<button id='likeBtn'>
  <span class='tooltip'>
<img alt='いいねアイコン' src='画像のURL'/>
 <span style='color:#ffffff;'>いいね&#65281;</span>
   <span class='tooltip-text'>この記事に いいねする</span>
  </span></button>
 <span id='like-span'/>

<!--JavaScriptエリア-->
<script>/*<![CDATA[*/
let likeSpan, likeBtn, likeInput, titleURL, n;
 
    likeSpan = document.getElementById("like-span");
    likeBtn = document.getElementById("likeBtn");
    likeBtn.addEventListener("click", likeSubmit);
    likeInput = document.getElementById("titleURL");
    titleURL = likeInput.value;
    const param = {titleURL};
    const query = new URLSearchParams(param);
fetch(`GASウェブアプリのURL?${query}`)
  .then(response => response.json())
  .then(likeJson => {
count = likeJson.likeCount;
likeSpan.innerHTML = count;
});
 
function likeSubmit(){
    n = likeSpan.innerHTML;
    n++;
    likeSpan.innerHTML = n;
    likeBtn.disabled = true;

  likeBtn.style.backgroundColor = '#c85554'; // 背景色を変更
  likeSpan.style.color = '#c85554'; //カウンタ色を変更

  // ツールチップのテキスト変更
  const tooltipTextElement = likeBtn.querySelector('.tooltip-text');
  if (tooltipTextElement) {
    tooltipTextElement.textContent = 'いいね済みだよ♡';
  }
  
// 送信後メッセージ表示
setTimeout(function() {
        alert('うれしい! ありがとう!\nI\'m so happy !');
        document.likePostData.submit();
    }, 1000); // 1000ミリ秒後に実行
}
/*]]>*/</script></div>

コピーしておいたGASのウェブアプリのURLを入れるのは、HTMLとjavascriptにそれぞれ1ヶ所ずつ。
クリック(タップ)のあとにボタンの地色とカウンタが赤に変わり、その後アラートで謝意を示す形にした。

結果は、以下の通り。
シート1ログ

シート2結果

シート3結果

画像使ったボタンは私のiPod touchでも表示できる。やったね! と思ったけど、やはり機能はしてくれないのであった(笑)
あー、目が、目が疲れた。
なおコード表示に行番号とコピーボタンも付けてみた。これについては次回。
小説の匣

駄文同盟.com

カテゴリ

ブログ アーカイブ

My Accounts

Twitter     pixiv

protected by DMCA

SSL標準装備の無料メールフォーム作成・管理ツール|フォームメーラー

QooQ