ウェブ開発者であれば、Node.jsやWordPressはお馴染みの存在でしょう。Node.jsはブラウザ外でJavaScriptを実行する強力な実行環境、そしてWordPressは人気のコンテンツ管理システム(CMS)です。

JavaScriptベースのNode.jsPHPで稼働するCMSのWordPressは、一見相容れない関係に思えますが、実はWordPress REST APIを使って連動させることができます。このAPIは、Node.jsアプリケーションがHTTPリクエストを通じてWordPressとやりとるすることを可能にし、ユーザー、コメント、固定ページ、投稿のようなサイト要素を含むさまざまなデータにアクセスを提供します。

とは言え、そもそもNode.jsとWordPressを組み合わせることに利点があるのか、疑問を抱く方も少なくないでしょう。

例えば、WordPressサイトを運営していて、独自のダッシュボードを構築し、最近の投稿、コメント数、ユーザーの行動など、サイトのリアルタイムデータを取得したいとします。

そんなとき、Node.jsが重要な役割を果たしてくれます。今回は、Node.jsエンドポイントの設定について取り上げます。このエンドポイントは、投稿の更新、コメントのモデレート、サイトのカスタマイズ、WordPress サイトの管理など、さまざまなタスクの実行にWordPress REST APIを使用します。

前提条件

これからご紹介する手順は、以下の条件を前提とします。

Node.jsでWordPressの投稿を管理する

WordPressの基本的な操作として、投稿の作成、更新、削除があります。まずはじめに、これらの操作用に特定のエンドポイントを作成する方法と、各操作に対して/postsエンドポイントにリクエストを送信する方法を見ていきます。

WordPressの投稿を新規作成する

REST APIを使用してWordPressで新規投稿を作成するには、/postsエンドポイントにPOSTリクエストを送信します。リクエストの本文(リクエストボディ)は、WordPressの投稿内容をJSON形式で提供する必要があります。

まずは、「App.js」という名前のNode.jsサーバーファイルを開き、Expressが正しく設定されていることを確認します。これは、Expressを初期化するconst app = express()で確認可能です。

続いて、新規投稿を追加するルートをサーバーファイルに実装します。このルートのコードは以下のとおりです。

app.post("/add-post", async (req, res) => {
   try {
    const postID = req.body.id
    const resp = await axios.post(`https://yourdomain.com/wp-json/wp/v2/posts/${postID}`, req.body)
	
    if(resp.status !== 200) throw "エラーが発生しました"
       
  } catch (err) {        
    console.log(err)        
  }
})

このコードにより、アプリケーションに/add-postエンドポイントが作成されます。このエンドポイントにリクエストが送信されると、リクエストボディから投稿IDを抽出し、WordPressサイトにPOSTリクエストを送信します。なお、https://yourdomain.comは、実際のWordPressのドメイン名に置き換えることをお忘れなく。

Visual Studio CodeのThunder Clientのようなツールを使ってテストすることができます。エラーが発生しないよう、リクエストボディがJSON形式であることを確認してください。

add-postエンドポイントへのPOSTリクエストボディ(JSON形式)
add-postエンドポイントへのPOSTリクエストボディ(JSON形式)

これにより、アプリケーションからWordPressサイトへの投稿を自動化、および効率化することができます。

WordPressの既存の投稿を更新する

WordPress APIで投稿を更新するには、WordPress API の/postsエンドポイントにPUTリクエストを送信します。この場合も、WordPressの投稿の更新内容は、JSON形式で提供する必要があります。

WordPressで既存の投稿を更新するルートは以下のとおり。

app.put("/update-post", async (req, res) => {
  try {
    const postID = req.body.id                    
      
    const resp = await axios.put(`https://yourdomain.com/wp-json/wp/v2/posts/${postID}`, req.body)
	
    if(resp.status !== 200) throw "エラーが発生しました"
       
  } catch (err) {        
    console.log(err)        
  }
})

例えば、WordPressのIDが3の投稿を更新するには、Thunder Clientで以下のように要求します。

update-postエンドポイントへのPUTリクエストボディ(JSON形式)
update-postエンドポイントへのPUTリクエストボディ(JSON形式)

WordPressの投稿を削除する

WordPressで投稿を削除するには、/postsエンドポイントに、削除したい投稿の一意IDを使ってDELETEリクエストを送信します。

app.delete("/delete-post", async (req, res) => {
  try {
    const postID = req.body.id                
        
    const resp = await axios.delete(`https://yourdomain.com/wp-json/wp/v2/posts/${postID}`)
	
    if(resp.status !== 200) throw "エラーが発生しました"
       
  } catch (err) {        
    console.log(err)        
    }
})

結果は次のようになります。

delete-postエンドポイントへのDELETEリクエストボディ(JSON形式)
delete-postエンドポイントへのDELETEリクエストボディ(JSON形式)

Node.jsでWordPressのコメントをモデレートする

