get_template_directory_uri と get_stylesheet_directory_uri の違い|子テーマでの使い分け

結論

子テーマを使っているサイトで、URL を取得する関数を間違えると、「画像が出ない」「CSS が 404」になります。使い分けは次のとおりです。

関数 返すもの 子テーマ使用時
get_template_directory_uri() 親テーマ(template)の URL 常に親テーマ
get_stylesheet_directory_uri() 有効なテーマ(stylesheet)の URL 子テーマ
get_theme_file_uri( $file ) 子テーマにファイルがあれば子、無ければ親の URL 子 → 親の順に探す

迷ったら、get_theme_file_uri() と get_theme_file_path() を使います。子テーマで上書きされたファイルも、自動で正しい側を指します。親テーマ側のファイルを必ず指したいとき(親の style.css を読み込む等)だけ、get_template_directory_uri() を使います。

原因・仕組み

WordPress のテーマには、template(親テーマのディレクトリ名)と stylesheet(有効なテーマのディレクトリ名)の2つの設定があります。親テーマ単体で使っている場合は同じ値、子テーマを有効にしている場合は異なる値になります。get_template_directory_uri() は前者、get_stylesheet_directory_uri() は後者を基準にします。公式リファレンスにも、子テーマの URL が欲しいときは get_stylesheet_directory_uri() を使う旨と、末尾にスラッシュが付かない旨が記載されています。また、get_theme_file_uri() は 4.7.0 で追加され、子テーマと親テーマを考慮して URL を返します。

手順(サンプルコード)

add_action( 'wp_enqueue_scripts', function () {
    // 親テーマの CSS(親の style.css を読む)
    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css', array(), null );
    // 子テーマの CSS(子の style.css)
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array( 'parent-style' ), null );
    // 子で上書きできる画像・JS はこちらが安全
    wp_enqueue_script( 'ks-app', get_theme_file_uri( 'js/app.js' ), array(), '1.0', true );
} );

// テンプレート内の画像
printf( '<img src="%s" alt="">', esc_url( get_theme_file_uri( 'images/logo.png' ) ) );

パス(include 用)は、URL とは別の関数です。get_template_directory()、get_stylesheet_directory()、get_theme_file_path() を、同じ考え方で使い分けます。URL をファイル読み込み(include)に使ってはいけません。

動作確認(検証環境と結果)

WordPress 7.1.2、PHP 8.2.12 で、DB を変更せず、pre_option_template / pre_option_stylesheet フィルターで「親 = twentytwentyfive、子 = ks-child」を擬似的に再現しました(php C:Tempwp-testrun.php template-directory-uri-vs-stylesheet-directory-uri.php)。

  • get_template_directory_uri(): http://localhost/wp-content/themes/twentytwentyfive
  • get_stylesheet_directory_uri(): http://localhost/wp-content/themes/ks-child
  • get_template_directory() と get_stylesheet_directory() は、同様に親・子のディレクトリを返した。
  • 子テーマのディレクトリが実在しない状態で get_theme_file_uri( 'assets/a.css' ) を呼ぶと、親テーマ側の URL を返した(子に無ければ親へフォールバック)。

続いて、pre_option_home を https://example.com、pre_option_siteurl を https://example.com/wp にして比較しました。

関数 結果
home_url( '/about/' ) https://example.com/about/
site_url( '/wp-login.php' ) http://example.com/wp/wp-login.php
admin_url() http://example.com/wp/wp-admin/
wp_login_url() http://example.com/wp/wp-login.php

site_url() 系で http になったのは、CLI 実行で is_ssl() が false のためです。wp-includes/link-template.php を読むと、get_site_url() はスキーム未指定のとき set_url_scheme() で is_ssl() に合わせる一方、get_home_url() は is_ssl() が false なら保存値のスキームを使う実装でした(検証環境 7.1.2 のソースで確認)。実際のサイトでは、設定の「WordPress アドレス」と「サイトアドレス」の両方を https で保存し、https でアクセスしてください。

プラグインの URL は、plugins_url( 'assets/app.js', WP_PLUGIN_DIR . '/ks-demo/ks-demo.php' ) が http://localhost/wp-content/plugins/ks-demo/assets/app.js、plugin_dir_url() が .../plugins/ks-demo/(末尾スラッシュ付き)を返しました。引数なしの plugins_url() は .../wp-content/plugins です。

get_template_directory_uri と get_stylesheet_directory_uri の違いの注意点

  • home_url() はサイトの公開 URL(訪問者がアクセスする場所)、site_url() は WordPress のコアファイルがある場所です。WordPress を /wp のサブディレクトリに置く構成では、両者が異なります。
  • URL を出力するときは esc_url()、属性やテキストには別のエスケープ関数を使います。
  • テーマ名のディレクトリを /wp-content/themes/ と直書きしないでください。WP_CONTENT_URL の変更や、ディレクトリ移動で壊れます。
  • プラグインの中では、__FILE__ を渡す plugins_url() か plugin_dir_url( __FILE__ ) を使うのが一般的です。
  • 親テーマのアップデートで、親側のファイルは上書きされます。子テーマ側に置いたファイルは残ります。

get_template_directory_uri と get_stylesheet_directory_uri の違いでよくあるミス

  • 子テーマで get_template_directory_uri() を使い、子テーマに置いた画像が表示されない。
  • URL と同じつもりで、include get_template_directory_uri() . '/x.php'; と書く。
  • home_url() の戻り値に、さらに / を付けて二重スラッシュになる。パスを渡す形(home_url( '/about/' ))を使う。
  • テーマ内で、http:// から始まる絶対 URL を直書きして、https 化で混在コンテンツになる。
  • 子テーマの style.css を、親の style.css の読み込み後に出さない。

get_template_directory_uri と get_stylesheet_directory_uri の違いのチェックリスト

  • 子テーマを使っているか確認したか。
  • 子で上書きする可能性があるファイルに、get_theme_file_uri() を使ったか。
  • include には、URL ではなくパスの関数を使ったか。
  • 出力に esc_url() を使ったか。
  • https 化後、WordPress アドレスとサイトアドレスの両方を確認したか。

get_template_directory_uri と get_stylesheet_directory_uri の違いのFAQ(よくある質問)

Q. 親テーマ単体のとき、どれを使っても同じですか。
A. 同じ結果になります。ただし、将来の子テーマ化に備えて、get_theme_file_uri() を使っておくと安全です。

Q. get_home_url と home_url の違いは?
A. home_url() は現在のサイトの get_home_url() を呼ぶ短縮形です。マルチサイトで別サイトの URL が欲しいときは get_home_url( $blog_id ) を使います(get_home_url() の使い方|説明・引数・注意点)。

Q. プラグインの CSS の URL は?
A. plugins_url( 'css/style.css', __FILE__ ) です(plugins_url() の使い方|説明・引数・注意点)。

筆者の見解(get_template_directory_uri と get_stylesheet_directory_uri の違い)

URL 関数の使い分けは、基準を1つ決めるだけで迷いが減ると考えます。私見では、テーマ内のアセットは原則として get_theme_file_uri()、親テーマを明示的に指す場合だけ get_template_directory_uri()、とルール化するのがよいです。さらに、サイトの URL は直書きせず、必ず関数から取得する習慣が、移設や https 化のときの手戻りを減らします。

get_template_directory_uri と get_stylesheet_directory_uri の違いの関連項目

出典(一次情報)

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