Laravelで作られたサイトのCSSを、WordPress側から読み込む方法

LaravelサイトのCSSを WPから動的に読み込む Laravel
※当サイトはアフィリエイト広告を掲載しています。

ベースがLaravelで作られたサイトに、WordPressでブログ機能を追加したい。これはよくある話です。

さらにサイトとブログをシームレスにしたい、つまり同一の外観(同じサイト)に見せたいこともたまにあります。

そんな時どうするかと言えば

  • 既存サイトのヘッダー・フッターのHTMLをコピー
  • Laravel(Vite)で作られたCSSをWordPressからも読み込む

……というのが、良くも悪くもてっとり早い方法です。別システムですからね。

そんな時、Laravel側の更新(build)が絡むとブログのデザインが崩れてしまう、という問題が発生します。

本ページでは、この問題の対策方法について考えてみたいと思います。これが最善かはわかりませんが、一例として参考になれば幸いです。

結論だけ知りたい方は、こちらを押してください。

Lara
Lara

非エンジニアのWordPress開発者の方もコピペで可能です。

問題が起こる方法をおさらい

まずは、問題が発生する可能性がある方法をおさらいしてみましょう。

header.phpからCSSを読み込む

Laravelで作られたサイトのHTMLソースを表示させ、ヘッダー部分からCSS等必要な箇所をheader.phpに貼り付けます。

言うまでもなく、bladeではなく出力後のHTMLです。

以下の例では、7-8行目で読み込んでいます。※7行目は無くても動きます。

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo( 'charset' ); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="profile" href="http://gmpg.org/xfn/11">
    <link rel="preload" as="style" href="/build/assets/app-xag6c3h5.css">
    <link rel="stylesheet" href="/build/assets/app-xag6c3h5.css">
    <link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>">
    <?php if ( is_singular() && pings_open( get_queried_object() ) ) : ?>
    <link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
    <?php endif; ?>
    <?php wp_head(); ?>
</head>

もちろんheader.phpに書かずとも、フックで読ませても良いと思います。

残りのHTMLを貼り付ける

後はfooter.phpsidebar.phpなど含め、サイトの共通部分(グローバルナビゲーションやフッター等)のHTMLを適所に貼り付けます。

これが最も簡単で安直な方法だと思います。

問題

この方法では、まるっと貼り付けただけで機能するので楽です。しかしながら、Laravelの修正が絡むととたんに厄介になります。

問題無く動作していたところ、忘れた頃に「ブログのデザインだけ崩れてるよ!」という連絡が入ることになるかもしれません。

一時的に問題無くとも、いつか冷や汗をかく可能性があるのがこの実装方法です。

Lara
Lara

こういう連絡はドキっとして嫌なものです。

何が悪い?

Laravel(Vite)でbuildすると、CSSのファイル名が変わってしまうからです。

こういうやつです→app-xag6c3h5.css

つまり最新のCSSを参照することができなくなるため、ブログ部分だけデザインの崩れが発生することがあります。

これはLaravel(Vite)がキャッシュを確実にクリアするためにしてくれているから(たぶん)。つまりご厚意でやってくれているのです。

ならCSSのパラメータを変えてくれるだけでも良いとも思いましたが。。もしかしたら、vite.config.jsをいじれば良い感じににもできるのかもしれません。……が、Viteはまだ詳しくはないので、とりあえず私は後述のPHPで対策しました。

その都度WordPressのheader.php(またはfunctions.php)を変更するのは超面倒臭い……。

ということで考えました。

manifest.jsonの情報からCSSを読む

どうにかならいかな、と何も検索せずに自分の頭で考えましたが、1つの方法を思いつきました。そういえばmanifest.jsonに、CSSの情報載ってるやん!と。

manifest.jsonの内容

public/build/manifest.jsonには、Viteでbuildした情報が載っています。以下の様に、12行目にありますね。これを取得すれば良さそうです。

// ~省略
  "public/img/example.jpg": {
    "file": "assets/example.jpg",
    "src": "public/img/example.jpg"
  },
  "resources/js/app.js": {
    "file": "assets/app-ce55534219.js",
    "isEntry": true,
    "src": "resources/js/app.js"
  },
  "resources/sass/app.scss": {
    "file": "assets/app-abcd2e93fg.css",
    "isEntry": true,
    "src": "resources/sass/app.scss"
  }
}

読み込む

PHPにはJSONを読み込むjson_decode()という便利な関数があります。

以下の様にWordPressのテーマのfunctions.phpに記述すれば、いとも簡単にmanifest.jsonを読み込めます。なんで思いつかなかったんだろうというほど、あっけないです。

function load_manifest_css() {
    // マニフェストファイルのパスを指定
    $manifest_path = realpath(__DIR__ . '/../../../../') .'/build/manifest.json';

    if(file_exists($manifest_path)) {
        $manifest = json_decode(file_get_contents($manifest_path), true);
        $app_css = isset($manifest['resources/sass/app.scss']['file']) ? $manifest['resources/sass/app.scss']['file'] : '';
        if($app_css) {
            wp_enqueue_style('app-css', get_template_directory_uri() . '/build/' . $app_css);
        }
    }
}
add_action('wp_enqueue_scripts', 'load_manifest_css');

一応、file_existsしていますが、このCSSが無いと致命的な場合、あえて判定しない方が処理速度的には良さそうです。

Lara
Lara

これだけで解決しました!

まとめ

ウェブサイトとブログを同じデザインにする……ということは、たまにあります。

通常のHTMLサイトなら、コピペで済ませてしまっても問題になることはそう多くありません。しかしLaravelを使用するなら、こういった対策が重要だなと改めて思いました。

本記事により、冷や汗を書く人が一人でも減れば幸いです。

コメント

タイトルとURLをコピーしました