最終更新 : 2022-08-06
そんなことありますよね?ない?
そもそもフロントエンドの人間として、wordpressって使いたくないじゃないですか。僕だけですか?だから僕はJAMStackを推してるんですけど。本当はmicroCMSとかヘッドレスCMS使いたい、でも「wordpressじゃなきゃヤダッ!」って言われることもままあるかと思われます。あと、ポリシーの関係で外部にデータおけないとかあると思うんですよ。それをうまいことやっていけないかなって考えてみた話です。あ、Docker使っていきます。
今回使うソースコード類はgithub上に載せてあります。
docker-compose.ymlを見ていく
docker-compose.ymlはこんな感じになります。
version: '3.1'
services:
wordpress:
image: wordpress
restart: always
ports:
- 8080:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- ./wordpress:/var/www/html
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- ./db:/var/lib/mysql
nuxt:
image: node:alpine
restart: always
volumes:
- ./nuxt:/home/node
tty: true
working_dir: /home/node
command: [node, webhook.js]
nginx:
image: nginx:alpine
restart: always
ports:
- 8000:80
volumes:
- ./nuxt/dist:/usr/share/nginx/html
volumes:
wordpress:
db:
nuxt:
wordpress,dbはwordpress関係です。docker hubに書いてあるやつそのままです。wordpressにはlocalhost:8080で繋がります。
nuxtはnodeイメージを使って、nuxtファイルを扱うコンテナです。./nuxtがマウントされてます。wordpressから変更のwebhookを受けてビルドする役割もあります。
nginxはサーバです。./nuxt/distをマウントして配信してます。localhost:8000で繋がります。
./nuxtのファイルを見ていく
この中はnuxtのプロジェクトファイルが入ってます。今回はwordpressのREST apiから投稿データを取得して、それぞれの投稿内容を個別のページで表示します。スタイルとか特につけてないです。index.vue
<template>
<div id="container">
<router-link v-for="d in data" :key="d.id" :to="`/p/${d.id}`" class="link">{{ d.title.rendered }}</router-link>
</div>
</template>
<script>
export default {
asyncData: async() => {
const data = await fetch("http://wordpress/wp-json/wp/v2/posts").then(json => json.json());
return {data: data};
}
};
</script>
<style scoped>
#container {
display: flex;
flex-direction: column;
padding: 24px;
}
</style>
/p/_id.vue
<template>
<div id="container">
<div v-html="data.content.rendered"></div>
</div>
</template>
<script>
export default {
asyncData: async(c) => {
const data = await fetch(`http://wordpress/wp-json/wp/v2/posts/${c.params.id}`).then(res => res.json());
return {data: data};
}
};
</script>
<style scoped>
#container {
padding: 24px;
}
</style>
また、この中の「webhook.js」は80番ポートで待ち構えて、postで通知が来たらexecで「npm run generate」を起動します。あんまりしっかり作ってないんで、連続でpostが来るとプロセス乱立します。webhook.js
const express = require('express');
const app = express();
const { exec } = require('child_process')
app.post('/build', (req, res) => {
console.log('build start');
res.end();
exec('npm run generate', (err, stdout, stderr) => {
if (err) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
});
app.listen(80, () => console.log('server is working at :80'));
wordpressを設定していく
wordpressのインストールは適当にやってください。REST apiを使うので「パーマリンク設定」を「基本」から変えておいてください。重要なのは、webhookを送ることです。どうやらプラグインにwebhook(てか、postでhttpリクエスト送るだけなんすけどね)を設定できるもの(こちら)がありますので、使っていきます。PHPなんて触りたくないので。とりあえずお使いのwordpressにインストール・有効化してください。
したらばセッティングです。プラグインのWP WebhooksからSettingsを押して設定画面に行きます。そこから更にSettingsを選択します。
ここで設定するのは「Activate "Send Data" Triggers」です。まあ、記事の追加・更新・削除あたりでビルドし直すのが良いでしょうから適当に選んで「Save all」してください。
次にWebhookのURLなどを設定していきます。「Send Data」から設定していきます。
「Webhook Name」は適当に、「Webhook URL」は「http://nuxt/build」にしてください。docker-composeで立てたコンテナ間の通信は、コンテナ名で名前解決してくれます。
これで追加したあと、「Refresh for Settings」をして、「Settings」から「Allow unsafe URLs」を有効にしてください。これしないとpostしてくれません。
これで設定は終了です。試しに投稿を一つ追加してみて、ビルドされるか確かめてください。
終わり
なんか、wordpressを使いたくない一心でやってますけど、まじでwordpress使いたくねぇんだよなぁ…(というと語弊があるけど、一番の狙いはPHP使いたくないってところです。JavaScriptで完結させたい)
あとは、wordpressの管理画面のアクセス制限つけたりすると、より良くなるんじゃないですかね?しらんけど。