WordPressのテンプレートの中で必ず目にする、wp_head()とwp_footer()がそれぞれなぜ必要で、それぞれ何をしているのか?について。
wp_head()とwp_footer()は、Wordpressのプラグインが正しく機能するために必要なファイル群を読み込むための関数。
2つあるのは、ファイルの種類によってHTMLの中で読み込むべき適切なタイミングが異なるため。例えば、ファーストビュー(ページを開いたときに最初に表示される領域)のレイアウトとなるスタイルシートはheadタグの中で最初に読み込む必要がある。
一方、javascriptなどを最初に記述してしまうとレンダリング(読み込み)処理が重くなりページの表示速度が下がってユーザビリティが下がってしまうため、body閉じタグの直前で読み込むのが一般的である。
WordPressの場合、ヘッダー部分はheader.phpに、フッター部分はfooter.phpのように分けられているため、それぞれに合わせて、wp_head()とwp_footer()の2つが用意されている。
なお、Wordpressではこの関数をプラグイン API フックと呼ぶ。ざっくりいうと、プラグインを読み込むための必要なデータを読み込む(API)ためのコードを挿入する(フック)という意味。
wp_head()の使い方と内容
header.phpの中のhead内に記述する。phpの関数なので、<?php wp_head() ?>として記述する。
▼header.phpの記述例
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<?php wp_head() ?>
</head>
<body>
<?php wp_head() ?>で呼び出される内容は以下になる。
<meta name='robots' content='max-image-preview:large' />
<link rel='dns-prefetch' href='//s.w.org' />
<script type="text/javascript">
window._wpemojiSettings = {"baseUrl":"https:\/\/s.w.org\/images\/core\/emoji\/13.0.1\/72x72\/","ext":".png","svgUrl":"https:\/\/s.w.org\/images\/core\/emoji\/13.0.1\/svg\/","svgExt":".svg","source":{"concatemoji":"http:\/\/localhost:10091\/wp-includes\/js\/wp-emoji-release.min.js?ver=5.7.1"}};
!function(e,a,t){var n,r,o,i=a.createElement("canvas"),p=i.getContext&&i.getContext("2d");function s(e,t){var a=String.fromCharCode;p.clearRect(0,0,i.width,i.height),p.fillText(a.apply(this,e),0,0);e=i.toDataURL();return p.clearRect(0,0,i.width,i.height),p.fillText(a.apply(this,t),0,0),e===i.toDataURL()}function c(e){var t=a.createElement("script");t.src=e,t.defer=t.type="text/javascript",a.getElementsByTagName("head")[0].appendChild(t)}for(o=Array("flag","emoji"),t.supports={everything:!0,everythingExceptFlag:!0},r=0;r<o.length;r++)t.supports[o[r]]=function(e){if(!p||!p.fillText)return!1;switch(p.textBaseline="top",p.font="600 32px Arial",e){case"flag":return s([127987,65039,8205,9895,65039],[127987,65039,8203,9895,65039])?!1:!s([55356,56826,55356,56819],[55356,56826,8203,55356,56819])&&!s([55356,57332,56128,56423,56128,56418,56128,56421,56128,56430,56128,56423,56128,56447],[55356,57332,8203,56128,56423,8203,56128,56418,8203,56128,56421,8203,56128,56430,8203,56128,56423,8203,56128,56447]);case"emoji":return!s([55357,56424,8205,55356,57212],[55357,56424,8203,55356,57212])}return!1}(o[r]),t.supports.everything=t.supports.everything&&t.supports[o[r]],"flag"!==o[r]&&(t.supports.everythingExceptFlag=t.supports.everythingExceptFlag&&t.supports[o[r]]);t.supports.everythingExceptFlag=t.supports.everythingExceptFlag&&!t.supports.flag,t.DOMReady=!1,t.readyCallback=function(){t.DOMReady=!0},t.supports.everything||(n=function(){t.readyCallback()},a.addEventListener?(a.addEventListener("DOMContentLoaded",n,!1),e.addEventListener("load",n,!1)):(e.attachEvent("onload",n),a.attachEvent("onreadystatechange",function(){"complete"===a.readyState&&t.readyCallback()})),(n=t.source||{}).concatemoji?c(n.concatemoji):n.wpemoji&&n.twemoji&&(c(n.twemoji),c(n.wpemoji)))}(window,document,window._wpemojiSettings);
</script>
<style type="text/css">
img.wp-smiley,
img.emoji {
display: inline !important;
border: none !important;
box-shadow: none !important;
height: 1em !important;
width: 1em !important;
margin: 0 .07em !important;
vertical-align: -0.1em !important;
background: none !important;
padding: 0 !important;
}
</style>
<link rel='stylesheet' id='dashicons-css' href='http://localhost:10091/wp-includes/css/dashicons.min.css?ver=5.7.1' type='text/css' media='all' />
<link rel='stylesheet' id='admin-bar-css' href='http://localhost:10091/wp-includes/css/admin-bar.min.css?ver=5.7.1' type='text/css' media='all' />
<link rel='stylesheet' id='wp-block-library-css' href='http://localhost:10091/wp-includes/css/dist/block-library/style.min.css?ver=5.7.1' type='text/css' media='all' />
<link rel="https://api.w.org/" href="http://localhost:10091/wp-json/" /><link rel="alternate" type="application/json" href="http://localhost:10091/wp-json/wp/v2/pages/12" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://localhost:10091/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://localhost:10091/wp-includes/wlwmanifest.xml" />
<meta name="generator" content="WordPress 5.7.1" />
<link rel="canonical" href="http://localhost:10091/" />
<link rel='shortlink' href='http://localhost:10091/' />
<link rel="alternate" type="application/json+oembed" href="http://localhost:10091/wp-json/oembed/1.0/embed?url=http%3A%2F%2Flocalhost%3A10091%2F" />
<link rel="alternate" type="text/xml+oembed" href="http://localhost:10091/wp-json/oembed/1.0/embed?url=http%3A%2F%2Flocalhost%3A10091%2F&format=xml" />
<style type="text/css" media="print">#wpadminbar { display:none; }</style>
<style type="text/css" media="screen">
html { margin-top: 32px !important; }
* html body { margin-top: 32px !important; }
@media screen and ( max-width: 782px ) {
html { margin-top: 46px !important; }
* html body { margin-top: 46px !important; }
}
</style>
metaタグやlinkタグでスタイルシートが読み込まれる。
wp_footer()の使い方と内容
footer.phpの中のbody閉じタグ直前に記述する。phpの関数なので、<?php wp_footer() ?>として記述する。
▼header.phpの記述例
<footer>
<div>my-themeサイト</div>
</footer>
<?php wp_footer() ?>
</body>
</html>
<?php wp_footer() ?>で呼び出される内容は以下になる。
<script type='text/javascript' src='http://localhost:10091/wp-includes/js/hoverintent-js.min.js?ver=2.2.1' id='hoverintent-js-js'></script>
<script type='text/javascript' src='http://localhost:10091/wp-includes/js/admin-bar.min.js?ver=5.7.1' id='admin-bar-js'></script>
<script type='text/javascript' src='http://localhost:10091/wp-includes/js/wp-embed.min.js?ver=5.7.1' id='wp-embed-js'></script>
<script type="text/javascript">
(function() {
var request, b = document.body, c = 'className', cs = 'customize-support', rcs = new RegExp('(^|\\s+)(no-)?'+cs+'(\\s+|$)');
request = true;
b[c] = b[c].replace( rcs, ' ' );
// The customizer requires postMessage and CORS (if the site is cross domain).
b[c] += ( window.postMessage && request ? ' ' : ' no-' ) + cs;
}());
</script>
<div id="wpadminbar" class="nojq nojs">
<a class="screen-reader-shortcut" href="#wp-toolbar" tabindex="1">ツールバーへスキップ</a>
<div class="quicklinks" id="wp-toolbar" role="navigation" aria-label="ツールバー">
<ul id='wp-admin-bar-root-default' class="ab-top-menu"><li id='wp-admin-bar-wp-logo' class="menupop"><a class='ab-item' aria-haspopup="true" href='http://localhost:10091/wp-admin/about.php'><span class="ab-icon"></span><span class="screen-reader-text">WordPress について</span></a><div class="ab-sub-wrapper"><ul id='wp-admin-bar-wp-logo-default' class="ab-submenu"><li id='wp-admin-bar-about'><a class='ab-item' href='http://localhost:10091/wp-admin/about.php'>WordPress について</a></li></ul><ul id='wp-admin-bar-wp-logo-external' class="ab-sub-secondary ab-submenu"><li id='wp-admin-bar-wporg'><a class='ab-item' href='https://ja.wordpress.org/'>WordPress.org</a></li><li id='wp-admin-bar-documentation'><a class='ab-item' href='https://ja.wordpress.org/support/'>ドキュメンテーション</a></li><li id='wp-admin-bar-support-forums'><a class='ab-item' href='https://ja.wordpress.org/support/forums/'>サポート</a></li><li id='wp-admin-bar-feedback'><a class='ab-item' href='https://ja.wordpress.org/support/forum/feedback/'>フィードバック</a></li></ul></div></li><li id='wp-admin-bar-site-name' class="menupop"><a class='ab-item' aria-haspopup="true" href='http://localhost:10091/wp-admin/'>my-theme</a><div class="ab-sub-wrapper"><ul id='wp-admin-bar-site-name-default' class="ab-submenu"><li id='wp-admin-bar-dashboard'><a class='ab-item' href='http://localhost:10091/wp-admin/'>ダッシュボード</a></li></ul><ul id='wp-admin-bar-appearance' class="ab-submenu"><li id='wp-admin-bar-themes'><a class='ab-item' href='http://localhost:10091/wp-admin/themes.php'>テーマ</a></li></ul></div></li><li id='wp-admin-bar-customize' class="hide-if-no-customize"><a class='ab-item' href='http://localhost:10091/wp-admin/customize.php?url=http%3A%2F%2Flocalhost%3A10091%2F'>カスタマイズ</a></li><li id='wp-admin-bar-updates'><a class='ab-item' href='http://localhost:10091/wp-admin/update-core.php' title='翻訳の更新'><span class="ab-icon"></span><span class="ab-label">1</span><span class="screen-reader-text">翻訳の更新</span></a></li><li id='wp-admin-bar-comments'><a class='ab-item' href='http://localhost:10091/wp-admin/edit-comments.php'><span class="ab-icon"></span><span class="ab-label awaiting-mod pending-count count-0" aria-hidden="true">0</span><span class="screen-reader-text comments-in-moderation-text">0件のコメントが承認待ちです</span></a></li><li id='wp-admin-bar-new-content' class="menupop"><a class='ab-item' aria-haspopup="true" href='http://localhost:10091/wp-admin/post-new.php'><span class="ab-icon"></span><span class="ab-label">新規</span></a><div class="ab-sub-wrapper"><ul id='wp-admin-bar-new-content-default' class="ab-submenu"><li id='wp-admin-bar-new-post'><a class='ab-item' href='http://localhost:10091/wp-admin/post-new.php'>投稿</a></li><li id='wp-admin-bar-new-media'><a class='ab-item' href='http://localhost:10091/wp-admin/media-new.php'>メディア</a></li><li id='wp-admin-bar-new-page'><a class='ab-item' href='http://localhost:10091/wp-admin/post-new.php?post_type=page'>固定ページ</a></li><li id='wp-admin-bar-new-user'><a class='ab-item' href='http://localhost:10091/wp-admin/user-new.php'>ユーザー</a></li></ul></div></li><li id='wp-admin-bar-edit'><a class='ab-item' href='http://localhost:10091/wp-admin/post.php?post=12&action=edit'>固定ページを編集</a></li></ul><ul id='wp-admin-bar-top-secondary' class="ab-top-secondary ab-top-menu"><li id='wp-admin-bar-search' class="admin-bar-search"><div class="ab-item ab-empty-item" tabindex="-1"><form action="http://localhost:10091/" method="get" id="adminbarsearch"><input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" /><label for="adminbar-search" class="screen-reader-text">検索</label><input type="submit" class="adminbar-button" value="検索"/></form></div></li><li id='wp-admin-bar-my-account' class="menupop with-avatar"><a class='ab-item' aria-haspopup="true" href='http://localhost:10091/wp-admin/profile.php'>こんにちは、<span class="display-name">admin</span> さん<img alt='' src='http://0.gravatar.com/avatar/f2c4e662923c1bb99fe0527b2434eaa4?s=26&d=mm&r=g' srcset='http://0.gravatar.com/avatar/f2c4e662923c1bb99fe0527b2434eaa4?s=52&d=mm&r=g 2x' class='avatar avatar-26 photo' height='26' width='26' loading='lazy'/></a><div class="ab-sub-wrapper"><ul id='wp-admin-bar-user-actions' class="ab-submenu"><li id='wp-admin-bar-user-info'><a class='ab-item' tabindex="-1" href='http://localhost:10091/wp-admin/profile.php'><img alt='' src='http://0.gravatar.com/avatar/f2c4e662923c1bb99fe0527b2434eaa4?s=64&d=mm&r=g' srcset='http://0.gravatar.com/avatar/f2c4e662923c1bb99fe0527b2434eaa4?s=128&d=mm&r=g 2x' class='avatar avatar-64 photo' height='64' width='64' loading='lazy'/><span class='display-name'>admin</span></a></li><li id='wp-admin-bar-edit-profile'><a class='ab-item' href='http://localhost:10091/wp-admin/profile.php'>プロフィールを編集</a></li><li id='wp-admin-bar-logout'><a class='ab-item' href='http://localhost:10091/wp-login.php?action=logout&_wpnonce=67443c0857'>ログアウト</a></li></ul></div></li></ul> </div>
<a class="screen-reader-shortcut" href="http://localhost:10091/wp-login.php?action=logout&_wpnonce=67443c0857">ログアウト</a>
</div>
scritpタグでjsファイルや関数が読み込まれる。
なお、読み込まれる内容はインストールしているプラグインなどによっても異なる。
(参考)プラグイン API フック詳細
プラグインAPIフックの詳細および他の種類は以下で確認できる。
プラグインAPIフックとは?
テーマを作成する時、ユーザーがどの WordPress プラグインをインストールしても問題なく動くようにしておく必要があることを覚えておきましょう。プラグインは、アクションフックを通して WordPress に機能を追加します。 (詳しくはプラグイン API を参照してください)
アクションフックの多くは WordPress のコア PHP コードの中に書かれており、動作させるために特別なタグをテーマに記述する必要はありません。しかし、プラグインがヘッダー、フッター、サイドバー、もしくはページの本文に、情報を直接表示できるようにするためのアクションフックが幾つかあり、これらはテーマに記述されている必要があります。以下が含めるべきアクションフックテンプレートタグの一覧です。
https://wpdocs.osdn.jp/%E3%83%86%E3%83%BC%E3%83%9E%E3%81%AE%E4%BD%9C%E6%88%90