WordPressウェブサイトをDocker&Svelteを使ってローカル環境で開発する②〜テーマ開発編


2022/07/05
2022/08/19
WordPressウェブサイトをDocker&Svelteを使ってローカル環境で開発する①〜準備編
【Svelte Framework入門】Svelteアプリ開発でrollup.jsからViteに移行する
Svelteで作成したSPAアプリをWordPressテーマ化してWordPress無料レンタルサーバーで試す①〜XFree編

前回までの内容は以下の記事になります。

合同会社タコスキングダム|蛸壺の技術ブログ
WordPressウェブサイトをDocker&Svelteを使ってローカル環境で開発する①〜準備編

Dockerコンテナ上に高機能なWordPressウェブサイトのローカル開発環境で自作する手順を解説します。

今回の記事では、主にWordPress内部にオリジナルのテーマを作成し、そのテーマをSvelteでビルドした静的リソースに置き換えることで、SPA(シングルページアプリケーション)としてカスタマイズしたWordPressウェブページを構築します。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】Javascript&Typescriptプログラミング入門のためのオススメ書籍&教材特集

WordPressでオリジナルのテーマをカスタマイズする

ウェブ検索すると、WordPressのサイトを外部からカスタマイズする方法は、おおよそ以下の3つの方法が紹介されているのを目にします。

            
            1. 独自テーマをインストールする
2. 独自プラグインでカスタマイズページを追加する
3. WordPressとは別のサーバーでウェブページをホスティングし、
    プロキシサーバとしてWordPressからそちらへリダイレクトさせる
        
例えば項目1にあたる独自テーマを一から作成するやり方を紹介している以下のようなサイトも多数あります。

参考|WordPressの自作テーマに挑戦してみよう! 初めてでも意外と簡単?

独自テーマを作るやり方は非常に汎用性があり、開発期間が許せばフロントエンドエンジニアがじっくりとウェブサイト構築に取り組めるのならば、最もおすすめの手法です。

開発時間に余裕がなかったり、既存のWordPressウェブサイトが中大規模で、途中からのコード修正が既にやりにくい場合には、項目2の「プラグイン」で対応する方が懸命な対応と言えます。

参考|超簡単!WordPressプラグインの作り方(デモファイルの配布あり)

また独自プラグインはテーマと比較してWordPressで有料販売しやすく、好んでプラグインの方を開発するエンジニアの方も多いようです。

実用性を兼ね備えるやり方としては、プラグイン方式もおすすめになります。

他方、WordPressのウェブサイトのエンドポイントURLを変換することで、通常のWordPressサーバーがホスティングする静的リソースを使わず、別の代替サーバーで立ち上げたウェブサイトへリダイレクトする機能を使う方式もあります。

この場合、WordPressウェブサイトを間借りした、別のウェブサイトである気がしますが、一応WordPressが提供している機能ですので、WordPressウェブサイトの一形態と言えます。

参考|エンジニア歴半年記念にNext.js(SSG)× Docker × TailwindCSSで作るPreview機能付きヘッドレスWordpressサイトを作ってみた件

この方式を行うデメリットしては、フロントエンドのみならず、サーバーサイドのバックエンド開発の知識も必要になってくる点です。

どちらかといえば、既存のWordPressウェブサイトを、非WordPress系のウェブサイトに移行するときに、サイト集客やGoogle検索のインデックスに影響を与えずにスムーズに新旧サイトを入れ替えるときに有効な技です。

このため主としてウェブサイトを運用するやり方には向かないかも知れません。

これら項目1〜3のやり方には長所短所がそれぞれありますが、このブログでは
「項目1」のやり方をベースにSvelteとWordPressを統合していきます。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】Javascript&Typescriptプログラミング入門のためのオススメ書籍&教材特集

WordPressに独自テーマを作成する

まずは独自テーマをどのように作成すると良いのかを具体的に手動でやってみましょう。

もっともシンプルに、ヘッダーとフッターとメインコンテンツだけを含むテーマを作ります。

前の記事でも解説していたように、DockerコンテナのWordPressプログラム本体が/var/www/htmlの中に納められています。

合同会社タコスキングダム|蛸壺の技術ブログ

ここでWordPressのテーマが格納されているのが、
wordpress/wp-content/themesというフォルダです。

さらにその中身を確認すると、

            
            $ tree wordpress/wp-content/themes/ -L 1
.
├── index.php
├── twentytwenty
├── twentytwentyone
└── twentytwentytwo
        
