WordPress REST API 使ってヘッドレス化してみた

Pocket

WordPress REST API 使って、Webページをヘッドレス化します。
デモはこちら

条件および方針

0. ヘッドレスCMSとか概要

1. サブドメインhttps://〇〇.webya.site/にWordPressをインストルール

2. サブドメインhttps://files.hogehogemoheji.com/images/にWordPressのメディアファイルをアップロードする

3. https://webya.site/demo/wp-rest-api/にWebページ(htmlとかの静的サイトまたは、静的サイトジェネレーターを使用)を作成

0. ヘッドレスCMSとか概要

WordPressがオワコンと言われる一方、静的サイトジェネレーター(SSG)が広まりこれを利用したWebページが開発されるようになりました。
また拡張性の高さからAPIファーストな設計が流行している雰囲気があります。
WordPressがオワコンといわれるのは表示スピードが遅い、PHPを利用したコードにより開発に特定の言語を利用しなければならないと言ったことがあげられるのなかと思います。
またCMSとコンテンツ表示部分が切り離されていないため、サイトを丸ごと書き換えられる恐れがあるなども考えられます。
じゃー、CMSとコンテンツ表示部分を切り分ければ良いよねって考え方からヘッドレスCMSが登場しました。
ヘッドレスCMSはコンテンツ管理部分とコンテンツ表示部分を完全に切り離しています。
どういうこと?ってなる方もいると思いますが、ヘッドレスCMS部分(コンテンツ管理部分)のみを提供するサービスが登場してきています(マイクロCMS)。これらのサービスを利用してコンテンツを管理し、サービスから提供されるAPI等のデータをコンテンツ表示部分に組み込む仕組みとなっています。
このサービスが出てきたときに思ったのが、WordPressのREST APIでできるんじゃね、だったので作成してみます。

1. サブドメインhttps://〇〇.webya.site/にWordPressをインストルール

WordPressをコンテンツを管理する用のサブドメインにインストールします。
また、インストールしたディレクトリにはベーシック認証をかけます。
これにより、外部サイトからAPIを使用されるのを防ぐことができます

2. サブドメインhttps://files.webya.site/images/にWordPressのメディアファイルをアップロードする

2.1 メディアファイルのアップロード先URLを変更

次に、WordPress内のメディアファイルのアップロード先URLを変更します。
アップロード先URLを変更する前に、一度メディアファイルをアップロードしてデフォルトのディレクトリ構成をみます。

wp-content
|
|______uploads
       |______2021
       |      |______02
       |      |______05
       |
       |______2022
              |______04
              |______05
                     |______△△.jpgとか

uploadsより下層のディレクトリを、サブドメインhttps://files.webya.site/imagesにフォルダごと移動させます。
移動後のディレクトリ構成は以下の感じです。
※これを先にやっておくと、アップロードエラーが出ないのでのちのち楽です。

https://files.webya.site/images
|______2021
|      |______02
|      |______05
|
|______2022
       |______04
       |______05
              |______△△.jpgとか

次はWordPress側でメディアファイルのアップロードURLと読み込みURLを変更します

