【2021年版】 WordPressプラグイン無しでタグの一覧を表示する画期的な方法 〜JavaScript+REST APIを使う

2021年5月16日Webデザイン

こんにちは!

最近ブログをサボり気味のしずかなかずしです。

サボり気味の理由は、週末のプログラミングプロジェクトが忙しいから、です。

ということで、本日はプログラミングネタでブログを更新してみます。関連するテーマはズバリ、WordPressです。WordPressのプラグイン無しで、JavaScriptを駆使して「タグ」や「カテゴリ」一覧の表示する画期的(!)な方法をご紹介します。

プラグインを使わない方法

WordPressはプラグインを追加してさまざまな拡張ができるのが利点ですが、導入には以下のような論点があります。

  • プラグインを導入することでサイトのスピードが遅くなる可能性がある
  • テーマや他のプラグインとのコンフリクトが発生する可能性がある

特にサイトのスピードはもっとも気になるところで、SEO的にもなるべくプラグインを使わないでできることを増やしていくというモチベーションが生まれます。

今回のように、タグやカテゴリ一覧をサイトに表示させたい場合、プラグインを使わないで実現するのは、一般的にはサーバーサイドのPHPのコードで行うことになります。ネットで「プラグインなし」のテクニックに関して検索しても、出てくるのは大抵PHPを駆使したやり方です。

PHPで実装する場合の課題は、WordPress本体の仕組みを知っている必要があることです。

そこで今回は、PHPを使わずにWordPress 5系のエディタであるGutenberg の"カスタムHTMLブロック"を駆使してやっていきます

カスタムHTMLでコンテンツを表示

まず最初に、カスタムHTMLでコンテンツを表示させる基本的な書き方を見てみましょう。

“カスタムHTML"ブロックに直接HTMLを記載だけだと、WordPressのデータを使って動的にページの要素を記載することができません。JavaScriptを使って動的に記載するようにHTMLは<div>タグのみを記載します。

ポイントは、<div>タグの中でID指定をすることです。 <div id=’put_content_here’>のように、id属性を使用します。このとき注意が必要なのは、put_content_hereは自分で自由に名前をつけることができるものの、同じページの他の要素につけられているID(例えば、WordPress自身やテーマ、その他のプラグイン等によってつけられたID)と同じ名前にならないように注意することです。

そして、JavaScriptのdocument.getElementById()関数を使って、その要素にアクセスして描画内容を変更する、という感じになります。実際のコードは以下のようになります。

<div id='put_contents_here'></div>
<script>
(function(){
  let elm = document.getElementById('put_contents_here')
  elm.innerHTML = `<div style='color:red'>この"hello, world!"は、JavaScriptで表示しています</div>`
})()
</script>

実際の表示は以下のようになります。



簡単に動作を説明しますと、<script>タグで囲われたコードでは、<div>タグでしていたIDの要素をgetElementById()で取り出しています。そして、戻り値のElementのinnerHTMLプロパティに設定した、HTMLが実際に表示れるHTMLという流れです。

(function() {})()で囲っているのは、カスタムHTMLを複数使った場合に定義する変数が二重定義にならないようにするためです。これがないと、’elm’という変数が同じページの別のJavaScriptで参照可能になり、予期せぬエラーや不具合につながる可能性があります。

JavaScriptでWordPressのREST APIを呼び出す

上記の例では、JavaScriptを使っているとは言え、まだ静的なHTMLを表示しているのに近い処理でした。

ここからは、もう少し本格的に動的コンテンツを扱います。その為に、WordPressのREST APIを使用します。

WordPressのREST APIとは、WordPressに実装されている機能で、プログラムからWordPressの記事の情報を取得するためのものです。WordPressをセットアップすると搭載されており、そのサーバーの/wp-json/wp/v2/ というパスの下にエンドポイント(REST APIのアクセスURL)が設定されます。

例えば、シンプルに、/wp-json/wp/v2/pagesを呼び出すと、最新の10記事のJSONが送られてきます。ブラウザでもアクセス可能ですので、試しに、このブログしずかなかずしの/wp-json/wp/v2/pagesにアクセスしてみて下さい。

するとどうでどうでしょう?

以下のような解読不能なデータが表示されるではありませんか。これはJSON形式のデータになっているのでJavaScriptのプログラムから簡単に使えます。

JavaScriptのプログラムから呼び出す時は、最近のモダンブラウザならfetch()というAPIが搭載されており、これが使えます。fetch()関数のブラウザサポートを見てもらうとわかりますが、Internet Explorer(IE)などの古いブラウザではサポートされていません。もし、IEなど昔ながらのブラウザの対応が必要な場合は、XMLHttpRequestといった古いブラウザが使えるAPIを使うか、JQueryなどブラウザの違いを吸収してくれるライブラリを使うことになります。

こうみえて私は「モダンな人」なので、この記事ではモダンなfetch()を使っていきます。

fetch()を使う場合、JSONが返ってくるようなエンドポイントからデータを取り出すのは非常に簡単で、以下のような感じになります。