という構成になっており、ウェブページのルート共通ファイルにあたるindex.phpと、3つのデフォルトのサンプルテーマ・twentytwenty(2020)twentytwentyone(2021)twentytwentytwo(2022)のフォルダが入っています。

合同会社タコスキングダム|蛸壺の技術ブログ

もう少しテーマの一つのフォルダの中を見てみましょう。

            
            .
├── index.php
├── 404.php
├── comments.php
├── footer.php
├── functions.php
├── header.php
├── searchform.php
├── singular.php
├── assets
├── classes
├── inc
├── package-lock.json
├── package.json
├── print.css
├── readme.txt
├── style-rtl.css
├── style.css
├── screenshot.png
├── template-parts
└── templates
        
見ての通り、WordPressのテーマの実体はPHPファイルを主としたHTML生成プログラムのリソースセットになっています。

ではWordPressのファイル構造をサッと把握してもらったところで、もっとも簡単なテーマを作成していきましょう。

以下のように
wordpress/wp-content/themesフォルダ内にemptyという空フォルダを作成し、その中にリソースファイルを追加します。

            
            $ mkdir wordpress/wp-content/themes/empty
$ cd wordpress/wp-content/themes/empty
$ touch functions.php index.php header.php footer.php style.css
        
WordPressテーマとして最低限動かしたい場合、以下のファイルが必要になるでしょう。

            
            + functions.php:
    テーマ全体で使う機能を設定する定義ファイル
+ index.php:
    HTMLページのテンプレートファイル(本体)
+ header.php
    HTMLページのテンプレートファイル(ヘッダーパート)
+ footer.php
    HTMLページのテンプレートファイル(フッターパート)
+ style.css
    スタイルシートのルートファイル
        
ではそれぞれのファイルの実装の中身を示します。

functions.php

functions.phpにはウェブサイトで共通のアセットファイルなどを管理するという重要な役目がありますが、この時点ではほぼ空です。

            
            <?php
///...以降で定義や共通関数を記述していく
        

index.php

いわゆるindex.htmlに対応するメインのPHPファイルです。

ヘッダーとフッターは別のファイルに分離しています。

            
            <?php get_header(); ?>
<main>
    <p>初めてのWordPressテーマです。</p>
</main>
<?php get_footer(); ?>
        

header.php

先程index.phpから分離したうちのヘッダー部分を担当するPHPファイルになります。

            
            <!DOCTYPE html>
<html>
<head>
    <?php wp_head(); ?>
</head>
<body>
<div>
    <p>ヘッダーです。</p>
</div>
        

footer.php

こちらはindex.phpから分離したうちのフッター部分を担当するPHPファイルになります。

            
            <div class="section-inner">
    <p>フッターです。</p>
</div>
<?php wp_footer(); ?>
</body>
</html>
        

style.css

style.cssファイルが無いとテーマの読み込みに失敗するため、スタイリングしない場合でもテーマのフォルダのルートに原則作成しなくてはいけません。

            
            /*
Theme Name: Empty
Text Domain: Empty
Version: 1.0
Tested up to: 6.0
Requires at least: 4.7
Requires PHP: 5.2.4
*/

html, body {
    width: 100%;
    background: rgb(255, 255, 255);
}
        

ダッシュボードから自作テーマを適用する

上記のように各リソースファイルを編集し終えたら、WordPressのダッシュボードより、[外観] > [テーマ]をクリックし、テーマの管理ページを表示すると、Emptyのテーマが有効になっていると思います。

合同会社タコスキングダム|蛸壺の技術ブログ

このテーマを適用することで、以下のようにもっとも単純なWordPressページが生成されているはずです。

合同会社タコスキングダム|蛸壺の技術ブログ

本格的にWordPressテーマの開発を勉強してみたい方はここからPHPのプログラミングを学習することになりますが、弊社のブログではPHPのネタは直接扱いません(というか著者はPHPあまり詳しくありません...)。

ということで、PHPでゴリゴリにWordPress開発をするスタイルではなく、
Javascript/TypescriptでいかにWordPressウェブサイトのリソースを置き換えていくのか、という視点で後半のSvelteとの統合の話に移ります。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】Javascript&Typescriptプログラミング入門のためのオススメ書籍&教材特集

SvelteのビルドリソースでWordPressのアセットファイルを置き換えるやり方

後半のパートの目標としては、

            
            1. Svelteでビルド・バンドルしたJavascriptファイルをWordPressテーマに埋め込む
