menu
書いてる野郎
orebike@gmail.com
企業サイトを作る場合、ページは主に固定ページに対するテンプレートを作っていくことになる。
普通ならば、企業サイトは、全体の構成、そこにハマっているヘッダー・フッター等は共通になっていることがほとんどだろう。
WordPress のテーマのテンプレートというのは、部品をバラバラにして串団子ののように乱暴に切り貼りすることしかできない。 全体の構成というものを共通化することができない。このような機能は通常のWeb系のフレームワークでは「レイアウト」という名前で提供されることが多い。 「レイアウト」というのは「中身」から「外枠」を決定できるという仕組みである。
WordPress にはそのような機能が無いので、テンプレートを静的に生成して、その際に外枠をつけてしまうという仕組みを作る。
様々な環境での環境構築の簡便さを考慮して、JavaScript で作り node.js で駆動することにする。
今回は JavaScript を使って HTML コードの中にちょびっと PHP なコードを生成する。 このような改行を含む大量の単純文字列操作をするための仕組みがどの言語システムにも存在していて node では ejs というモノを使う。
ejs にもレイアウトのような機能は無いっぽく、それを拡張する機能はあるっぽいが、うまく動くのか怪しい。 簡単なので自作する。
レイアウトのような機能を実現するには、仕組みとして3つの機能が必要
つまり流れはこうである。
そして作ったモノがこのような感じになる。
const targetPageEjs = process.argv[2]; const ejs = require('ejs'); const fs = require('fs'); // ejs ファイルを読み出す const contentEjs = fs.readFileSync(targetPageEjs, 'utf8'); const data = { filename: targetPageEjs, // 実際に駆動させる今呼び出した ejs ファイルの中身 // 本来パラメータを渡す必要は無いのだが、このオブジェクトを通じて targetPageEjs の中身を吸い上げるので // そのためにオブジェクトを構築する page: { title: "", description: "", cssfile: "", layout: "", templatename: "" } }; // 実際に駆動させて結果を取得する const content = ejs.render(contentEjs, data); // オブジェクトを通じて data.page の中身が書き換わっているので // layout で外枠を指定することができる const layoutEjs = fs.readFileSync(data.page.layout, 'utf8'); const html = ejs.render(layoutEjs, { filename: data.page.layout, page: { content: content, //先に描画した中身をパラメータとして渡す cssfile: data.page.cssfile, // head 内に書き込みたい中身毎に違う css をパラメータとして渡す title: data.page.title, // head 内に書き込みたい中身毎に違う title をパラメータとして渡す description: data.page.description, // head 内に書き込みたい中身毎に違う description をパラメータとして渡す templatename: data.page.templatename // WordPress のテンプレートにはコメントで名前が埋め込めるの } }); // 出来上がったモノを画面へ出力する console.log(html);
このように実行する。画面にテンプレートがぶちまけられるのでリダイレクトでファイルに入れ込むだけ。
$ node render.js hoge.ejs > content_hoge.php
ejs ファイルはこうなっている。
<% page.title = "ほげほげのページ" %> <% page.description = "ここがページの説明です" %> <% page.cssfile = "hogehoge.css" %> <% page.layout = "layout1.ejs" %> <% page.templatename = "CONTENT_HOGEHOGE" %> <h1>ほげほげのページ</h1> <p>ここにテキストが入ります。</p>
ファイルの冒頭の設定ファイル的な記述を使って外部のオブジェクトを書き換えている。ここで layout1.ejs という「外枠」を指定している。 中身が外枠を指定できることでレイアウトが実現する
layout1.ejs はこうなる
<?php /* * Template Name: <%= page.templatename %> */ ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /> <title><%- page.title %></title> <meta name="description" content="<%- page.description %>" /> <link rel="stylesheet" type="text/css" href="<?= get_template_directory_uri() ?>/style/<%= page.cssfile %>" /> </head> <body> <%- include("header1", {}) %> <%- page.content %> <%- include("footer1", {}) %> </body> </html>
うけとったパラメータを穴に埋めこんでいく。途中の %=
は HTMLのサニタイズ入り、 %-
はサニタイズ無しを意味している。
文字列として出力しないで単純に埋め込むだけならば include という記述が使える。今回だとヘッダーとフッターを読み込んでいる。 この際は ejs の拡張子は省略して書くことができる。
このレイアウトでは WordPress のテンプレート文法、関数、PHP の出力記述、ejs の出力記述、JavaScript の制御構文、HTML のタグと、複数の記述がゴチャゴチャになり、それもどれもが駆動タイミングがズレているということで混乱ので気をつけて書く必要がある。
このようにファイルを用意しておいて
node render.js hoge1.ejs > content_hoge1.php node render.js hoge2.ejs > content_hoge2.php node render.js hoge3.ejs > content_hoge3.php node render.js hoge4.ejs > content_hoge4.php node render.js hoge5.ejs > content_hoge5.php node render.js hoge6.ejs > content_hoge6.php
このように実行すると3秒おきに適当にビルドしてくれる。
$ yes 'sh build_template.sh|sleep 3'|sh
重い処理でもないし、大量に作るわけでもないので、毎秒全件ビルドでもほぼ問題ないだろう。
yes コマンドというのは何か処理が進む度に yes を入力して次の処理に進めるためのコマンドで、通常は何か対話的な入力をするための処理で全部「yes」と答えるためのどうしようもない手抜きツールなのだが、これを利用すると任意のコマンドの連続実行が可能になる。