Comments APIを使用すると、アプリケーションからWordPressサイトのコメントにアクセスして操作することができます。このAPIには、WordPressサイトのコメントを作成、一覧表示、読み取り、更新、削除するためのエンドポイントがあります。

例えば、WordPressサイトの「Follow me」(フォローしてください)というフレーズのコメントを非公開にしたいとします。regex式を使用して、コメントの投稿前にこのフレーズが含まれるかどうかをチェックすることができます。

以下のコードを使用します。

app.post("/add-comment", async (req, res) => {
  try {
    let regex = /Follow me/i;    
    let comment = req.body.comment                
      
    if(regex.test(comment)) throw "投稿が許可されていない言葉が含まれています"  		

    const resp = await axios.post(`https://yourdomain/wp-json/wp/v2/comments`, req.body)
	
  if(resp.status !== 200) throw "エラーが発生しました"  		
	
  } catch (err) {      
  
  console.log(err)
        
    }
})

このルートでは、「Follow me」というフレーズを含まないコメントだけが公開され、次のようなコメントは非公開になります。

「Follow me」を含むコメントを排除した/add-commentエンドポイントへのPOSTリクエストボディ(JSON形式)
「Follow me」を含むコメントを排除した/add-commentエンドポイントへのPOSTリクエストボディ(JSON形式)

ユーザーに合わせてサイトをパーソナライズする

ユーザーのニーズや好みを記録し、アクセスの多い国を特定することで、ユーザーごとにWordPressのページをパーソナライズすることができます。

Node.jsでは、バックエンドアプリケーションのログインまたはサインアップルートからのCookieにユーザー情報を保存し、ブラウザに保存することができます。

app.post("/sign-up", async (req, res) => {
  // Sign up user
    res.cookie("cookie_id", 123456)
    res.cookie("lang", req.body.language)
	
    res.status(200).json("Logged in.")
})

アカウント登録時に、ユーザーが普段使用している言語を取得し、cookie_idと一緒にCookieとしてブラウザに送信します。

ブラウザに保存された情報を元に、ユーザーに応じた言語でWordPressの投稿を取得することができます。これを実現するには、まずWordPressサイトのコンテンツを翻訳する必要があります。これには、WordPressサイトでWPMLとYoast SEOを統合するのが便利です。

統合すると、複数の言語用に以下のようなサブフォルダが作成されます。

  • mydomain.com/ja/
  • mydomain.com/es/
  • mydomain.com/fr/

WordPressの投稿を取得する際、Cookieに保存されているユーザーが主に使用している言語で投稿一覧を取得します。

app.get("/get-posts", async (req, res) => {
  try { 
    const lang = req.cookies.lang
       
    const resp = await axios.get(`https://mydomain.com/${lang}/wp-json/wp/v1/posts`)
	
  if(resp.status !== 200) throw "エラーが発生しました"
       
  } catch (err) {        
    console.log(err)        
    }
})

これで、アカウント登録時にユーザーが使用する言語に基づいた投稿一覧を取得できるようになります。

独自の管理パネルを構築する

ユーザーのエンドポイントを拡張することで、WordPressのユーザーの種類と権限を制御する独自の管理パネルを構築できます。Users APIを使って、Comment APIのように機能するアプリケーションから、WordPressサイトのユーザー情報にアクセスし、操作を行います。

例えば、あるユーザーの権限を「管理者」に更新したい場合には、以下のルートを使用します。

app.put("/update-user", async (req, res) => {
  try {
    const userID = req.body.id                
	
    const resp = await axios.put(`https://yourdomain/wp-json/wp/v2/users/${userID}`, req.body)
	
    if(resp.status !== 200) throw "エラーが発生しました"
       
  } catch (err) {        
    console.log(err)        
   }
})

リクエスト内で、更新したいユーザーのIDと詳細情報を含むオブジェクトを渡します。

update-userエンドポイントへのPUTリクエストボディ(JSON形式)
update-userエンドポイントへのPUTリクエストボディ(JSON形式)

Node.jsサーバーの開発を終えたら、Kinstaのアプリケーションホスティングで簡単にホストすることができます。

まとめ

Node.jsをWordPressサイトに統合することで、機能の可能性がぐっと広がります。投稿の更新、コメントのモデレート、ユーザー権限の管理、ユーザー使用する言語に応じたサイトのパーソナライズなどを行うことができます。

今回ご紹介した機能以外にも、高度な検索、テーマの管理、投稿リビジョンの追加なども実現可能です。WordPress公式のREST APIハンドブックにもぜひ目を通してみてください。

WordPressのREST APIを使用したことはありますか?以下のコメント欄でぜひご意見をお聞かせください。

 

Jeremy Holcombe Kinsta

Content & Marketing Editor at Kinsta, WordPress Web Developer, and Content Writer. Outside of all things WordPress, I enjoy the beach, golf, and movies. I also have tall people problems ;).