関連記事一覧をランダム表示にする

以前ブログ記事の下部に「新着記事一覧」「関連記事一覧」を実装しました。

しかし最近はカテゴリー「その他」の記事を追加することが多く、そうすると新着記事と関連記事の一覧が全く同じになってしまいます。
(関連記事は「カテゴリー内の新着記事」を抜き出していた為)

「関連記事一覧はカテゴリー内の記事からランダムで5つ表示させることはできないかな?」と思い調べてみました。

ChatGPTの力を借りて実装することができたので、設定内容を書いていこうと思います。

ChatGPTに聞いてみる

https://miscnote.com/blog/list-of-articles
で記事の一覧を作っています。各記事はliに入っています。
他のページからこのページを読み込み、ランダムに記事を5つ表示させる方法を教えてください

と聞いてみたところ、それっぽいコードを教えてくれたので、更に、

liにdata-categoryという要素があります。この要素の値に限定してランダムに選ぶことはできますか?

このカテゴリに、その前にphpで設定した$categoryという値を使うことはできますか?

と聞いてみると、最終的にこのようなコードを教えてくれました。

// PHPで設定した$categoryの値をJavaScriptの変数に代入
  var selectedCategory = '<?php echo $category; ?>';
  // 外部のページからデータを取得する関数(Fetch APIを使用)
  async function fetchArticles(url) {
    try {
      const response = await fetch(url);
      const data = await response.text();
      return data;
    } catch (error) {
      console.error("データを取得できませんでした。", error);
      return null;
    }
  }

  // 記事一覧を表示する関数
  function displayRandomArticles(articleList, numArticles, category) {
    const articles = Array.from(articleList); // 記事一覧を配列に変換
    const selectedArticles = [];

    // ランダムに記事を選択
    while (selectedArticles.length < numArticles && articles.length > 0) {
      const randomIndex = Math.floor(Math.random() * articles.length);
      const article = articles[randomIndex];
      const articleCategory = article.getAttribute("data-category");

      // カテゴリが一致する場合に記事を選択
      if (articleCategory === category) {
        selectedArticles.push(article);
      }

      // 選択された記事を配列から削除
      articles.splice(randomIndex, 1);
    }

    // 選択した記事を表示
    const articleContainer = document.getElementById("article-container"); // 表示する要素のIDを設定
    selectedArticles.forEach((article) => {
      articleContainer.appendChild(article.cloneNode(true));
    });
  }

  // 外部ページのURL
  const externalPageURL = "https://miscnote.com/blog/list-of-articles";

  // 外部ページから記事一覧を取得し、指定したカテゴリに基づいてランダムに表示する
  fetchArticles(externalPageURL).then((data) => {
    if (data) {
      const parser = new DOMParser();
      const doc = parser.parseFromString(data, "text/html");
      const articleList = doc.querySelectorAll("li"); // 記事一覧を取得するセレクタを設定
      const numRandomArticles = 5; // ランダムに表示する記事の数を設定

      // カテゴリに基づいて記事一覧を表示する関数を呼び出す
      displayRandomArticles(articleList, numRandomArticles, selectedCategory);
    }
  });

※回答内容を整理・まとめて記載しています。

テストページを作成し設置してみたらほぼそのままで動いたので、早速本運用のページに反映させてみました。

…なぜか動かない…テストページなら動くのに…

スクリプトの中にPHPのコードが入っている

ChatGPTから教えてもらったスクリプトをコピペして使っているだけだったので、もう一度よく考えて見てみると…

最初のコード、

// PHPで設定した$categoryの値をJavaScriptの変数に代入
  var selectedCategory = '<?php echo $category; ?>';

<?php echo $category; ?> はJavaScriptではなくPHPのコードだと気付きました。

テストページはPHPで作成しHTML内に直接スクリプトを記載する形だったので動いていたようです。

そして本運用のページではスクリプトをjsファイルに入れて動かそうとしていたので、PHPのコードの部分がうまく機能していなかったんですね。

つまり最初のこのコードだけPHPファイル内のscriptタグに記載し、残りはjsファイルに記載すればOKでした!

最後に

しっかりと知識をつけずコピペでコードを使用していると、こういうところに気付くのに時間がかかってしまいますね…😅

それにしてもChatGPTはすごい!欲しいコードをスラスラと書いてくれます!

これを検索して探し当てようと思っても、なかなかうまくいかないと思います。それらしいコードを見つけても、自分のサイト用に修正するには知識が要りますからね。

今回は最初に自分のサイトアドレスとタグを指定していたので、そのまま使えるコードを作ってくれました。助かる!

そして私はこれから、「このスクリプトがどういう原理で動いているのか」を解析して勉強しようと思います。本来は順序が逆なのでしょうが、欲しいスクリプトが先に手に入っているので、気持ち的にかなり楽ですね。勉強もしやすいです。

関連記事
新着記事
ブログ内検索