fetch(url).then(response => response.json()).then(function(json) { 必要な処理 })

上記で、「必要な処理」という部分で先程の人間が読みにくいデータにアクセスできます。例えば、エンドポイントが

{ name: 'foo’, age: ’19’}

のようなデータが返ってきたとします。その場合は、fetch()で取得した結果に対して、json.nameや、json.ageのように記述することで実際のデータが取り出せます。

WordPress REST APIから返ってくるデータは、JSONの上位の階層が配列 [] になっていて、以下のようになっています。

[

{id: 〇〇, date: △△,…},

{id: ◎◎, date: □□, …},

]

この場合、配列の要素にアクセスするには、forEach()が便利です。具体的には、forEach()を使って以下のように配列の各要素ごとの処理を行います。

json.forEach(item => {item.idにアクセス})

タグ一覧を表示するカスタムHTMLコード

それでは、実際にタグ一覧を取得してみます。

タグ一覧を取得するWordPress REST APIのエンドポイントは/wp-json/wp/v2/tagsです。ただし、デフォルトではタグが10個しか取れません。また、返ってくるデータには不要なフィールドが沢山含まれます。必要なものだけに絞ったほうがパフォーマンスに有利です。

ですので、以下のようにパラメータつきで、呼び出します。

/wp-json/wp/v2/tags?per_page=30&_fields=id,link,_links,name

per_pageというパラメータは、一度に何個のタグを返すか、という指定です。 上記の場合は30個(存在する場合)返ってきます。また、_fieldsに指定するキーワードは、返ってくるタグ情報の中身を制限する(フィルターする)ものです。

実際のソースコードを見てみましょう。WordPress Gutenbergエディタの「カスタムHTML」の中にコピペできる実際のソースコードは以下になります。

<div id='add_by_js'></div>
<script>
(function() {
  let per_page = 6
  let element_name = 'add_by_js'
  
  // url for REST API
  let url = `/wp-json/wp/v2/tags?per_page=${per_page}&_fields=id,link,_links,name`

  // calling REST API
  fetch(url).then(response => response.json()).then(function(json) {
    let html = ''
    json.forEach(item => {
      html +=
      /*html*/
      `
        <div class='wp-block-button is-style-outline'>
          <a class='wp-block-button__link' href='${item.link}'>${item.name}</a>
        </div>
      `
    })
    let elm = document.getElementById(element_name)
    let newDiv = document.createElement('div');
    newDiv.innerHTML = html
    elm.appendChild(newDiv)
  })
})()
</script>

簡単にソースコードの中身を解説すると、まず、<div>エレメントの名前は、’add_by_js’としています。JavaScriptのコードのelement_name変数にはこれを入力しておきます(4行目)。

11行目でfetch()を呼んで、WordPressのREST APIを叩いています。

返ってきたjsonは配列なので、13行目で各要素に分解。要素毎にHTMLのaタグでリンクできるようにしています(16行目以降)。ここで、実際のデータ、item.nameやitem.linkにアクセス。この部分のHTMLの記載(例えば、class属性、など)を変更すれば、タグ一覧の見た目を変えられます。

forEachループを抜けた後に、id=’add_by_js’のdiv要素の下に、1つ追加でdivタグを作成し、その中にループで作ったHTMLをセットしています(24行目)。

ちなみに、アクセスしているurl変数のtagsの部分をcategoriesに変更すると、同じコードでカテゴリ一覧も表示できます。

let url = '/wp-json/wp/v2/categories?per_page=${per_page}&_fields=id,link,_links,name'

応用編: タグが付いた記事一覧を表示

WordPress REST APIのURLを色々変えてみると、いろんな一覧表示ができます。

例えば、特定のタグが付いた記事一覧を取得するURLは以下のようになります。

/wp-json/wp/v2/posts?tags=2263&per_page=5&_fields=id,title,link

この例では、tags=のパラメータとして、WordPressのtagのIdを指定します。タグのidの調べ方はネットで検索すれば色々出てきます。(参考:WordPressの投稿・カテゴリー・タグのIDを管理画面から調べる方法

<div id='add_by_js_2'></div>
<script>
(function() {
  let per_page = 6
  let tag_id = 2263
  let element_name = 'add_by_js_2'

  // url for REST API
  let url = `/wp-json/wp/v2/posts?tags=${tag_id}&per_page=${per_page}&_fields=id,title,link`

  // calling REST API
  fetch(url).then(response => response.json()).then(function(json) {
    let html = ''
    json.forEach(item => {
      html +=
      /*html*/
      `
        <p>
          <a href='${item.link}'>${item.title.rendered}</a>
        </p>
      `
    })
    let elm = document.getElementById(element_name)
    let newDiv = document.createElement('div');
    newDiv.innerHTML = html
    elm.appendChild(newDiv)
  })
})()
</script>

実際の表示

以下は実際にこのページでJavaScript+カスタムHTMLで表示した実例です。


カテゴリ一覧(6個のみ)


「4K」というタグが付いた記事一覧(6個)

以上。何かのお役に立てば!