2. Svelteでビルド・バンドルしたCssファイルをWordPressテーマに埋め込む
3. 1と2をポストビルド処理として自動化する
        
という内容を軸に話を進めます。

WordPress側のPHPファイルから外部Javascriptスクリプトを読み込む

WordPress側のPHPプログラムでJSスクリプトを読み込ませるテクニックから解説します。

WordPressのウェブページでは最終的にレンダリングされるHTMLへ直接
<script>タグを仕込むというスタイルは正式な作法ではなく、その代わりにfunctions.phpから外部のリソースを注入することによって実現します。

一つ簡単なJSスクリプトで試してみましょう。

wordpress/wp-content/themes/emptyフォルダ内にassetsというフォルダを作り、そこでリソースを管理します。

            
            #...wordpress/wp-content/themes/empty内で作業する
$ mkdir assets
$ mkdir assets/js
$ touch assets/js/hello_wp.js
        

とりあえず空で作成した
assets/js/hello_wp.jsファイルを以下のようにします。

            
            console.log(`Hello, WORDPRESS THEME!`);
        
次にfunctions.phpを以下のように編集します。

            
            <?php

//👇テーマルートディレクトリまでのパスを定数として定義
if (!defined('WP_THEMES_ROOT')) {
    define('WP_THEMES_ROOT', get_template_directory_uri());
}

function add_files() {
    wp_enqueue_script('my_first_script', WP_THEMES_ROOT . '/assets/js/hello_wp.js');
}

add_action('wp_enqueue_scripts', 'add_files');
        
ここでのadd_action関数は、「アクションフック」と呼ばれるもので、add_action([アクション名], [ハンドラ名])で、指定したアクション先に、ハンドラ(ハンドル関数)の中身に定義されたアクションの詳細を追加しているもののようです。

参考|WordPressでファイルを読み込むためのwp_enqueue_styleとwp_enqueue_scriptの使い方と引数の意味を理解しておこう。

...PHPを使わない人間にはあまりアクションフック自体が馴染みが薄いですが、理解はしやすいので定形構文としてそんなもんなんだ、くらいに思っておきましょう。

再度、WordPressページを読み込んで、ブラウザコンソールを確認すると、

合同会社タコスキングダム|蛸壺の技術ブログ

標準出力得られていればOKです。

これでWordPressとJavascriptコードとの提携が出来るようなりました。

ここで試しにSvelteのビルド出力した
bundle.jsを、手動でテーマのassets/js以下にコピペしておいておきます。

Svelteコードの制約として、バンドル後のJSスクリプトは
<head>要素内に記述されている必要があります。

デフォルトの
wp_enqueue_scriptsアクションでは、HTML内に生成されるDOMがレンダリングされる前にスクリプトが実行されてしまうので、SvelteアプリがターゲットDOMの所在を解決できずにレンダリングエラーしてしまいます。

これを避けるために、
functions.phpを以下のように追記します。

            
            //...中略

function add_svelte(){
    wp_enqueue_script('svelte_script', WP_THEMES_ROOT . '/assets/js/bundle.js');
}

add_action('wp_head', 'add_svelte');
        

ポイントとして、アクションフック先に
wp_headを指定することで、<head>要素にJSスクリプトを追加することが出来るようです。

WordPressページをリロードして、

合同会社タコスキングダム|蛸壺の技術ブログ

Svelteアプリが無事レンダリング出来ていることが確認できます。

WordPress側のPHPファイルから外部Cssスタイルを読み込む

先程はJSスクリプトをfunctions.phpに読み込ませてみましたが、ほぼ同じ理屈でcssファイルもwp_enqueue_style関数から外部リソースとして読み込ませることが出来ます。

まずテーマのcssスタイル用に
assets/cssフォルダを作成し、そこにSvelteのビルド後のバンドルスタイルファイル(bundle.css)を手動でコピペしてみましょう。

そしてfunctions.phpを更に以下のように修正します。

            
            <?php

//テーマディレクトリまでのパス定数
if (!defined('WP_THEMES_ROOT')) {
    define('WP_THEMES_ROOT', get_template_directory_uri());
}

function add_files() {
    wp_enqueue_script('my_first_script', WP_THEMES_ROOT . '/assets/js/hello_wp.js');
    #👇WordPressルートのstyle.cssはここで読み込み
    wp_enqueue_style('root_style', WP_THEMES_ROOT . '/style.css');
}
add_action('wp_enqueue_scripts', 'add_files');

