【Blogger】フィードですべての投稿タイトルを取得してHTMLで出力してみました

更新  
公開
当サイトはアフィリエイト広告を使用しています

Blogger



プロトタイプですが、すべての投稿タイトルを取得してHTMLで出力するプログラムを書いてみました。

フィード1回あたり取得できるデータの数は150でした。そこで、フィードを繰り返してすべての投稿を取得しました。

リンク付きの投稿・記事タイトルをリストで表示するだけのシンプルなものです。

<div class="">投稿数</div>
<ul class="">
    <li class=""><a href="">タイトル</a></li>
    <li class=""><a href="">タイトル</a></li>
</ul>

将来的に取得、出力するデータを増やすなどしてサイトマップ的なものができそうです。

ページに貼り付けることを想定しています。

目次

プログラムと設置方法

プログラムはHTML JavaScript CSSをまとめたものになります。

クリックすると開きます
<div id="allPosts" class="all-posts">
  <div id="allPostsLoader" class="all-posts__loader"></div>
</div>
<script>/*! Copyright:2023 sutajp | Released under the MIT license | https://sutasutashiki.blogspot.com/p/mit-license.html */
  //<![CDATA[
  /** フィードですべての投稿を取得, HTMLで出力する */
  "use strict";
  /**
   * HTMLを生成して出力する関数
   * @param {Array<object>} objects - [{title:string, url:string}]
   * @param {number} totalResults
   */
  function createHtml(objects, totalResults) {
    /** フラグメントを設定 */
    const fragment = document.createDocumentFragment();
    /** div要素 */
    const divElm = document.createElement("div");
    divElm.className = "all-posts__total-posts-number";
    divElm.textContent = "投稿数" + totalResults;
    /** ul要素 */
    const ulElm = document.createElement("ul");
    ulElm.className = "all-posts__post-list";
    for (const outputObject of objects) {
      /** li要素 */
      const liElm = document.createElement("li");
      liElm.className = "all-posts__post-list-item";
      /** a要素 */
      const anchorElm = document.createElement("a");
      anchorElm.className = "all-posts__post-list-item-anchor";
      anchorElm.href = outputObject.url;
      anchorElm.textContent = outputObject.title;
  
      liElm.append(anchorElm);
      ulElm.append(liElm);
      fragment.append(divElm, ulElm);
    }
    /** HTMLを出力 */
    const allPosts = document.getElementById("allPosts");
    allPosts.append(fragment);
    /** HTMLを出力後, ローダーにdisplay:noneを設定*/
    const allPostsLoader = document.getElementById("allPostsLoader");
    allPostsLoader.style.display = "none";
  }
  
  /**
   * JSONデータを取得してオブジェクトを生成する関数
   */
  async function createObjects() {
    /**
     * 取得したデータを格納
     * @type {Array<object>} - [{title:string, url:string}]
     */
    let objects = [];
    /**
     * 投稿数
     * @type {Number} - json.feed.openSearch$totalResults.$t
     */
    let totalResults;
    /**
     * 投稿数の取得の可否条件
     * @type {Boolean}
     */
    let flag = true;
  
    let startIndex = 0;
    const maxResults = 150;
  
    do {
      const feedUrl =
        "/feeds/posts/summary?alt=json&start-index=" +
        (startIndex * maxResults + 1) +
        "&max-results=" +
        maxResults;
      const response = await fetch(feedUrl);
      const json = await response.json();
  
      for (const jsonFeedEntry of json.feed.entry) {
        for (const jsonFeedEntryLink of jsonFeedEntry.link) {
          if (jsonFeedEntryLink.rel == "alternate") {
            const feedObject = {};
            feedObject.title = jsonFeedEntry.title.$t;
            feedObject.url = jsonFeedEntryLink.href;
            objects.push(feedObject);
          }
        }
      }
      /** startIndexを数え上げる */
      startIndex++;
      /** doの外にある変数にwhileの条件式につかう投稿数を格納 */
      if (flag == true) {
        totalResults = json.feed.openSearch$totalResults.$t;
        /** 2回目以降は投稿数を取得しない */
        flag = false;
      }
    } while (objects.length < totalResults);
    /** createHtml関数を実行 */
    createHtml(objects, totalResults);
  }
  createObjects();
  //]]>
  </script>
<style>
.all-posts {
  min-height: 500px;
}
/* https://projects.lukehaas.me/css-loaders/ */
.all-posts__loader {
  color: #808080;
  font-size: 16px;
  margin: auto;
  width: 1em;
  height: 1em;
  top: 100px;
  left: 0;
  right: 0;
  border-radius: 50%;
  position: relative;
  -webkit-animation: load4 1.3s infinite linear;
  animation: load4 1.3s infinite linear;
  -webkit-transform: translateZ(0);
  -ms-transform: translateZ(0);
  transform: translateZ(0);
}
@-webkit-keyframes load4 {
  0%,
  100% {
    box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em,
      0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
  }
  12.5% {
    box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em,
      0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
  }
  25% {
    box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0,
      0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
  }
  37.5% {
    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em,
      0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
  }
  50% {
    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em,
      0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
  }
  62.5% {
    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
      0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
  }
  75% {
    box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em,
      0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
  }
  87.5% {
    box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
      0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
  }
}
@keyframes load4 {
  0%,
  100% {
    box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em,
      0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
  }
  12.5% {
    box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em,
      0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
  }
  25% {
    box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0,
      0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
  }
  37.5% {
    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em,
      0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
  }
  50% {
    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em,
      0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
  }
  62.5% {
    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
      0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
  }
  75% {
    box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em,
      0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
  }
  87.5% {
    box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
      0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
  }
}
</style>

ページにプログラムを貼り付けます

ページにプログラムを貼り付けたら、公開しなくてもプレビュー表示で雰囲気を確認できます。

ローディング画面

コンピューターの性能や通信環境、データの量などの関係で、画面が表示されるまでに時間を要する場合があります。

そこで画面が表示されるまで、ローディング画面を表示しています。

必要なければ下記をコメントアウトか削除してください。

<div id="allPostsLoader" class="all-posts__loader"></div>
/** HTMLを出力後, ローダーにdisplay:noneを設定*/
const allPostsLoader = document.getElementById("allPostsLoader");
allPostsLoader.style.display = "none";
CSSはすべて削除
<style>
...
</style>

メモ

当初feed.linknextにあるURLの使用を検討しましたが、nextにあるURLを使うと「下書き」も取得してしまうことが分かりました。

do while文をはじめて使いました。繰り返し処理はfor forEach for ofしか使ったことなかったので、フィードの繰り返し処理で使えることに気が付くまで時間がかかりました。

JavaScript | do...while文を使った繰り返し処理

参考サイト

Single Element CSS Spinners

Flux - Protocole des données Blogger - Blogger Code PE



検索

お知らせ

カテゴリー

Random Picks

すたすた式

Enjoy!👍

QooQ