6.WordPressテーマのheadタグ内にSEO用のメタデータを追加する
検索エンジンのクローラーやSNSでの拡散時にサイトの情報を伝えるためには、metaデータを<head>内に適切に記述しておく必要があります。
metaデータできちんとサイトの情報をコントロールすることで、SEOにもSNS拡散にも大きな効果が期待できます。サイトの質を高めることができるので、テーマを作成する際は必ず記述しておきましょう。
今回は、WordPressの<head>内に記述しておきたいmetaデータの出力方法についてご紹介します。
metaデータとは!?
headタグ内に記述するmetaデータはユーザーに情報を伝えるためのものでなく、GoogleやFaceookなどのロボットにサイトの情報を適切に伝えるためのデータです。そのため、Webサイト上には直接表示されず、ソースコード上にのみ表示されます。
Googleや各SNSは、headタグの中に記述されたmetaデータを参照して、検索されたりシェアされたりしたときの出力を決定するものなので、直接Webサイト上では表示されませんが、ユーザーがサイトに興味を持ち訪問してもらうためにも必要不可欠なものだといえるでしょう。
今回出力する各metaデータの名前と説明
metaデータには様々な種類があり、それぞれ効果が違います。metaデータについて本記事で追加するものについてそれぞれご紹介します。
通常のmetaデータ
主に、検索エンジンやブラウザに情報を伝えるためのmetaデータです。
- title
- 現在のWEBページのタイトルを伝えるためのタグです。Googleなどの検索結果を初め、ブラウザのタブやブックマークした場合の名前にも出力されます。
- description
- 現在のWEBページの説明を示すテキスト情報を伝えるためのタグです。Googleなどの検索結果の説明欄に出力されます。
- keywords
- 現在のWEBページのキーワードを伝えるためのタグです。Googleでは、特に重要視されていないようですが、Google以外の検索エンジン対策に設定しておきます。
OGPタグ
OGPは『Open Graph Protcol』の略称で、主にSNS(FacebookやLINEなど)でシェアされたときに情報を伝えるための要素です。
- og:type
- ページの種類を伝えるためのタグです。
- og:locale
- Webページが対応している言語を指定するためのタグです。
- og:title
- <title>と同じようにページのタイトルを伝えるためのタグです。
- og:url
- WebページのURLを伝えるためのタグです。
- og:description
- 『name=”description”』と同じように、現在のWEBページの説明を示すテキスト情報を伝えるためのタグです。
- og:image
- 現在のWEBページに設定されているサムネイル画像(イメージ画像)を伝えるためのタグです。『og:image』で指定した画像が、SNSでシェアされた場合に出力されます。指定してない場合は、ページ内からランダムで出力されます。
- og:site_name
- サイトの名前を伝えるためのタグです。
実際にシェアすると下記のような感じで反映されます。
メタタグをheadタグに追加する
WordPressのようなCMSの場合は、ページによって出力する内容が変わるので、各ページに対応できるように条件分岐を行いながらmetaデータを出力していきます。
メタデータは、header.phpに直接記述しても良いのですが、メタデータのみを記述したファイルを作成し分けておいた方がわかりやすいため、作成中のWordPressテーマ内に『meta-data.php』というファイルを新たに作成しその中に記述します。
※『meta-data.php』を作成しない場合は、『header.php』の<head>の中に直接記述してください。
作成中のWordPressテーマ内に『meta-data.php』ファイルを追加したら、header.phpにテンプレートを呼び出す記述を追加しましょう。
header.phpの<head>タグ内に追加
(wp_head();の記述より前に追加してください。)
<?php get_template_part('meta-data'); ?>
投稿・固定ページ用のメタデータを変数に格納する
meta-data.phpに追加
<?php
$title = $description = $keywords = '';
if(is_single() && !is_home() || is_page() && !is_front_page()) {
//タイトル
$title = get_the_title();
//ディスクリプション
if(!empty($post->post_excerpt)) {
$description = str_replace(array("\r\n", "\r", "\n", " "), '', strip_tags($post->post_excerpt));
} elseif(!empty($post->post_content)) {
$description = str_replace(array("\r\n", "\r", "\n", " "), '', strip_tags($post->post_content));
$description_count = mb_strlen($description, 'utf8');
if($description_count > 120) {
$description = mb_substr($description, 0, 120, 'utf8').'…';
}
}
//キーワード
if(has_tag()) {
$tags = get_the_tags();
$kwds = array();
$i = 0;
foreach($tags as $tag) {
$kwds[] = $tag->name;
if($i === 4) {
break;
}
$i++;
}
$keywords = implode(',',$kwds);
}
//ページタイプ
$page_type = 'article';
//ページURL
$page_url = get_the_permalink();
//OGP用画像
if(!empty(get_post_thumbnail_id())) {
$ogp_img_data = wp_get_attachment_image_src(get_post_thumbnail_id(), 'full');
$ogp_img = $ogp_img_data[0];
}
}
投稿と固定ページのmetaデータの中に入れる要素は上記のようになります。
- $title
- 投稿や固定ページのタイトルは、Wordpress関数『get_the_title()』で取得できます。
- $description
- ディスクリプションは、投稿・固定ページの管理画面の『抜粋欄』に記述した内容、無い場合は『本文から120文字』を抜粋して取得します。
- 『抜粋欄』に記述した内容は、『$post->post_excerpt』で取得することができます。メタディスクリプションは、htmlタグや改行タグを除外して出力する必要があるためphp関数『strip_tags』でhtmlタグを除外し、改行も一緒にphp関数『str_replace』を使用して除外しておきましょう。
- 投稿や固定ページの『本文』は、『$post->post_post_content』で取得することができます。抜粋と同様にhtmlタグと改行タグを除外した後に、php関数『mb_strlen』で文字数を計測します。120文字より多い場合は、120文字で文字列をカットし最後に『…』を追加したものを格納しましょう。
- $keywords
- キーワードは、投稿に設定してあるタグを全て取得する処理を行い、カンマ区切りで5つだけを変数に格納します。また、タグが設定してない場合や固定ページの場合は、空欄になるよう条件分岐をしておきましょう。
- $page_type
- 投稿や固定ページは、記事を表す『article』を入れます。
- $page_url
- 投稿や固定ページのURLは、『get_the_permalink()』で取得します。
- $ogp_img
- OGP画像は、サムネイル(アイキャッチ)画像がある場合に、画像までのパス(URL)を挿入します。サムネイル画像の情報は、『wp_get_attachment_image_src(get_post_thumbnail_id(),’full’)』でサムネイル(アイキャッチ)画像の情報を配列で取得し、配列の中から取り出したURL情報を変数に格納します。
TOP・アーカイブページ用のメタデータを変数に格納する
投稿・固定ページ用のメタデータの直後に挿入する
else { //ループのページ(home・カテゴリー・タグなど)
//先に投稿・固定ページ以外の詳細な条件分岐
if(is_category()) {
$title = single_cat_title('', false).'の記事一覧';
if(!empty(category_description())) {
$description = strip_tags(category_description());
} else {
$description = 'カテゴリー『'.single_cat_title('', false).'』の記事一覧ページです。';
}
} elseif(is_tag()) {
$title = single_cat_title('', false).'の記事一覧';
if(!empty(tag_description())) {
$description = strip_tags(tag_description());
} else {
$description = 'タグ『'.single_cat_title('', false).'』の記事一覧ページです。';
}
} elseif(is_year()) {
$title = get_the_time('Y年').'の記事一覧';
$description = '『'.get_the_time('Y年').'』に投稿された記事の一覧ページです。';//指定したい場合は個別に入力
} elseif(is_month()) {
$title = get_the_time('Y年n月').'の記事一覧';
$description = '『'.get_the_time('Y年m月').'』に投稿された記事の一覧ページです。';//指定したい場合は個別に入力
} elseif(is_day()) {
$title = get_the_time('Y年n月j日').'の記事一覧';
$description = '『'.get_the_time('Y年n月j日').'』に投稿された記事の一覧ページです。';//指定したい場合は個別に入力
} elseif(is_author()) {
$author_id = get_query_var('author');
$author_name = get_the_author_meta('display_name', $author_id);
$title = $author_name.'が投稿した記事一覧';
$description = '『'.$author_name.'』が書いた記事の一覧ページです。';
} else {
$description = get_bloginfo('description');
}
//キーワード
$allcats = get_categories();
if(!empty($allcats)) {
$kwds = array();
$i = 0;
foreach($allcats as $allcat) {
$kwds[] = $allcat->name;
if($i === 4) {
break;
}
$i++;
}
$keywords = implode(',', $kwds);
}
//ページタイプ
$page_type = 'website';
//ページURL
$http = is_ssl() ? 'https'.'://' : 'http'.'://';
$page_url = $http.$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
} //条件分岐終了
//OGP用画像
if(empty($ogp_img)) {
$ogp_img = get_template_directory_uri().'/images/ogp_img.jpg'; //サイト全てに共通の画像へのパス
}
//タイトル
if(!empty($title)) {
$output_title = $title.' | '.get_bloginfo('name');
} else {
$title = get_bloginfo('name');
$output_title = get_bloginfo('name');
}
?>
TOPページとアーカイブページのmetaデータの中に入れる要素は上記のようになります。タイトルやディスクリプションは、各アーカイブページごとに適切に出力されるように、条件分岐を行い細かく指定しましょう。
- $title
- タイトルは、各アーカイブページごとに条件分岐を行い、『表示している投稿の種類 + の記事一覧』という文言を格納します。『の記事一覧』の部分は、自分の好きな文言に変更してください。
- $description
- ディスクリプションは、各アーカイブページごとに条件分岐を行います。カテゴリーページとタグページは、『管理画面 > 投稿 > カテゴリーまたはタグ > 説明』に記述した内容、カテゴリ・タグの説明がないときやそれ以外のページでは『表示している投稿の種類 + 指定した文言』を格納します。
- $keywords
- キーワードは、サイトに設定しているカテゴリーを全て取得する処理を行い、カンマ区切りで5つ変数に格納します。また、カテゴリーを設定してない場合や固定ページの場合は、空欄になるよう条件分岐をしておきましょう。
- $page_type
- TOPページやアーカイブページは、WEBサイトであることを表す『website』を入れます。
- $page_url
- ページのURLは、PHPで現在のURLを取得して格納します。
- $ogp_img
- 画像は、すべての条件分岐が終了した後(条件分岐の閉じタグの後)に記述します。『if(empty($ogp_img)) { ~ } 』という条件分岐を追加し、今までの条件分岐の中で画像($ogp_img)に値が格納されていない場合に、サイト全体に共通するサムネイル画像を格納するようにします。
- $output_title
- <title>タグに挿入するタイトルを$titleとは別に、$output_titleという変数を作成して値を格納します。
- 『if(!empty($title)) {~} else {~}』という条件分岐を追加し、変数($title)に値がある場合は『ページのタイトル | サイトタイトル』、ない場合は『サイトタイトル | サイトのディスクリプション』という形になるように値を作成しましょう。
- 同時に、$titleが空の場合は、$titleにサイトタイトルを格納するように『$title = get_bloginfo(‘name’);』を追加してください。
変数に格納したメタデータを出力する
上記の記述では、metaデータを変数に格納しただけなのでまだソースコード上では出力されません。格納した変数を出力するための処理を、上記で記述した条件分岐の下に追加しましょう。
header.phpのmetaデータを変数に格納する処理の下に追加
<title><?php echo $output_title; ?></title>
<meta name="description" content="<?php echo $description; ?>">
<meta name="keywords" content="<?php echo $keywords; ?>">
<meta property="og:type" content="<?php echo $page_type; ?>">
<meta property="og:locale" content="ja_JP">
<meta property="og:title" content="<?php echo $title; ?>">
<meta property="og:url" content="<?php echo $page_url; ?>">
<meta property="og:description" content="<?php echo $description; ?>">
<meta property="og:image" content="<?php echo $ogp_img; ?>">
<meta property="og:site_name" content="<?php bloginfo('name'); ?>">
prefixを設定する
SNS用のOGPタグを適切に出力するためには、prefixを記述しておく必要があります。無くても大丈夫らしいのですが、念のために記述しておきましょう。prefixは、headタグの開始タグに組み込みます。
header.phpの<head>に追記
<head prefix="og: http://ogp.me/ns#">
noindexの設定を行う
noindexとは、Googleなどの検索エンジンに対して「このページは登録しなくても大丈夫です」と伝えることができる設定です。検索エンジンに登録されないだけで、クローラーの巡回は通常通り行われます。
WordPressなどのCMSを使ってサイトを作成した場合、トップページやカテゴリページ・タグページ・アーカイブページ・検索ページなどのページが自動生成されます。(主にindex.phpベースのページです。)
Googleからは、WordPressなどのCMSによる自動生成コンテンツは適切に処理するとアナウンスされてはいますが、万が一を考え自動生成ページが重複コンテンツとして扱われ、サイトの評価を防ぐために『noindex』の設定を適切に行っておきましょう。
今回は、『タグページ』『アーカイブページ』『検索結果ページ』『404ページ』の4つのページをnoindexとして処理します。カテゴリページに関しては賛否両論ありますが、noindexにせずそのままにしておきます。
meta-data.phpに記述
<?php if(is_tag() || is_date() || is_search() || is_404()): ?>
<meta name="robots" content="noindex">
<?php endif; ?>
上記の記述は『if(is_tag() || is_archive())』のように論理演算子『 || 』でまとめどれかがtrueの場合に実行されるようにします。
上記の書き方ではなく、『if』『elseif』を使って一つ一つ条件分岐をしても問題ありません。
noindexと一緒にnofollow()も追加して『<meta name=”robots” content=”noindex,nofollow”>』とすると、リンクをクローラーが巡回しないようにすることもできます。ページ内のリンクも巡回しなくなってしまうので今回は設定していませんが、状況に応じて使い分けてください。
ページごとの条件分岐について
headタグ内では、各ページごとの出力について条件分岐をして切り分けます。WordPressでは、現在のページの種類を判別するための関数が設定されているため、それを使って条件分岐を行います。
各ページごとに判別するための関数は下記の通りです。
TOPページ
<?php if(is_home() || is_front_page()) { ~ } ?>
投稿
<?php if(is_single()) { ~ } ?>
固定ページ
<?php if(is_page()) { ~ } ?>
アーカイブ
<?php if(is_archive()) { ~ } ?>
カテゴリ一覧
<?php if(is_category()) { ~ } ?>
タグ
<?php if(is_tag()) { ~ } ?>
年,月,日,時間
<?php if(is_date()) { ~ } ?>
検索結果
<?php if(is_search()) { ~ } ?>
404
<?php if(is_404()) { ~ } ?>
メタタグの出力を確認する
上記をheadタグ内に追加したら、metaタグかheadタグ内にきちんと出力されているかをブラウザで確認してみましょう。
metaタグはデベロッパーツールでもチェックすることができますが、ブラウザ上で右クリック → ページのソースを表示(Chormeの場合)でチェックすると見やすいかと思います。
条件分岐している各ページを確認し、意図した通りに出力されているかを確認してください。metaタグの出力チェックが完了したら、FacebookデバッカーでOGPタグの内容がきちんと反映されるか確認しましょう。
Facebookデバッカーは、サイトがローカル環境にある場合は使用できません。必ず本番環境でチェックしてください。
Facebookデバッカーに接続したら、ブログ内の適当なページのURLを入力してください。
上記の画像のように、OGPタグがきちんと反映されていれば問題なく認識されています。
修正が必要な問題と出力された場合は?
facebookデバッカーでチェックすると下記のように出てきます。
プロパティ『fb:app_id』は指定しなくても、問題なくページはOGPタグで設定した内容でページはシェアされます。
『fb:app_id』を指定すると「Facebookインサイト」というGoogle AnaylticsのようなFacebookの計測ツールを使用できるようになります。
Facebookインサイトを使用しない場合は、上記の警告は無視しても大丈夫です。使用したい場合は、『Facebookデベロッパー』からアプリIDを取得してメタデータを追加してください。
X(Twitter)カードのOGPタグの設定を行う
Twitterカードを使用するには、基本的な情報はOGPからのデータを読み込みますが、Twitterカード専用の記述を追加する必要があります。
header.phpのheadタグ内のmetaデータを出力する箇所の後に記述
<meta name="twitter:site" content="@Xのユーザー名">
<meta name="twitter:card" content="summary">
<meta name="twitter:creator" content="@Xのユーザー名">
<meta name="twitter:description" content="<?php echo $description; ?>">
<meta name="twitter:image:src" content="<?php echo $ogp_img; ?>">
上記の5行をopgタグを出力するための記述の後に追加しましょう。『@Xのユーザー名』には、Xカードとして出力したいサイトのtwitterのユーザー名を入力してください。
headタグ内への記述が完了したら、Twitterカードを利用するためにサイト申請を行い承認を受ける必要があります。
Twitterカードの申請は、サイトがローカル環境にある場合は使用できません。必ず本番環境でチェックしてください。
上記のサイトにアクセスしたらURLの入力画面が表示されますので、Twitterカードの申請を行います。
サイト内の適当な投稿ページのURLを入力し『Preview card』をクリックして確認しましょう。
無事に登録されれば、上記のように右側のLOGに『Card loaded successfully』と出力されたらTwitterカードの設定は終了です。
Card Validator からプレビュー機能は削除されたようです。プレビューを確認したい場合は、Tweet Composerを利用してください。
ファビコンの設定を行う
ファビコン(ブラウザのタブに表示されるアイコン)の設定をすることでサイトが印象に残りやすくなり、サイトのブランド力や認知度の向上が期待できます。
WordPressの管理画面からも設定できますが、一部反映されない場合があるようなので、テーマ側で設定しておくことをオススメします。
ファビコン用の画像を作成する
ファビコン(ブラウザのタブに表示されるアイコン)は、ウェブクリップアイコンをベースにアイコン画像(.ico)に変換して作成します。icoという拡張子に対応しているソフトは少ないため、今回はWebサイトを使ってWEB上で変換します。
アイコンコンバータにアクセスしたら、先程作成した正方形の画像を選択し『変換』ボタンをクリックしてください。
変換が完了したら変換された画像が一覧で表示されますので、アイコン形式一覧の画像の『Pixel : 32 x 32』サイズの画像を『Download』ボタンより保存しましょう。
保存するときは、ファイルの名前を『favicon.ico』という名前に変更して保存してください。
※保存後に変更でも可
ファビコンをテーマに反映する
まず、作成した『favicon.ico』画像をWordPress上にアップロードします。
デモでは、WordPressテーマの中の『images』フォルダ内アップロードしていますが、WordPressテーマフォルダの中であればどちらでも構いません。自分の管理しやすい場所にアップロードしてください。
画像のアップロードが完了したら、headタグ内にスマホのアイコン用の記述を行います。
meta-data.phpに記述
<link rel="shortcut icon" href="<?php echo get_template_directory_uri(); ?>/images/favicon.ico">
headタグ内に記述したら、設定は完了です。
上記の画像のようにブラウザのタブにファビコンが出力されたかを確認しましょう。
meta-data.phpの記述サンプル
meta-data.php内の記述は、少々複雑な部分も多くわかりずらい箇所もあったかと思いますので、下記にサンプルコードを記述しておきます。ぜひ参考にしてください。
<?php
$title = $description = $keywords = '';
if(is_single() && !is_home() || is_page() && !is_front_page()) {
//タイトル
$title = get_the_title();
//ディスクリプション
if(!empty($post->post_excerpt)) {
$description = str_replace(array("\r\n", "\r", "\n", " "), '', strip_tags($post->post_excerpt));
} elseif(!empty($post->post_content)) {
$description = str_replace(array("\r\n", "\r", "\n", " "), '', strip_tags($post->post_content));
$description_count = mb_strlen($description, 'utf8');
if($description_count > 120) {
$description = mb_substr($description, 0, 120, 'utf8').'…';
}
}
//キーワード
if(has_tag()) {
$tags = get_the_tags();
$kwds = array();
$i = 0;
foreach($tags as $tag) {
$kwds[] = $tag->name;
if($i === 4) {
break;
}
$i++;
}
$keywords = implode(',',$kwds);
}
//ページタイプ
$page_type = 'article';
//ページURL
$page_url = get_the_permalink();
//OGP用画像
if(!empty(get_post_thumbnail_id())) {
$ogp_img_data = wp_get_attachment_image_src(get_post_thumbnail_id(), 'full');
$ogp_img = $ogp_img_data[0];
}
} else { //ループのページ(home・カテゴリー・タグなど)
//先に投稿・固定ページ以外の詳細な条件分岐
if(is_category()) {
$title = single_cat_title('', false).'の記事一覧';
if(!empty(category_description())) {
$description = strip_tags(category_description());
} else {
$description = 'カテゴリー『'.single_cat_title('', false).'』の記事一覧ページです。';
}
} elseif(is_tag()) {
$title = single_cat_title('', false).'の記事一覧';
if(!empty(tag_description())) {
$description = strip_tags(tag_description());
} else {
$description = 'タグ『'.single_cat_title('', false).'』の記事一覧ページです。';
}
} elseif(is_year()) {
$title = get_the_time('Y年').'の記事一覧';
$description = '『'.get_the_time('Y年').'』に投稿された記事の一覧ページです。';//指定したい場合は個別に入力
} elseif(is_month()) {
$title = get_the_time('Y年n月').'の記事一覧';
$description = '『'.get_the_time('Y年m月').'』に投稿された記事の一覧ページです。';//指定したい場合は個別に入力
} elseif(is_day()) {
$title = get_the_time('Y年n月j日').'の記事一覧';
$description = '『'.get_the_time('Y年n月j日').'』に投稿された記事の一覧ページです。';//指定したい場合は個別に入力
} elseif(is_author()) {
$author_id = get_query_var('author');
$author_name = get_the_author_meta('display_name', $author_id);
$title = $author_name.'が投稿した記事一覧';
$description = '『'.$author_name.'』が書いた記事の一覧ページです。';
} else {
$description = get_bloginfo('description');
}
//キーワード
$allcats = get_categories();
if(!empty($allcats)) {
$kwds = array();
$i = 0;
foreach($allcats as $allcat) {
$kwds[] = $allcat->name;
if($i === 4) {
break;
}
$i++;
}
$keywords = implode(',', $kwds);
}
//ページタイプ
$page_type = 'website';
//ページURL
$http = is_ssl() ? 'https'.'://' : 'http'.'://';
$page_url = $http.$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
}
//OGP用画像
if(empty($ogp_img)) {
$ogp_img = get_template_directory_uri().'/images/ogp_img.jpg'; //サイト全てに共通の画像へのパス
}
//タイトル
if(!empty($title)) {
$output_title = $title.' | '.get_bloginfo('name');
} else {
$title = get_bloginfo('name');
$output_title = get_bloginfo('name');
}
?>
<title><?php echo $output_title; ?></title>
<meta name="description" content="<?php echo $description; ?>">
<meta name="keywords" content="<?php echo $keywords; ?>">
<meta property="og:type" content="<?php echo $page_type; ?>">
<meta property="og:locale" content="ja_JP">
<meta property="og:title" content="<?php echo $title; ?>">
<meta property="og:url" content="<?php echo $page_url; ?>">
<meta property="og:description" content="<?php echo $description; ?>">
<meta property="og:image" content="<?php echo $ogp_img; ?>">
<meta property="og:site_name" content="<?php bloginfo('name'); ?>">
<?php if(is_tag() || is_date() || is_search() || is_404()): ?>
<meta name="robots" content="noindex">
<?php endif; ?>
<link rel="shortcut icon" href="<?php echo get_template_directory_uri(); ?>/images/favicon.ico">
今回記述したもの以外にも、必要性に合わせてheadタグ内にデータを追加していき、ロボットに適切な情報を伝えることでサイトの上位表示に繋げましょう。
以上で、WordPressテーマ作成のデモテーマの作成は完了です。テーマに追加する機能については『WPカスタマイズ』カテゴリで紹介しています。新たな機能をWordPressに追加したいときに覗いてみてください。
作成したテーマをベースに自分好みな機能やデザインを追加して、自分好みのWordPressテーマにカスタマイズしてください!
下記より記事で作成したところまでのテーマファイルを下記よりダウンロードできます。