function add_svelte(){
    wp_enqueue_script('svelte_script', WP_THEMES_ROOT . '/assets/js/bundle.js');
    #👇Svelteアプリのスタイルもhead要素内で読み込みする
    wp_enqueue_style('main_style', WP_THEMES_ROOT . '/assets/css/bundle.css');
}
add_action('wp_head', 'add_svelte');
        
ではSvelteとWordPressの連携の準備が整いましたので、ページをリロードすると、

合同会社タコスキングダム|蛸壺の技術ブログ

ようやく首題の
「Svelte-WordPress」ウェブページが形になりました。

Svelteビルド後の出力ファイル先を変更する

以上までで「Svelte-WordPress」ウェブページの作り方の概要の内容は終わりで、後はSvelteでゴリゴリとウェブサイトを作り込んでいくわけですが、ビルドの度に手動でbundle.jsbundle.cssをWordPressテーマのassetsフォルダへコピーするのはかなり苦痛です。

そこでSvelteビルド後に、WordPressのテーマアセットフォルダへ自動仕訳してくれるようにシェルスクリプトを一つ噛まします。

Svelteプロジェクト側のルートから作業して、
shell/postbuild.shというシェルスクリプトを作ります。

            
            $ mkdir shell
$ touch shell/postbuild.sh
        
で、スクリプトの中身を以下にしておきます。

            
            #!/bin/bash
echo 'POSTBUILD PROCESS'

#👇Svelteアプリのビルド後保存先の開発Dockerコンテナ内での絶対パス
SVELTE_DIST=/usr/src/app/svelte-app/public/build

#ビルド後のリソースの送り先(こちらもDockerコンテナ内での絶対パス)
WP_ASSETS_DIR=/usr/src/app/wordpress/wp-content/themes/empty/assets

if [ -d $WP_ASSETS_DIR ]; then
    if [ ! -d $WP_ASSETS_DIR/js ]; then
        mkdir $WP_ASSETS_DIR/js
    fi
    if [ ! -d $WP_ASSETS_DIR/css ]; then
        mkdir $WP_ASSETS_DIR/css
    fi
else
    echo 'Themeにassetsフォルダがありません!'
fi

if [ -f $SVELTE_DIST/bundle.js ]; then
    cp $SVELTE_DIST/bundle.js $WP_ASSETS_DIR/js/
    echo 'bundle.jsをコピーしました'
fi

if [ -f $SVELTE_DIST/bundle.css ]; then
    cp $SVELTE_DIST/bundle.css $WP_ASSETS_DIR/css/
    echo 'bundle.cssをコピーしました'
fi
        
あとはpackage.jsonのスクリプトパートにこのスクリプトを仕込んでおきます。

            
            {
  "name": "svelte-wordpress-app",
  //...中略
  "scripts": {
    "build": "rollup -c",
    //...中略
    //👇postbuildコマンドを追記
    "postbuild": "bash shell/postbuild.sh"
  },
//...以下略
        
これでビルド後にshell/postbuild.shの処理が走ってくれるとSvelteのビルドリソースが全てWordPress側で自動で流れるようになると思います。

            
            $ yarn build
#👇アプリのビルド後にリソースのコピー処理が走るとOK
yarn run v1.22.17
rollup -c

src/main.ts → public/build/bundle.js...
created public/build/bundle.js in 5.7s

bash shell/postbuild.sh
POSTBUILD PROCESS
bundle.jsをコピーしました
bundle.cssをコピーしました
        
これで、WordPressのSvelteによるSPA化が無事完了しました。めでたしめでたし。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】Javascript&Typescriptプログラミング入門のためのオススメ書籍&教材特集

まとめ

以上までで、WordPressウェブサイト(テーマ)をSvelteアプリによるビルド生成物で置き換える方法の手順を2回に渡り説明してきました。

JS系のフレームワークであれば、Svelteに限らず、ReactでもVueでもAngularでもビルド後にWordPressのテーマのアセットフォルダへ上手く結びつけられたら理屈上ではどのフレームワークでも動くと思います。

ただし、リッチなフレームワークほど出力生成物の容量が大きいので、SvelteやSolid.jsなどの軽量なフレームワークの方がより快適かも知れません。

SvelteによるWordPressウェブサイトの開発環境の構築の話はここで一旦終わりですが、実際のWordPressが使えるレンタルサーバーで動くのかは興味があるところです。

今後時間があれば、適当なアプリでウェブサイトを公開する手順も紹介していきたいと思います。