https://〇〇.webya.site/wp-admin/options.phpにアクセスし、【upload_path】と【upload_url_path】を変更します。
・upload_pathは相対パス(../files.webya.site/images)
・upload_url_pathは絶対パスを設定(https://files.webya.site/images)

2.2 APIのリクエストURLを変更

APIのリクエストURLを変更します(初期値https://〇〇.webya.site/wp-json/△△~)。
使用するテーマに子テーマを作成し、子テーマのfunctions.phpに以下の内容を書き足します。

〇funcitons.php

//api出力url変更
function func_rest_url_prefix( $slug ) {
	flush_rewrite_rules();
	return 'api';
}

add_filter( 'rest_url_prefix', 'func_rest_url_prefix');

これによりAPIのリクエストURLをhttps://〇〇.webya.site/api/△△~に変更できます。

3. https://webya.site/demo/wp-rest-api/にWebページ(htmlとかの静的サイトまたは、静的サイトビルダーを使用)を作成

トップページ(index.html)とブログ詳細ページ(blog.html)とブログ一覧ページ(bloglist.html)を作成します。各htmlでJavascript(jQuery)を読み込み、非同期でPHPを呼び出して、PHPからWordPressのREST APIにアクセスしてjson取得、取得したjsonを再度Javascript(jQuery)で整形してWebページに表示させます。

PHPでjsonを取得することでAPIを取得するURLを隠すことができます。
取得URL見えないのでWordPressを使っていることを隠すのにもちょうどよいです。

〇ディレクトリ構成

original
|______index.html
|______blog.html
|______bloglist.html
|
|______css
|
|
|______js
|      |______jquery-2.0.0.min.js
|      |______common.js
|
~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~
|______api-index.php
|______api-blog.php
|______api-bloglist.php
|______api-common.php

cssは省略しています。

〇index.html

<!DOCTYPE html>
  <html>
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <title>タイトル</title>
      <meta name="description" content="">
      <link rel="stylesheet" href="css/index.css">
      <link rel="stylesheet" href="css/bloglist.css">
      <link rel="stylesheet" href="css/side.css">
      <link rel="stylesheet" href="css/sanitize.css">
      <link rel="stylesheet" href="css/common.css">
      <link rel="preconnect" href="https://fonts.googleapis.com">
      <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
      <link href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;500;700&amp;display=swap" rel="stylesheet"><meta name="robots" content="noindex">
    </head>
    <body>
      <header>
        <div class="head">
        <div class="headRow">
        <h1 class="headIcon"><a href="./.">タイトル</a></h1>
        <div class="headMenu">
        <nav class="headNav">
        <ul class="headNavList">
        <li class="headNavItem"><a class="headNavLink" href="./.">トップページ</a></li>
        <li class="headNavItem"><a class="headNavLink" href="bloglist.html?id=1">ブログ</a></li>
        </ul>
        </nav>
        </div>
        </div>
        <div class="headBtnWrap">
        <div class="headBtn"><span></span><span></span><span></span></div>
        </div>
        </div>
      </header>
      <main>
        <div class="centerBox">
        <div class="mainRow">
        <div class="sideMenu">
        <div class="sideMenuInner">
        <div class="sideBox">
        <p class="textSearchTitle">検索</p>
        <form method="get" action="bloglist.html?id=1">
        <input type="hidden" name="id" value="1">
        <input class="serch" type="text" name="search" placeholder="あいまい検索">
        </form>
        </div>
        <div class="sideBox">
        <p class="catTitle">カテゴリー</p>
        <ul class="catList">
        <li class="catItem"><a class="catLink" href="bloglist.html?id=1">すべて</a></li>
        <li class="catItem"><a class="catLink" href="bloglist.html?id=1&amp;categories=4">カテゴリー01</a></li>
        <li class="catItem"><a class="catLink" href="bloglist.html?id=1&amp;categories=6">カテゴリー02</a></li>
        </ul>
        </div>
        <div class="sideBox">
        <p class="tagTitle">タグ</p>
        <ul class="tagList">
        <li class="tagItem"><a class="tagLink" href="bloglist.html?id=1&amp;tags=5">タグ01</a></li>
        <li class="tagItem"><a class="tagLink" href="bloglist.html?id=1&amp;tags=7">タグ02</a></li>
        <li class="tagItem"><a class="tagLink" href="bloglist.html?id=1&amp;tags=8">タグ03</a></li>
        </ul>
        </div>
        </div>
        </div>
        <div class="main">
        <div class="blog">
        <ul class="blogList" id="blogList"></ul>
        </div>
        <div class="pageNation">
        <div class="pageNationRow">
        <p class="pageNationTitle">記事一覧</p>
        <div class="pageCount">
        <p class="pageCountText" id="pageCountText"></p>
        </div>
        </div>
        <ul class="pageList" id="pageList"></ul>
        </div>
        </div>
        </div>
        </div>
      </main>
      <footer>
        <div class="footerWrap">
        <div class="centerBox"></div>
        </div><small>Copyright - タイトル, 2022 All Rights Reserved.</small>
      </footer>
      <script src="js/jquery-2.0.0.min.js"></script>
      <script src="js/common.js"></script>
      <script src="js/index.js"></script>
      <script src="js/page.js"></script>
    </body>
  </html>

・index.jsでブログ記事の一覧を取得します。
・page.jsではブログ記事の総数とページネーションを作成します。

〇index.js

$.ajax({
    type: 'POST', // HTTPリクエストメソッドの指定
    url: 'ahahahahahahahahaha/api.php', // 送信先URLの指定
    async: true, // 非同期通信フラグの指定
    dataType: 'json', // 受信するデータタイプの指定
    data: {

    }
})
.done(function(results) {

  $.each(results, function (i, item) {
    var date_data = new Date(item.date);
    var year = date_data.getFullYear();
    var month = date_data.getMonth() + 1;
    var day = date_data.getDate();
    var title = item.title;
    var link = item.link;
    var id = item.id;
    var thum = item.thum_info;
    var date = year + '年' + month + '月' + day + '日';

    $('#blogList').append("<li class='blogItem'><a class='blogLink' href='blog.html?id=" + id + "'><div class='blogRow'><div class='blogThum'><img class='objImg' src='" + (thum ? thum : "https://webya.site/demo/wp-rest-api/images/thum-no.png") + "'></div><div class='blogInfo'><div class='blogInfoTop'><p class='blogday'>" + date + "</p><p class='blogTitle'>" + title + "</p></div><div class='blogInfoTopBottom'><p class='blogMore'>READ MORE</p></div></div></div></a></li>");
    });

})
.fail(function(XMLHttpRequest, textStatus, errorThrown) {
  // 通信が失敗したときの処理
    console.log("errrrrrr");
  console.log("XMLHttpRequest : " + XMLHttpRequest.status);
  console.log("textStatus     : " + textStatus);
  console.log("errorThrown    : " + errorThrown.message);
});

・ajaxを使用して、API取得用のPHPファイルにリクエストをします。
PHPから返ってきたデータは記事の数だけjson形式でresultsに格納されているので、eachを使用して記事の数だけ処理を繰り返します。
取得したjsonはappendを使用してhtml上に追加します。
その際にサムネイルがある場合はサムネイルを表記し、サムネイルがない場合は、別データを表示するようにしています。

〇api.php

<?php
  header("Content-Type: application/json; charset=UTF-8"); //ヘッダー情報の明記。必須。
  
  $request = "https://〇〇.webya.site/api/wp/v2/posts?context=embed&per_page=5";

  $basic = array(
    'User-Agent: My User Agent 1.0',    //ユーザエージェントの指定
    'Authorization: Basic '.base64_encode('hoge:hogehoge1234'),//ベーシック認証([ID]:[PASSWORD])
  );
   
  $options = array(
      'http' => array(
      'header' => implode("\r\n", $basic )
    )
  );

  $json = file_get_contents($request, false, stream_context_create($options));

  echo $json;

・index.jsのajaxにからのリクエスト受けて、api.phpが動きます。
$requestはWordPressからお知らせを5件取得するURLです。通常はfile_get_contentsにURLを入れればjsonをすぐに取得できますが、WordPressのインストールされたディレクトリにはベーシック認証がかかっているので、WordPressからjsonを取得するときはURL情報とベーシック認証の情報を一緒にfile_get_contentsする必要があります。
※WordPress側で認証設定をするためにプラグインの導入が必要との記事がありますが、プラグインを使用しなくても認証機能が使えました。

〇page.js

$(function() {
  var url = new URL(window.location.href);
  var params = url.searchParams;
  var x = Number(params.get('id'));//現在のページ番号
  var y = params.get('search');//キーワード検索時の情報
  var z = params.get('categories');//カテゴリ検索時の情報
  var a = params.get('tags');//タグ検索時の情報


  $.ajax({
      type: 'POST', // HTTPリクエストメソッドの指定
      url: 'ahahahahahahahahaha/api-page.php', // 送信先URLの指定
      async: true, // 非同期通信フラグの指定
      dataType: 'json', // 受信するデータタイプの指定
      data: {
        "id" : x,
        "search" : y,
        "categories" : z,
        "tags" : a,
       },
  })

  .done(function(page) {
    //

    var sum = Number(page) + 1;
    for(let i = 1; i < sum; i++){
      $('#pageList').append("<li class='pageItem'><a class='pageLink' href='bloglist.html?id=" + i + (y ? ("&search=" + y) :"") + (z ? ("&categories=" + z) :"") + (a ? ("&tags=" + a) :"") + "'>" + i + "</a></li>");
    }
    
    if(1 < x){
      $('#pageCountText').append(x + "/" + page +"ページ");    
    }else {
      $('#pageCountText').append(1 + "/" + page +"ページ"); 
    }

  })
  .fail(function(XMLHttpRequest, textStatus, errorThrown) {
    // 通信が失敗したときの処理
      $('#pageCountText').append("無効なリクエストです");
  });                 
});

・page.jsでページネーション部分を実装します。URLからgetパラメータを取得します。
getパラメータをajaxを使用してPHPに渡します。
PHPからの応答はpageに格納(総ページ数)されているので、あとは受け取った値と定義した検索用のgetパラメータを組み合わせてページネーション部分を作成します。

〇api-page.php

<?php
  header("Content-Type: application/json; charset=UTF-8"); //ヘッダー情報の明記。必須。

  $id = $_POST['id'];//$_POST['id']
  $id = htmlspecialchars($id, ENT_QUOTES, 'UTF-8');
  $search = $_POST['search'];//$_POST['search']
  $search = htmlspecialchars($search, ENT_QUOTES, 'UTF-8');
  $categories = $_POST['categories'];//
  $categories = htmlspecialchars($categories, ENT_QUOTES, 'UTF-8');
  $tags = $_POST['tags'];//
  $tags = htmlspecialchars($tags, ENT_QUOTES, 'UTF-8');

  //キーワード検索のとき
  if(!($search == null)) {
    $request = "https://〇〇.webya.site/api/wp/v2/posts?context=embed&per_page=5&page=" . $id ."&search=" . $search;
  }
  //カテゴリー検索のとき
  else if(!($categories == null)){
    $request = "https://〇〇.webya.site/api/wp/v2/posts?context=embed&per_page=5&page=" . $id . "&categories=" . $categories;
  }
  //タグ検索のとき
  else if(!($tags == null)) {
    $request = "https://〇〇.webya.site/api/wp/v2/posts?context=embed&per_page=5&page=" . $id ."&tags=" . $tags;
  }
  //検索条件がないとき
  else {
    $request = "https://〇〇.webya.site/api/wp/v2/posts?context=embed&per_page=5&page=1";
  }

  $basic = array(
    'User-Agent: My User Agent 1.0',    //ユーザエージェントの指定
    'Authorization: Basic '.base64_encode('hoge:hogehoge1234'),//ベーシック認証([ID]:[PASSWORD])
  );
   
  $options = array(
      'http' => array(
      'header' => implode("\r\n", $basic )
    )
  );

  $headers = get_headers($request,1,stream_context_create($options));

  echo json_encode($headers["X-WP-TotalPages"]);

・page.jsからajaxから送られてきたデータをPOSTで受け取ります。
受け取ったデータはエスケープ処理してタグを無効化します。
条件によってWordPressに送るURLが変わります。URLが確定したらベーシック認証の情報と一緒にWordPressに情報送ります。
検索条件に合わせて、WordPressのページ数が応答で返ってくるのでそれをecho json_encode($headers[“X-WP-TotalPages”])でpage.js側に送ります。

〇blog.html

<!DOCTYPE html>
  <html>
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <title>記事詳細 - タイトル</title>
      <meta name="description" content="">
      <link rel="stylesheet" href="css/blog.css">
      <link rel="stylesheet" href="css/bloglist.css">
      <link rel="stylesheet" href="css/side.css">
      <link rel="stylesheet" href="css/sanitize.css">
      <link rel="stylesheet" href="css/common.css">
      <link rel="preconnect" href="https://fonts.googleapis.com">
      <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
      <link href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;500;700&amp;display=swap" rel="stylesheet"><meta name="robots" content="noindex">
    </head>
    <body>
      <header>
        <div class="head">
        <div class="headRow">
        <h1 class="headIcon"><a href="./.">タイトル</a></h1>
        <div class="headMenu">
        <nav class="headNav">
        <ul class="headNavList">
        <li class="headNavItem"><a class="headNavLink" href="./.">トップページ</a></li>
        <li class="headNavItem"><a class="headNavLink" href="bloglist.html?id=1">ブログ</a></li>
        </ul>
        </nav>
        </div>
        </div>
        <div class="headBtnWrap">
        <div class="headBtn"><span></span><span></span><span></span></div>
        </div>
        </div>
      </header>
      <main>
        <div class="centerBox">
        <div class="mainRow">
        <div class="sideMenu">
        <div class="sideMenuInner">
        <div class="sideBox">
        <p class="textSearchTitle">検索</p>
        <form method="get" action="bloglist.html?id=1">
        <input type="hidden" name="id" value="1">
        <input class="serch" type="text" name="search" placeholder="あいまい検索">
        </form>
        </div>
        <div class="sideBox">
        <p class="catTitle">カテゴリー</p>
        <ul class="catList">
        <li class="catItem"><a class="catLink" href="bloglist.html?id=1">すべて</a></li>
        <li class="catItem"><a class="catLink" href="bloglist.html?id=1&amp;categories=4">カテゴリー01</a></li>
        <li class="catItem"><a class="catLink" href="bloglist.html?id=1&amp;categories=6">カテゴリー02</a></li>
        </ul>
        </div>
        <div class="sideBox">
        <p class="tagTitle">タグ</p>
        <ul class="tagList">
        <li class="tagItem"><a class="tagLink" href="bloglist.html?id=1&amp;tags=5">タグ01</a></li>
        <li class="tagItem"><a class="tagLink" href="bloglist.html?id=1&amp;tags=7">タグ02</a></li>
        <li class="tagItem"><a class="tagLink" href="bloglist.html?id=1&amp;tags=8">タグ03</a></li>
        </ul>
        </div>
        </div>
        </div>
        <div class="main">
        <div class="content">
        <p class="articleday" id="articleday"></p>
        <p class="articleTitle" id="articleTitle"></p>
        <div class="articleHead" id="articleHead"></div>
        <div class="article" id="article"> </div>
        </div>
        <div class="pageNation">
        <div class="pageNationRow">
        <p class="pageNationTitle">記事一覧</p>
        <div class="pageCount">
        <p class="pageCountText" id="pageCountText"></p>
        </div>
        </div>
        <ul class="pageList" id="pageList"></ul>
        </div>
        </div>
        </div>
        </div>
      </main>
      <footer>
        <div class="footerWrap">
        <div class="centerBox"></div>
        </div><small>Copyright - タイトル, 2022 All Rights Reserved.</small>
      </footer>
      <script src="js/jquery-2.0.0.min.js"></script>
      <script src="js/common.js"></script>
      <script src="js/blog.js"></script>
    </body>
  </html>

・blog.jsでブログの詳細を取得します。

〇blog.js

var url = new URL(window.location.href);
var params = url.searchParams;
var x = params.get('id');

$.ajax({
    type: 'POST', // HTTPリクエストメソッドの指定
    url: 'ahahahahahahahahaha/api-get.php', // 送信先URLの指定
    async: true, // 非同期通信フラグの指定
    dataType: 'json', // 受信するデータタイプの指定
    data: { "id" : x },
})
.done(function(results) {
  //タイトル、本文
  var title = results[0].title;
  var content = results[0].content;
  $('#articleTitle').append(title);
  $('#article').append(content);

  //日付
  var date_data = new Date(results[0].date);
  var year = date_data.getFullYear();
  var month = date_data.getMonth() + 1;
  var day = date_data.getDate();
  var date = year + '年' + month + '月' + day + '日';
  $('#articleday').append(date);

  //サムネイル
  var thum = results[0].thum_info
  $('#articleHead').css("background", "url('" + (thum ? thum : "https://webya.site/demo/wp-rest-api/images/thum-no.png") +"')");
  $('#articleHead').append("<img src='"+ (thum ? thum : "https://webya.site/demo/wp-rest-api/images/thum-no.png") +"'>");

  //ページネーション
  $('#pageCountText').append("1/" + results[1] +"ページ");
  var sum = Number(results[1]) + 1;
  for(let i = 1; i < sum; i++){
    $('#pageList').append("<li class='pageItem'><a class='pageLink' href='bloglist.html?id=" + i + "'</a>" + i + "</li>");
  }

  //ディスクリプションなど
  document.title = results[0]._aioseo_title;
  document.querySelector('meta[name="description"]').setAttribute("content", results[0]._aioseo_description);

})
.fail(function(XMLHttpRequest, textStatus, errorThrown) {
  // 通信が失敗したときの処理
    console.log("errrrrrr");
    console.log("XMLHttpRequest : " + XMLHttpRequest.status);
    console.log("textStatus     : " + textStatus);
    console.log("errorThrown    : " + errorThrown.message);
});

・URLのgetパラメータから記事idを取得します。
取得したidをajaxでPHPに送ります。
PHPから返ってきた応答にはブログ記事の詳細と総ページ数が格納されています。取得したデータをもとに、記事のタイトル、本文、ディスクリプション等やページネーション部分を作ります。

〇api-get.php

<?php
  header("Content-Type: application/json; charset=UTF-8"); //ヘッダー情報の明記。必須。


  $id = $_POST['id'];//
  $id = htmlspecialchars($id, ENT_QUOTES, 'UTF-8');


  $request = "https://〇〇.webya.site/api/wp/v2/posts/" . $id ."?context=view";
  
  $basic = array(
    'User-Agent: My User Agent 1.0',    //ユーザエージェントの指定
    'Authorization: Basic '.base64_encode('hoge:hogehoge1234'),//ベーシック認証([ID]:[PASSWORD])
  );
   
  $options = array(
      'http' => array(
      'header' => implode("\r\n", $basic )
    )
  );

  $json = file_get_contents($request, false, stream_context_create($options));

  //記事データを取得できた場合、記事データに総ページ数の情報を追加する
  if($json){
    $json = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
    $php_array = json_decode($json,true);


    $headers = get_headers("https://〇〇.webya.site/api/wp/v2/posts?context=embed&per_page=5",1,stream_context_create($options));
    $total = $headers["X-WP-TotalPages"];//テキスト追加

    $data_arr = array($php_array, $total);//apiに要素追加


    echo json_encode($data_arr);
  }else {
    //エラー処理
    if(count($http_response_header) > 0){
        //「$http_response_header[0]」にはステータスコードがセットされている
        $status_code = explode(' ', $http_response_header[0]);  //「$status_code[1]」にステータスコードの数字だけが入る
 
        //エラーの判別
        switch($status_code[1]){
            //404エラーの場合
            case 404:
                echo "指定したページが見つかりませんでした";
                break;
            //500エラーの場合
            case 500:
                echo "指定したページがあるサーバーにエラーがあります";
                break;
            //その他のエラーの場合
            default:
                echo "何らかのエラーによって指定したページのデータを取得できませんでした";
        }
    }else{
        //タイムアウトの場合 or 存在しないドメインだった場合
        echo "タイムエラー or URLが間違っています";
    }
  }

・blog.jsから渡されたidの情報をPOSTで取得。
idの情報をWordPressに送り、記事データを取得する。
ついでに総ページ数のデータを取得して、記事データと合わせる。
合わせたデータをblog.js側に送る。

〇bloglist.html

<!DOCTYPE html>
  <html>
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <title>記事一覧 - タイトル</title>
      <meta name="description" content="">
      <link rel="stylesheet" href="css/bloglist.css">
      <link rel="stylesheet" href="css/side.css">
      <link rel="stylesheet" href="css/sanitize.css">
      <link rel="stylesheet" href="css/common.css">
      <link rel="preconnect" href="https://fonts.googleapis.com">
      <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
      <link href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;500;700&amp;display=swap" rel="stylesheet"><meta name="robots" content="noindex">
    </head>
    <body>
      <header>
        <div class="head">
        <div class="headRow">
        <h1 class="headIcon"><a href="./.">タイトル</a></h1>
        <div class="headMenu">
        <nav class="headNav">
        <ul class="headNavList">
        <li class="headNavItem"><a class="headNavLink" href="./.">トップページ</a></li>
        <li class="headNavItem"><a class="headNavLink" href="bloglist.html?id=1">ブログ</a></li>
        </ul>
        </nav>
        </div>
        </div>
        <div class="headBtnWrap">
        <div class="headBtn"><span></span><span></span><span></span></div>
        </div>
        </div>
      </header>
      <main>
        <div class="centerBox">
        <div class="mainRow">
        <div class="sideMenu">
        <div class="sideMenuInner">
        <div class="sideBox">
        <p class="textSearchTitle">検索</p>
        <form method="get" action="bloglist.html?id=1">
        <input type="hidden" name="id" value="1">
        <input class="serch" type="text" name="search" placeholder="あいまい検索">
        </form>
        </div>
        <div class="sideBox">
        <p class="catTitle">カテゴリー</p>
        <ul class="catList">
        <li class="catItem"><a class="catLink" href="bloglist.html?id=1">すべて</a></li>
        <li class="catItem"><a class="catLink" href="bloglist.html?id=1&amp;categories=4">カテゴリー01</a></li>
        <li class="catItem"><a class="catLink" href="bloglist.html?id=1&amp;categories=6">カテゴリー02</a></li>
        </ul>
        </div>
        <div class="sideBox">
        <p class="tagTitle">タグ</p>
        <ul class="tagList">
        <li class="tagItem"><a class="tagLink" href="bloglist.html?id=1&amp;tags=5">タグ01</a></li>
        <li class="tagItem"><a class="tagLink" href="bloglist.html?id=1&amp;tags=7">タグ02</a></li>
        <li class="tagItem"><a class="tagLink" href="bloglist.html?id=1&amp;tags=8">タグ03</a></li>
        </ul>
        </div>
        </div>
        </div>
        <div class="main">
        <div class="blog">
        <ul class="blogList" id="blogList"></ul>
        </div>
        <div class="pageNation">
        <div class="pageNationRow">
        <p class="pageNationTitle">記事一覧</p>
        <div class="pageCount">
        <p class="pageCountText" id="pageCountText"></p>
        </div>
        </div>
        <ul class="pageList" id="pageList"></ul>
        </div>
        </div>
        </div>
        </div>
      </main>
      <footer>
        <div class="footerWrap">
        <div class="centerBox"></div>
        </div><small>Copyright - タイトル, 2022 All Rights Reserved.</small>
      </footer>
      <script src="js/jquery-2.0.0.min.js"></script>
      <script src="js/common.js"></script>
      <script src="js/bloglist.js"></script>
      <script src="js/page.js"></script>
    </body>
  </html>

・blog.jsで検索結果の一覧を取得する。
・page.jsはindex.htmlの時と同様にページネーションを取得している。

〇bloglist.js

$(function() {
  var url = new URL(window.location.href);
  var params = url.searchParams;
  var x = Number(params.get('id'));//現在のページ番号
  var y = params.get('search');//キーワード検索時の情報
  var z = params.get('categories');//カテゴリ検索時の情報
  var a = params.get('tags');//タグ検索時の情報

  $.ajax({
      type: 'POST', // HTTPリクエストメソッドの指定
      url: 'ahahahahahahahahaha/api-getlist.php', // 送信先URLの指定
      async: true, // 非同期通信フラグの指定
      dataType: 'json', // 受信するデータタイプの指定
      data: {
        "id" : x,
        "search" : y,
        "categories" : z,
        "tags" : a,
       },
  })
  .done(function(results) {
    //

    $.each(results, function (i, item) {
      var date_data = new Date(item.date);
      var year = date_data.getFullYear();
      var month = date_data.getMonth() + 1;
      var day = date_data.getDate();
      var title = item.title;
      var link = item.link;
      var id = item.id;
      var thum = item.thum_info;
      var date = year + '年' + month + '月' + day + '日';
      $('#blogList').append("<li class='blogItem'><a class='blogLink' href='blog.html?id=" + id + "'><div class='blogRow'><div class='blogThum'><img class='objImg' src='" + (thum ? thum : "https://webya.site/demo/wp-rest-api/images/thum-no.png") + "'></div><div class='blogInfo'><div class='blogInfoTop'><p class='blogday'>" + date + "</p><p class='blogTitle'>" + title + "</p></div><div class='blogInfoTopBottom'><p class='blogMore'>READ MORE</p></div></div></div></a></li>");
    });

    //検索結果に応じて、cssを追加
    if(x && !y && !z && !a){
      $('.catItem:nth-of-type(1)').children('.catLink').addClass('catLinkActive');
    }
    //検索結果に応じて、cssを追加
    if(z == 4) {
      $('.catItem:nth-of-type(2)').children('.catLink').addClass('catLinkActive');
    }else if(z == 6){
      $('.catItem:nth-of-type(3)').children('.catLink').addClass('catLinkActive'); 
    }
    //検索結果に応じて、cssを追加
    if(a == 5){
      $('.tagItem:nth-of-type(1)').children('.tagLink').addClass('tagLinkActive');
    }else if(a ==7){
      $('.tagItem:nth-of-type(2)').children('.tagLink').addClass('tagLinkActive');
    }else if(a ==8){
      $('.tagItem:nth-of-type(3)').children('.tagLink').addClass('tagLinkActive');
    }


  })
  .fail(function(XMLHttpRequest, textStatus, errorThrown) {
  // 通信が失敗したときの処理
    console.log("errrrrrr");
    console.log("XMLHttpRequest : " + XMLHttpRequest.status);
    console.log("textStatus     : " + textStatus);
    console.log("errorThrown    : " + errorThrown.message);
  });


});

・URLのゲットパラメータを取得し、ajaxを使用してPHPに情報を送る。
その後返ってきたデータを元にブログ一覧を描画し、必要に応じてcssを追加している。

〇api-getlist.php

<?php
  header("Content-Type: application/json; charset=UTF-8"); //ヘッダー情報の明記。必須。

  $id = $_POST['id'];//$_POST['id']
  $id = htmlspecialchars($id, ENT_QUOTES, 'UTF-8');
  $search = $_POST['search'];//$_POST['search']
  $search = htmlspecialchars($search, ENT_QUOTES, 'UTF-8');
  $categories = $_POST['categories'];//
  $categories = htmlspecialchars($categories, ENT_QUOTES, 'UTF-8');
  $tags = $_POST['tags'];//
  $tags = htmlspecialchars($tags, ENT_QUOTES, 'UTF-8');

  //テキストが入っていれば
  if(!($search == null)) {
    $request = "https://〇〇.webya.site/api/wp/v2/posts?context=embed&per_page=5&page=" . $id ."&search=" . $search;
  }
  //カテゴリーが入っていれば
  else if(!($categories == null)){
    $request = "https://〇〇.webya.site/api/wp/v2/posts?context=embed&per_page=5&page=" . $id . "&categories=" . $categories;
  }
  //タグが入っていれば
  else if(!($tags == null)) {
    $request = "https://〇〇.webya.site/api/wp/v2/posts?context=embed&per_page=5&page=" . $id ."&tags=" . $tags;
  }
  //idが入って、かつカテゴリ、サーチ、タグが空なら
  else if(!($id == null) && !$search && !$categories && !$tags) {
    $request = "https://〇〇.webya.site/api/wp/v2/posts?context=embed&per_page=5&page=" . $id;
  }
  else {
    $request = "";
  }

  $basic = array(
    'User-Agent: My User Agent 1.0',    //ユーザエージェントの指定
    'Authorization: Basic '.base64_encode('hoge:hogehoge1234'),//ベーシック認証([ID]:[PASSWORD])
  );
   
  $options = array(
      'http' => array(
      'header' => implode("\r\n", $basic )
    )
  );

  $json = file_get_contents($request, false, stream_context_create($options));

  echo $json;

以上です。
そのうち静的サイトジェネレーター使っても実装したいと思います。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする