Laravel と WordPress を同居させる
サイト全体は Laravel で構築しつつ、ブログや更新情報だけ WordPress を使いたい、というニーズって結構あると思います。WordPress を Laravel の外にインストールして、サブドメインとかで運用する方法もありますが、今回は Laravel のディレクトリ構造の中に WordPress をインストールして共存させることをゴールとします。使用している Laravel のバージョンは 6.x、WordPress は 5.9 です。
Laravel は、/var/www/laravel/
以下に、WordPress は、Laravel 内の /public/wp/
以下にそれぞれインストールし、https://example.com/blog/ 以下を WordPress で管理する想定で説明します。ディレクトリ構造が違う場合は適宜読み替えてください。
/public/.htaccess を書き換える
インストール直後の Laravel は、すべてのリクエストを /public/index.php
に集めるように設定されています。このままだと、WordPress がリクエストを処理できないので、リライトの設定を行います。先に完成版を示します。
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# WordPress でプレビュー表示する際に必要
RewriteCond %{QUERY_STRING} preview=true
RewriteRule ^index\.php$ /wp/index.php [L]
# WordPress の wp-json 対策
SetEnvIf Request_URI ^/wp-json/(.*) REST_ROUTE=$1
RewriteCond %{REQUEST_URI} ^/wp-json/
RewriteCond %{QUERY_STRING} (.*)$
RewriteRule . /wp/index.php?rest_route=/%{ENV:REST_ROUTE}&%1 [L]
# WordPress 化したいページをかっこの中に列記する
RewriteCond %{REQUEST_URI} ^/(blog)/
RewriteRule . /wp/index.php [L]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_URI} !^wp/wp-admin.*$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_URI} !^wp.*$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
プレビュー表示対策は、WordPress をサイトの一部のみで利用するでも説明しているので、他の部分について説明します。
wp-json 対策
現在の WordPress は、各種処理を REST API 経由で行っています。詳細は、公式ドキュメントを見てほしいのですが、特に設定を変更していない場合、/wp-json/
以下にリクエストが飛ぶようになっています(/wp-json/wp/v2/posts
など)。
実際の処理は、/wp/index.php?rest_route={rest_route}
(例えば、/wp/index.php?rest_route=/wp/v2/post
)が行うので、そこにリクエストが飛ぶようにリライトの設定を行います。
SetEnvIf Request_URI ^/wp-json/(.*) REST_ROUTE=$1
RewriteCond %{REQUEST_URI} ^/wp-json/
RewriteCond %{QUERY_STRING} (.*)$
RewriteRule . /wp/index.php?rest_route=/%{ENV:REST_ROUTE}&%1 [L]
先に環境変数 REST_ROUTE
に /wp-json/
以下の部分を入れておき、引数とあわせて /wp/index.php
に渡しています。
WordPress に渡したい URL の処理
あとは、WordPress で管理する URL や管理画面の URL を Laravel に渡さないように除外の設定などを入れていきます。
wp-config.php の修正
せっかく Laravel と同居させるのですから、データベースの接続設定などは /.env を参照するようにします。こちらも完成版を先に。
<?php
$root_dir = '/var/www/laravel';
// Cannot redeclare __() 対策
require_once($root_dir . '/public/wp/wp-includes/l10n.php');
require_once($root_dir . '/vendor/autoload.php');
$dotenv = Dotenv\Dotenv::create($root_dir);
if (file_exists($root_dir . '/.env')) {
$dotenv->load();
$dotenv->required(['DB_DATABASE', 'DB_USERNAME', 'DB_PASSWORD']);
}
/**
* WordPress の基本設定
*
* このファイルは、インストール時に wp-config.php 作成ウィザードが利用します。
* ウィザードを介さずにこのファイルを "wp-config.php" という名前でコピーして
* 直接編集して値を入力してもかまいません。
*
* このファイルは、以下の設定を含みます。
*
* * MySQL 設定
* * 秘密鍵
* * データベーステーブル接頭辞
* * ABSPATH
*
* @link https://ja.wordpress.org/support/article/editing-wp-config-php/
*
* @package WordPress
*/
// 注意:
// Windows の "メモ帳" でこのファイルを編集しないでください !
// 問題なく使えるテキストエディタ
// (http://wpdocs.osdn.jp/%E7%94%A8%E8%AA%9E%E9%9B%86#.E3.83.86.E3.82.AD.E3.82.B9.E3.83.88.E3.82.A8.E3.83.87.E3.82.A3.E3.82.BF 参照)
// を使用し、必ず UTF-8 の BOM なし (UTF-8N) で保存してください。
// ** MySQL 設定 - この情報はホスティング先から入手してください。 ** //
/** WordPress のためのデータベース名 */
define('DB_NAME', $_ENV['DB_DATABASE']);
/** MySQL データベースのユーザー名 */
define('DB_USER', $_ENV['DB_USERNAME']);
/** MySQL データベースのパスワード */
define('DB_PASSWORD', $_ENV['DB_PASSWORD']);
/** MySQL のホスト名 */
define('DB_HOST', $_ENV['DB_HOST']);
/** データベースのテーブルを作成する際のデータベースの文字セット */
define('DB_CHARSET', $_ENV['DB_CHARSET']);
/** データベースの照合順序 (ほとんどの場合変更する必要はありません) */
define('DB_COLLATE', $_ENV['DB_COLLATION']);
/**#@+
* 認証用ユニークキー
*
* それぞれを異なるユニーク (一意) な文字列に変更してください。
* {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org の秘密鍵サービス} で自動生成することもできます。
* 後でいつでも変更して、既存のすべての cookie を無効にできます。これにより、すべてのユーザーを強制的に再ログインさせることになります。
*
* @since 2.6.0
*/
define('AUTH_KEY', $_ENV['WP_AUTH_KEY']);
define('SECURE_AUTH_KEY', $_ENV['WP_SECURE_AUTH_KEY']);
define('LOGGED_IN_KEY', $_ENV['WP_LOGGED_IN_KEY']);
define('NONCE_KEY', $_ENV['WP_NONCE_KEY']);
define('AUTH_SALT', $_ENV['WP_AUTH_SALT']);
define('SECURE_AUTH_SALT', $_ENV['WP_SECURE_AUTH_SALT']);
define('LOGGED_IN_SALT', $_ENV['WP_LOGGED_IN_SALT']);
define('NONCE_SALT', $_ENV['WP_NONCE_SALT']);
/**#@-*/
/**
* WordPress データベーステーブルの接頭辞
*
* それぞれにユニーク (一意) な接頭辞を与えることで一つのデータベースに複数の WordPress を
* インストールすることができます。半角英数字と下線のみを使用してください。
*/
$table_prefix = $_ENV['WP_TABLE_PREFIX'];
/**
* 開発者へ: WordPress デバッグモード
*
* この値を true にすると、開発中に注意 (notice) を表示します。
* テーマおよびプラグインの開発者には、その開発環境においてこの WP_DEBUG を使用することを強く推奨します。
*
* その他のデバッグに利用できる定数についてはドキュメンテーションをご覧ください。
*
* @link https://ja.wordpress.org/support/article/debugging-in-wordpress/
*/
define('WP_DEBUG', !!$_ENV['APP_DEBUG']);
/* カスタム値は、この行と「編集が必要なのはここまでです」の行の間に追加してください。 */
/* 編集が必要なのはここまでです ! WordPress でのパブリッシングをお楽しみください。 */
/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}
/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';
単純に /vendor/autoload.php
を require_once するだけだと、Laravel と WordPress の両方に __() 関数があるため、Cannot redeclare __()
のエラーが発生してしまいます。そこで、WordPress 側の __() 関数を定義している /public/wp/wp-includes/l10n.php
を先に読み込んでおきます。
ちなみに、/.env
ファイルはこんな感じ。
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_general_ci
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
# WordPressテーブル接頭辞
WP_TABLE_PREFIX=wp_
# WordPress認証用ユニークキー(https://api.wordpress.org/secret-key/1.1/salt/ で作成したものを下に転記する)
WP_AUTH_KEY=
WP_SECURE_AUTH_KEY=
WP_LOGGED_IN_KEY=
WP_NONCE_KEY=
WP_AUTH_SALT=
WP_SECURE_AUTH_SALT=
WP_LOGGED_IN_SALT=
WP_NONCE_SALT=
Laravel Mix の利用
基本的には WordPress で管理するページのスタイルシートは WordPress のテーマファイルで設定すればよいのですが、Laravel 側で使用している CSS を流用したいこともあると思います。Laravel Mix を使って CSS や JS をコンパイルし、キャッシュ対策のためにバージョン付けをしている場合、Laravel 内であれば、blade テンプレート内で {{ mix('/js/app.js') }}
のように書けば、バージョン付きのパスに自動的に変換してくれますが、WordPress ではそうはいきません。そこで、mix 関数と互換性がある wp_mix 関数を定義します。テーマファイル内の function.php に以下のコードを追加してください。
function wp_mix($path) {
$mix_manifest = WWW_ROOT . 'mix-manifest.json';
$json = file_get_contents($mix_manifest);
$decoded_json = json_decode($json, true);
echo $decoded_json[$path];
}
これで、WordPress のテンプレートファイル内で
<link rel="stylesheet" type="text/css" href="<?php wp_mix('/css/app.css'); ?>">
のように記述することで、バージョン付きのパスが取得できます。
ディスカッション
コメント一覧
まだ、コメントがありません