少し前に「WordPress 4.7のREST APIを使った記事閲覧プログラム」を掲載したが、これはクライアント側(ブラウザ)のみでの実験。今度はサーバー側にNode.jsを使ってBLOGのViewを再構築することに…。
これまでNode.jsはメッセージング系で少し触ったことがあるものの、Webサーバー、つまりApacheの替わりとしては使ったことがなかったので、WordPress 4.7のREST APIがある程度分かったついでに実験したくなった(笑)。
但し、管理画面も実装するならともかく、Viewだけだとクライアント側のみで出来るので、わざわざサーバー側でやることもなく、あくまでも遊びだ。
全体の概要
Node.jsの開発環境はググるといろいろ出てくるので省略。当初はWindowsのBashを使用したものの、WindowsからBashへのファイルのやり取りが面倒(逆はOK)だったので*追記あり、後半はmacOSへ移行した。どちらもnodebrewを使えば簡単に環境を構築できる。
npmでインストールしたモジュールは以下の通り。
最後の3つは軽くパフォーマンスアップするもので無くても作動する。またサイトがhttpsの場合は、http(http.get)モジュールではなくhttpsモジュール(https.get)を使用する。
ここにコードを載せても載りきらないので要点はこんな感じだ。
- Expressでのルーティング
app.get(‘/’ …
app.get(‘/page/:pages’ …
app.get(‘/tag/:tags/page/:pages’ …
app.get(‘/category/:categories/page/:pages’ …
app.get(‘/post/:postId’ …
※例えば/pageといった、1ページだけのルーティングは省略
- 各ルーティングで必要なデータをREST APIで得る
-
一覧表示の各内容は、content.renderedにimgなどタグも含めそのまま入っているので、<!−−more−−>までで切り出す
-
paginateで必要な最大件数/最大ページ数はJSONにはなく、レスポンスヘッダのX-WP-TotalとX-WP-TotalPagesに入っているので、例えばhttp.get(url, (d)とすると、d.rawHeaders[]のn番目に先の文字列があり、n+1が欲しい値となる
- REST APIで得たデータを加工してテンプレートejsへ渡す
index.ejs(他の一覧も兼ねる)
post.ejs
テンプレートはこの2本だけだが、実際はヘッダー、サイドバー、フッターなどを別ejsにしてincludeするよくあるパターン。htmlのフレームワークはお馴染みBootstrapだ。
API仕様の気になる点
プログラム自体は簡単だが、実際に動かして思ったのは、純粋に一覧だけ(title、date、categories、tags、featured_media程度のみ)得るAPIが無いため、何をするにしてもpostsでデータを得る必要がり、JSONのデータ量と、それを作るときのサーバー側の負荷(ショートコードやfunctions.phpの内容も展開する)が結構かかる。
加えてサムネイル画像を一覧に出そうとすると_embedオプションを付けなければならず、更にデータ量が増す。ここのように遅いサーバーだとその差は体感ではっきりわかるほどだ。
本家はたまたまアイキャッチ画像(featured_media)を使わず、記事の頭に大き目の画像を入れてあるので、これには引っかからなかったが、一般的には重い処理となるだろう。
本家にあって、こちらに無いのは「前後記事へのリンク」と「Archivesの年月一覧」。今のAPI仕様ではどうみても全件データを引っ張って解析しない限りこの2つには対応できないように思う。
一部クライアント側でレンダリング
一点手抜き(?)したのは、サイドバーの各一覧。これはサーバー側ではなく、クライアント側で書いている。もともとウィジェットを置く場所なのでこれもありかなと…。
ちょっとアクロバティックなのはPopular Posts。これはWordPress Popular Postsがウィジェットとして表示しているもので、実体はadmin-ajax.php?action=wpp_get_popularを呼ぶとリストのhtmlが戻ってくる形になっている。ただそのまま呼ぶとクロスドメイン制約で値を得られない。
そこで同じサーバー内にあるのを利用して、curlを使い一定間隔でそのhtmlをファイルへ保存、参照する形にしている。
これで無事表示は出来るのだがリンク先は本家。実験サイトではないため、このままだとあまり意味がない。また本家のURLはタイトルベース、実験サイトはIDベースなので、ドメインの部分だけ置換しても作動しない。
「うーん」と思っていたところ、表示するサムネイル画像のファイル名にIDが入っていることが分かり、それを使って実験サイトへのURLになるよう書き換えた(笑)
雑感
仕上げはサーバーへの設置だ。Proxyを設定するのが面倒なので、iptablesでポート3000を開けそのまま外に出している。この時、スクリプトをデーモン化する必要があり、forever -w start app.jsで起動。無事、外からアクセスできるようになった。
一式やってみた感想は、当初Node.jsの話を聞いたとき、既にいろいろあるのに何故今更JSと思ったが、サーバー側もクライアント側も全てJSで書け分かり易い上にデバックもし易く、これはありだ。
またテンプレートエンジンのEJSは、htmlそのまま<% %>の中だけJSの世界となりとっつき易い。つまり普段、LAMPを使っていれば、ベースの部分は何も学ぶ必要がなく、各モジュールの仕様だけ理解すれば(しかもJS)即扱える。これはなかなか楽しいかも知れない。
Node.js+Express+EJSで再構築したBLOGのViewはこちら。
追記
「WindowsからBashへのファイルのやり取りが面倒」と書いたが、/mnt/c/Users/にWindowsのファイルシステムがマウントされているので、ここならどちらからでも普通にアクセスできる。
更にVisual Studio Codeの総合ターミナルをBashに変更すればかなりGoodな環境となる。
Visual Studio Codeの総合ターミナルでBashが作動中
方法はメニューのファイル/設定/基本設定/ユーザー設定で、
1 2 3 4 |
{ "terminal.integrated.shell.windows": "C:\\Windows\\sysnative\\bash.exe", "termnial.integrated.shell.unixlike": "bash.exe" } |
これを追加すればOK。もちろんviやnode app.jsもこの中でそのまま作動!