WEBLOG

WordPress > 標準設定

WordPress テンプレートでパンくずと構造化マークアップを設定値から自動生成

Create:

Category:WordPress標準設定

[ Version.21 ]

とあるプロジェクトのWEBミーディングで

クライアント様、制作会社(弊社)、SEOコンサルタント会社様が一同に会し、オンラインミーティングを行った時の事。

構造化マークアップは、SEOにおいて重要度が増しているらしく、下記の指摘がありました。

  • パンくずリストと構造化マークアップ内 BreadcrumbList のページ名称は同一にする。
  • 商品詳細ページには、商品詳細ページの記述を。
  • Q&Aページには、Q&Aページの記述を。

全てのテンプレートファイルにjsonを記述するのは、非効率で管理も煩雑になるため仕組化。

各テーマファイルに設定を記述

Frameクラス(後述)のインスタンス作成

$Frame = new Frame();

全ページ(パンくず)

$Frame->breadcrumbs = [
	'/' => 'HOME',
	'/blog/' => 'ブログ',
	'current' => '現在の記事名',
];

設定値 $breadcrumbs は配列で、キーにリンクパスを記述します。

商品詳細ページ

$obj = (object) [];
$post = $wp_single_post;
$obj->type = 'product';
$obj->image = $post->acf_pic ?? '';
$obj->name = $post->post_title ?? '';
$obj->url = $post->permalink;
$obj->description = $post->acf_texts_raw;
$obj->low_price = 0;
$obj->high_price = 999999;
$obj->is_stock = $post->acf_is_stock;
$obj->specs = [];
foreach ($post->acf_specs as $spec) {
	$obj->specs[] = (object) [
		'name' => $spec->dt,
		'value' => $spec->dd_raw,
	];
}
$Frame->add_structured = $obj;

上記は、$post に商品詳細ページの基本情報やACFの情報が入っているという前提です。

商品詳細ページには、オブジェクト形式でそれぞれの値を記述します。

Q&Aページ

$obj = (object) [];
$obj->type = 'faq';
$obj->faqs = [];
foreach ($wp_archive_posts as $post) {
	$obj->faqs[] = (object) [
		'q' => $post->post_title,
		'a' => $post->faq_a,
	];
}
$Frame->add_structured[] = $obj;

Q&Aページも、商品詳細ページと同様です。

設定値をもとにjson生成

実際のクラスファイルはもっと長いのですが、今回関係する箇所だけを抜粋表示しています。

class Frame
{
	public $breadcrumbs = [];
	public $add_structureds = [];


	// head_parts
	const tb = "\t";

	private function structuredJson()
	{
		$tag = '';
		$structureds = [];
		if (is_home()) {
			foreach (STRUCTURED_DATA as $v) {
				$structureds[] = [
					'@context' => 'https://schema.org',
					'@type' => 'Organization',
					'name' => $v['name'],
					'address' => [
						'postalCode' => $v['postalCode'] ?? '',
						'streetAddress' => $v['streetAddress'] ?? '',
						'addressLocality' => $v['addressLocality'] ?? '',
						'addressRegion' => $v['addressRegion'] ?? '',
					],
					'telephone' => $v['telephone'] ?? '-',
				];
			}
		} elseif (isset($this->breadcrumbs) && function_exists('home_url')) {
			$breadcrumb_lists = [];
			$count = 1;
			foreach ($this->breadcrumbs as $k => $v) {
				if (preg_match('/^htttp/', $k)) {
					$uri = $k;
				} elseif ($k === 'current') {
					$uri = ($_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
				} else {
					$uri = home_url($k);
				}
				$breadcrumb_lists[] = [
					'@type' => 'ListItem',
					'position' => $count,
					'name' => $pagename,
					'item' => $uri,
				];
				$count++;
			}
			$structureds[] = [
				'@context' => 'https://schema.org',
				'@type' => 'BreadcrumbList',
				'itemListElement' => $breadcrumb_lists,
			];
		}
		if ($this->add_structureds) {
			foreach ($this->add_structureds as $structured) {
				if (isset($structured->type) && $structured->type === 'product') {
					$offers['@type'] = 'AggregateOffer';
					$offers['priceCurrency'] = 'JPY';
					if (isset($structured->low_price) && $structured->low_price) {
						$offers['low_price'] = $structured->low_price;
					}
					if (isset($structured->high_price) && $structured->high_price) {
						$offers['high_price'] = $structured->high_price;
					}
					$additional_property = [];
					if (isset($structured->specs) && $structured->specs) {
						foreach ($structured->specs as $i => $spec) {
							$additional_property[] = [
								'@type' => 'PropertyValue',
								'name' => $spec->name,
								'value' => $spec->value,
							];
						}
					}
					$structureds[] = [
						'@context' => 'https://schema.org',
						'@type' => 'Product',
						'image' => $structured->image ?? '',
						'name' => $structured->name ?? '',
						'url' => $structured->url ?? '',
						'description' => $structured->description ?? '',
						'offers' => $offers,
						'additionalProperty' => $additional_property,
					];
				} elseif (isset($structured->type) && $structured->type === 'faq') {
					$main_entity = [];
					if (isset($structured->faqs) && $structured->faqs) {
						foreach ($structured->faqs as $i => $faq) {
							$main_entity[] = [
								'@type' => 'Question',
								'name' => $faq->q,
								'acceptedAnswer' => [
									'@type' => 'Answer',
									'text' => $faq->a,
								],
							];
						}
					}
					$structureds[] = [
						'@context' => 'https://schema.org',
						'@type' => 'FAQPage',
						'mainEntity' => $main_entity,
					];
				}
			}
		}
		$structureds = json_encode($structureds, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
		$structureds = explode("\n", $structureds);
		// tag
		$tag .= self::tb . '' . '<script type="application/ld+json">' . "\n";
		foreach ($structureds as $v) {
			$tag .= self::tb . "\t" . $v . "\n";
		}
		$tag .= self::tb . '' . '</script>' . "\n";
	return $tag;
	}
}

フッターやヘッダーの必要な箇所に出力

echo $Frame->structuredJson();

ブログ用にコードを修正していますが、コピペでも使用できると思います。

pagetop
loading