PHP でパンくずリストを出力(JSON-LDも)
PHP でパンくずリストを出力する方法の覚書です。
以下では PHP を使って動的にパンくずリストや JSON-LD での構造化マークアップを出力したり、パンくずリストを外部ファイル化する例などを掲載しています。
WordPress でパンくずリストや JSON-LD の構造化マークアップを出力する方法は以下を御覧ください。
更新日:2022年03月11日
作成日:2021年6月5日
パンくずリストの出力
サイトのフォルダ構造をそのまま反映したパンくずリストを出力場合は、比較的簡単に動的にパンくずリストを出力することができます。
パンくずリストはサイトのフォルダ構造を反映させる必要はないので、フォルダ構造と異なる場合は、各ページごとに手動またはテンプレートなどを使って出力するのが簡単だと思います。
関連ページ:
パンくずリストを動的に出力
以下は PHP の環境変数 $_SERVER['SCRIPT_NAME'] を使って、サイトのフォルダ構造を反映したパンくずリストを動的に出力する例です。
$_SERVER['SCRIPT_NAME'] はそのページのドキュメントルートからのパスを返します($_SERVER)。
この例の場合、パンくずリストに表示される項目はディレクトリ名を単純に大文字に変換して表示し、現在のページの項目にはファイル名を表示するのであまり実用的ではありません。
Document Root (htdocs) ├── about // ABOUT(パンくずリストに表示されるラベル) │ └── index.php ├── contact //CONTACT │ └── index.php ├── index.php //HOME └── news //NEWS ├── index.php ├── news1.php //NEWS1.PHP ├── tech //TECH │ ├── index.php │ └── tech1.php //TECH1.PHP └── world //WORLD ├── index.php └── world1.php //WORLD1.PHP
リンクの URL はドキュメントルートからの絶対パスになります。
インデックスファイルの場合、最後の項目(index.php)はそのファイルのディレクトリと同じリンク先になるので index.php を表示しないようにしています。
例: HOME / NEWS / TECH / index.php (TECH と index.php のリンク先は同じ)
また、この場合、サイトがドキュメントルートにインストールされていることが前提です。
function breadcrumbs() {
//このスクリプトを実行しているページのホームディレクトリからのパス(ファイル名を含む)
$file_path = $_SERVER['SCRIPT_NAME'];
//ページのホームディレクトリからのパスをスラッシュで区切った値(ディレクトリ名)の配列。
$dirs = explode("/", $file_path); //1番目[0]は空。最後はファイル名。
//ディレクトリ名の配列(空の要素を削除)※
$dirs = array_values(array_filter($dirs,"strlen")); //または array_shift($dirs);
//パンくずリストのマークアップ(HOME 部分)
$html = '<a href="/">HOME</a>';;
//パンくずリストのリンク先 URL
$url = "";
//各ディレクトリ名ごとにリンクを付けたマークアップを生成
foreach($dirs as $dir){
$url .= "/".$dir;
//ファイルが index.php の場合はスキップ(ファイル名 index.php を表示しない)
if(strtolower($dir) !== 'index.php') {
//パンくずリストの項目はスラッシュ( / )で区切る(文字は大文字に変換)
$html .= " / "."<a href=".$url.">".strtoupper($dir)."</a>";
}
}
echo $html;
}
空の要素の削除(7行目)
$_SERVER['SCRIPT_NAME'] は / から始まるパスを返すので explode("/", $file_path) が返す最初の要素は空の要素にるため、7行目で空の要素を削除しています。
空の要素は先頭の要素なので、array_shift() でも大丈夫だと思いますが、この例では配列に含まれる空文字の要素を全て削除しています。
array_filter() の第2引数 strlen は文字列の長さを返す関数で空の文字列だった場合に 0 を返すので、配列から空の文字列の要素をフィルターできます。
array_values() で結果の配列のインデックスを振り直しています。
使い方
パンくずリストを表示するページで上記関数を記述したファイルを読み込み実行します。
include '../inc/vars.php';(上記関数を記述したファイル) <div class="breadcrumbs"><?php breadcrumbs(); ?></div>
表示例
| URL |
|---|
| http://example.com/news/tech/tech1.php(本番環境) |
| http://example.localhost/news/tech/tech1.php(バーチャルホストを設定したローカル環境) |
| パンくずリストに表示される文字 |
| HOME / NEWS / TECH / TECH1.PHP |
| 出力されるマークアップ(見やすいように改行しています) |
<a href="/">HOME</a> / <a href="/news">NEWS</a> / <a href="/news/tech">TECH</a> / <a href="/news/tech/news1.php">TECH1.PHP</a> href 属性の値はドキュメントルートからの絶対パスになっています |
バーチャルホストを設定していないローカル環境やルートディレクトリのサブディレクトリにインストールしている場合、Home はサーバーのドキュメントルート(htdocs など)になってしまいます。
サイトをドキュメントルート以外にインストールする場合の例は リンクを相対パス(URL)で出力 を御覧ください。
現在のページを非表示
パンくずリストでは、必ずしも表示されているページのリンクを表示する必要はありません。
以下は前述の関数 breadcrumbs() を変更して現在のページを表示しないようにする例です。
foreach 文を for 文に変更して、パスを分割した配列要素の最後の要素の場合にはファイル名を出力しないようにしています(ファイル名が index.php 以外の場合で)。
function breadcrumbs() {
$file_path = $_SERVER['SCRIPT_NAME'];
$dirs = explode("/", $file_path);
$dirs = array_values(array_filter($dirs,"strlen"));
$html = '<a href="/">HOME</a>';;
$url = "";
//以下を変更
for($i = 0; $i < count($dirs); $i++ ) {
$url .= "/".$dirs[$i];
if(strtolower($dirs[$i]) !== 'index.php') {
if($i === count($dirs) -1) {
//ファイル名は表示せず / のみを追加
$html .= " / ";
}else {
$html .= " / "."<a href=".$url.">".strtoupper($dirs[$i])."</a>";
}
}
}
echo $html;
}
ページのタイトルを表示
パンくずリストの現在のページの部分にファイル名ではなく、そのページのタイトルを表示する例です。
ページのタイトルは、それぞれのページの先頭などで定義しておく必要があります。以下の例では変数 $title にページのタイトルを設定しています。
<?php $title = 'Tech ニュース 1'; //ページのタイトルを定義(設定) include $path.'inc/vars.php'; //関数の記述されているファイルの読み込み include $path.'inc/head.php'; // head 部分の共通ファイルの読み込み(任意) ?> </head> <body> <div class="wrapper"> ・・・以下省略・・・
関数内から、各ページで定義されている $title にアクセスするにはグローバル変数としてアクセスする必要があるので、以下の例では $GLOBALS['title'] で $title にアクセスしています。
function breadcrumbs() {
$file_path = $_SERVER['SCRIPT_NAME'];
$dirs = explode("/", $file_path);
$dirs = array_values(array_filter($dirs,"strlen"));
$html = '<a href="/">HOME</a>';;
$url = "";
for($i = 0; $i < count($dirs); $i++ ) {
$url .= "/".$dirs[$i];
if(strtolower($dirs[$i]) !== 'index.php') {
if($i === count($dirs) -1) {
//それぞれのページに設定してある $title(ページのタイトル)を表示
$html .= " / " . $GLOBALS['title'];
}else {
$html .= " / "."<a href=".$url.">".strtoupper($dirs[$i])."</a>";
}
}
}
echo $html;
}
ディレクトリを指定した文字で表示
英語のページやインデックスページなどのタイトルを英語にしている場合は、今までの例の方法でも何とかなるかも知れませんが、日本語の場合はそれらの文字列を変換する必要があります。
例えば、以下のようなフォルダ構成で about ディレクトリでは ABOUT などではなく、「会社概要」と表示する場合です。
. ├── about //会社概要 │ └── index.php ├── contact //お問い合わせ │ └── index.php ├── index.php └── news //ニュース ├── index.php ├── news1.php ├── tech //テクノロジー │ ├── index.php │ └── tech1.php └── world //ワールド ├── index.php └── world1.php
以下はディレクトリ名をキー、表示する文字列を値とした配列を用意して、パンくずリストの項目を指定した文字列で表示する例です。
ディレクトリ名の代わりに表示する文字列へは、$dirs[$i](ディレクトリ名)をキーとして配列 $dir_titles から取得しています。
function breadcrumbs() {
$file_path = $_SERVER['SCRIPT_NAME'];
$dirs = explode("/", $file_path);
$dirs = array_values(array_filter($dirs,"strlen"));
//ホームの文字列(以下は HOME と表示)
$html = '<a href="/">HOME</a>';;
$url = "";
//ディレクトリ名の代わりに表示する文字列を指定した配列
$dir_titles = [
'about' => '会社案内',
'contact' => 'お問い合わせ',
'news' => 'ニュース',
'tech' => 'テクノロジー',
'world' => 'ワールド',
];
for($i = 0; $i < count($dirs); $i++ ) {
$url .= "/".$dirs[$i];
if(strtolower($dirs[$i]) !== 'index.php') {
if($i === count($dirs) -1) {
//それぞれのページに設定してある $title を表示
$html .= " / " . $GLOBALS['title'];
//以下はページのタイトルを表示しない場合
//$html .= " / ";
}else {
//$dir_titles から文字列を取得
$html .= " / "."<a href=".$url.">".$dir_titles[$dirs[$i]]."</a>";
}
}
}
echo $html;
}
例えば、上記の例の tech1.php(http://example.com/news/tech/tech1.php)でのパンくずリストは以下のように表示されます。
HOME / ニュース / テクノロジー / Tech ニュース 1
※ サイトに新しいディレクトリを追加した場合は、$dir_titles も更新(新しいディレクトリを追加)する必要があります。
マークアップの変更
今までの例ではパンくずリストの項目は単に a 要素でマークアップしていましたが、実際には ol 要素や ul 要素などでマークアップすることが多いと思います。
<ol class="breadcrumbs"> <li class="breadcrumb-item"><a href="/">HOME</a></li> <li class="breadcrumb-item"><a href="/news/">ニュース</a></li> <li class="breadcrumb-item active" aria-current="page">ニュース 1</li> </ol>
.breadcrumbs {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
list-style-type:none;
}
.breadcrumb-item {
padding: 0 0.5rem;
}
以下は上記のようなマークアップで出力する例です。
必要に応じて区切り文字を指定できるように引数に $separatorを設定しています(引数を省略すればスラッシュが区切り文字に使われます)。
function breadcrumbs( $separator=' / ') {
$file_path = $_SERVER['SCRIPT_NAME'];
$dirs = explode("/", $file_path);
$dirs = array_values(array_filter($dirs,"strlen"));
$li = '<li class="breadcrumb-item">';
$li_current = '<li class="breadcrumb-item active" aria-current="page">';
$html = $li. '<a href="/">HOME</a></li>';
$url = "";
//ディレクトリ名の代わりに表示する文字列を指定した配列
$dir_titles = [
'about' => '会社案内',
'contact' => 'お問い合わせ',
'news' => 'ニュース',
'tech' => 'テクノロジー',
'world' => 'ワールド',
];
for($i = 0; $i < count($dirs); $i++ ) {
$url .= "/".$dirs[$i];
//ファイルが index.php の場合はスキップ(index.php を表示しない)
if(strtolower($dirs[$i]) !== 'index.php') {
if($i === count($dirs) -1) {
//それぞれのページに設定してある $title を表示
$html .= $separator. $li_current . $GLOBALS['title'] .'</li>';
} else {
//$dir_titles から文字列を取得
$html .= $separator . $li. '<a href="' .$url.'">' .$dir_titles[$dirs[$i]].'</a></li>';
}
}
}
//ol 要素で囲んでマークアップを作成して出力
echo '<ol class="breadcrumbs">'. $html .'</ol>';
}
以下は、デフォルトでは上記と同じマークアップを出力しますが、第2パラメータに文字列 ul を指定すれば ol 要素の代わりに ul 要素でマークアップします。
また、第3及び第4パラメータを指定すれば、クラス名を変更できます。
function breadcrumbs( $separator=' / ' , $list_elem='ol', $list_class='breadcrumbs', $li_class='breadcrumb-item') {
$file_path = $_SERVER['SCRIPT_NAME'];
$dirs = explode("/", $file_path);
$dirs = array_values(array_filter($dirs,"strlen"));
$li = '<li>';
//$li_class が指定されていればクラスを追加
if($li_class !=='') $li = '<li class="' .$li_class . '">';
$html = $li. '<a href="/">HOME</a></li>';
$url = "";
//ディレクトリ名の代わりに表示する文字列を指定した配列
$dir_titles = [
'about' => '会社案内',
'contact' => 'お問い合わせ',
'news' => 'ニュース',
'tech' => 'テクノロジー',
'world' => 'ワールド',
];
for($i = 0; $i < count($dirs); $i++ ) {
$url .= "/".$dirs[$i];
if(strtolower($dirs[$i]) !== 'index.php') {
if($i === count($dirs) -1) {
//それぞれのページに設定してある $title を表示
$html .= $separator. $li . $GLOBALS['title'] .'</li>';
}else {
//$dir_titles から文字列を取得
$html .= $separator. $li. '<a href="' .$url.'">' .$dir_titles[$dirs[$i]].'</a></li>';
}
}
}
//$list_elem で指定された要素を作成
$list_start = '<' .$list_elem . '>';
//list_class が指定されていればクラスを追加
if($list_class !=='') $list_start = '<' .$list_elem . ' class="' .$list_class . '">';
//終了タグを作成
$list_end = '</' .$list_elem . '>';
//ol または ul 要素で囲んでマークアップを作成して出力
echo $list_start. $html .$list_end;
}
以下は区切り文字を「 | 」にして ul 要素でマークアップする場合の例です。
<?php breadcrumbs(' | ' , 'ul'); ?>
区切り文字(セパレータ)
この例では区切り文字(セパレータ)を関数で出力していますが、区切り文字を出力せず、CSS の ::after 疑似要素を使って出力する方法もあります。
前述の関数の場合、第一引数にセパレータを指定できるので空文字を指定し、スタイルを設定してセパレータを CSS で設定することができます。
または、CSS でセパレータを設定すると決めていれば、関数自体からセパレータを削除します。
<?php breadcrumbs(''); ?>
以下は CSS でセパレータを > に設定する例です。
.breadcrumbs li::after {
content: " > ";
padding-left: 0.5rem;
}
.breadcrumbs li:last-child::after {
/* 最後の要素は何も表示しない */
content: "";
}
リンクを相対パス(URL)で出力
今までの例のパンくずリストのリンクは絶対パスだったので、サイトをドキュメントルート以外にインストールすると余分な項目が表示されてしまい、期待通りの表示や動作になりません。
以下はサイトをドキュメントルート以外にインストールしても機能するパンくずリストの例です(もっと良い方法があるかも知れません)。
この方法の場合、各ページの先頭などで、そのファイルからホームディレクトリ(サイトのトップディレクトリ)までのパスを変数(以下の例では $path)に定義しておく必要があります。
<?php $title = 'トップページ'; $description = '説明(トップページ)'; $is_home = true; $path = './'; //ホームディレクトリまでのパスを変数に定義 include $path.'inc/vars.php'; include $path .'inc/head.php'; ?> </head> <body> ・・・
<?php $title = 'Tech ニュース 1'; $path = '../../'; //ホームディレクトリまでのパスを変数に定義 include $path.'inc/vars.php'; include $path.'inc/head.php'; ?> </head> <body> ・・・
また、関数側ではインストールしたディレクトリの位置(パス)を指定する必要があります。
以下の例では $intalled_dir という変数を関数の外側で定義しています(関数内でこの変数にアクセスするには $GLOBALS['intalled_dir'] とします)。
ルートディレクトリにインストールしている場合は、$intalled_dir には空文字('')を指定します。
例えば、http://localhost/example/test にサイトをインストールしている場合は '/example/test' を指定します。
//サイトをインストールしているディレクトリ(ルートディレクトリの場合は空文字 '')
//先頭にスラッシュ(/)を付け、最後はスラッシュなし
$intalled_dir = '/example';
function breadcrumbs( $separator=' / ') {
$file_path = $_SERVER['SCRIPT_NAME'];
//パス($file_path)からインストールされたディレクトリまでの文字を削除
if($GLOBALS['intalled_dir'] !== '') {
$file_path = str_replace($GLOBALS['intalled_dir'], "", $file_path);
}
//パスをスラッシュで区切った値(ディレクトリ名)の配列
$dirs = explode("/", $file_path);
//配列の空の要素を削除(先頭は常に空)
$dirs = array_values(array_filter($dirs,"strlen"));
//このページのルートディレクトリへのパス(各ページの先頭で定義してある $path)
$path = $GLOBALS['path'];
$li = '<li class="breadcrumb-item">';
$li_current = '<li class="breadcrumb-item active" aria-current="page">';
//リンクを相対パス($path)に
$html = $li. '<a href="' .$path . '">HOME</a></li>';
$url = "";
//ディレクトリ名の代わりに表示する文字列を指定した配列
$dir_titles = [
'about' => '会社案内',
'contact' => 'お問い合わせ',
'news' => 'ニュース',
'tech' => 'テクノロジー',
'world' => 'ワールド',
];
for($i = 0; $i < count($dirs); $i++ ) {
if($i === 0 ) {
//リンク文字列の先頭に相対パスを追加
$url .= $path .$dirs[$i];
} else {
$url .= "/".$dirs[$i];
}
//ファイルが index.php の場合はスキップ(index.php を表示しない)
if($i === count($dirs) -2) {
if(strtolower($dirs[$i + 1]) === 'index.php') {
//それぞれのページに設定してある $title を表示
$html .= $separator. $li_current .$dir_titles[$dirs[$i]] .'</li>';
break;
}else{
$html .= $separator . $li. '<a href="' .$url.'">' .$dir_titles[$dirs[$i]].'</a></li>';
}
} else {
if($i === count($dirs) -1) {
//それぞれのページに設定してある $title を表示
$html .= $separator. $li_current . $GLOBALS['title'] .'</li>';
} else {
$html .= $separator . $li. '<a href="' .$url.'">' .$dir_titles[$dirs[$i]].'</a></li>';
}
}
}
//ol 要素で囲んでマークアップを作成して出力
echo '<ol class="breadcrumbs">'. $html .'</ol>';
}
ホームの場合は出力しない
ホームの場合はパンくずリストを出力しないようにする1つの方法は、ホームのファイルにホームであることを示す変数を設定しておいて、その値が定義されているばあいは出力しないようにします。
以下の例ではホームのファイル(index.php)に $is_home という変数を定義しておきます(この例では値を true にしています)。
<?php $title = 'トップページ'; $description = '説明(トップページ)'; $is_home = true; //ホーム判定用の変数 $path = './'; include $path.'inc/vars.php'; include $path .'inc/head.php'; ?> </head> ・・・以下省略・・・
そしてパンくずリストの出力(breadcrumbs() の最後の部分)を以下のように書き換えてホーム以外でのみ出力するようにします。
関数内で $is_home にアクセスするには $GLOBALS['is_home'] とします。
function breadcrumbs( $separator=' / ') {
$file_path = $_SERVER['SCRIPT_NAME'];
・・・中略・・・
//ホームの場合は出力しない
if(!isset($GLOBALS['is_home'])) {
echo '<ol class="breadcrumbs">'. $html .'</ol>';
}
}
2ヶ国語サイトの例
以下は日本語と英語の2ヶ国語のサイトのパンくずリストの例です。
以下のようなフォルダ構成の場合、今までの例のパンくずリストでは英語ページの場合、先頭に HOME が表示され、日本語のトップページ(ホーム)にリンクされています。
.
├── about //日本語(会社概要)
│ └── index.php
├── contact //日本語(お問い合わせ)
│ └── index.php
├── en //英語ページ
│ ├── about //英語(About Us)
│ │ └── index.php
│ ├── contact //英語(Contact Us)
│ │ └── index.php
│ ├── index.php //英語トップページ(Top)
│ └── news //英語(News)
│ ├── index.php
│ ├── news1.php
│ ├── tech //英語(Technology)
│ │ ├── index.php
│ │ └── tech1.php
│ └── world //英語(World)
│ ├── index.php
│ └── world1.php
├── index.php //日本語トップページ(HOME)
└── news //日本語(ニュース)
├── index.php
├── news1.php
├── tech //日本語(テクノロジー)
│ ├── index.php
│ └── tech1.php
└── world //日本語(ワールド)
├── index.php
└── world1.php
英語ページの場合、HOME(日本語トップページへのリンク)を表示させない方法の一例です。
以下の場合、そのページのパスに英語のディレクトリ名(この場合は en)が含まれている場合は英語ページとして判定し、日本語の HOME を表示しないようにしています。全ての英語ページに判定用変数(例 $is_en = true)を定義して判定する方法もあるかと思います。
パンくずリストに表示するディレクトリ名の変換用文字列は英語用も用意します。以下の例では英語のトップページを Top としていますが、HOME にする場合は、Top を HOME に変更します。
また、以下の例はサイトをドキュメントルート以外にインストールしても機能するようにパンくずリストのリンクは相対パスを指定しています。
//サイトをインストールしているディレクトリ(ルートディレクトリの場合は空文字 '')
//先頭にスラッシュ(/)を付け、最後はスラッシュなし
$intalled_dir = '/example';
function breadcrumbs( $separator=' / ') {
$file_path = $_SERVER['SCRIPT_NAME'];
//$_SERVER['SCRIPT_NAME'] のパス($file_path)からインストールされたディレクトリまでの文字を削除
if($GLOBALS['intalled_dir'] !== '') {
$file_path = str_replace($GLOBALS['intalled_dir'], "", $file_path);
}
// パスをスラッシュで区切った値(ディレクトリ名)の配列
$dirs = explode("/", $file_path);
// 配列の空の要素を削除(先頭は常に空)
$dirs = array_values(array_filter($dirs,"strlen")); //または array_shift($dirs);
// 英語ページかどうかの判定用変数
$is_en = false;
// 英語ページかどうかの判定
foreach($dirs as $dir){
if(preg_match('/^en$/', $dir)) {
//ディレクトリ名が en に一致する場合は英語ページと判定
$is_en = true;
}
}
//このページのルートディレクトリへのパス(各ページの先頭で定義)
$path = $GLOBALS['path'];
$li = '<li class="breadcrumb-item">';
$li_current = '<li class="breadcrumb-item active" aria-current="page">';
//リンクを相対パス($path)に
$html = $li. '<a href="' .$path . '">HOME</a></li>';
if($is_en) {
$html = '';
}
$url = "";
//ディレクトリ名の代わりに表示する文字列を指定した配列
if($is_en) {
//英語ページ用
$dir_titles = [
'about' => 'About Us',
'contact' => 'Contact Us',
'news' => 'News',
'tech' => 'Technology',
'world' => 'World',
'en' => 'Top'
];
}else{
//日本語ページ用
$dir_titles = [
'about' => '会社案内',
'contact' => 'お問い合わせ',
'news' => 'ニュース',
'tech' => 'テクノロジー',
'world' => 'ワールド',
'en' => 'Top'
];
}
for($i = 0; $i < count($dirs); $i++ ) {
if($i === 0 ) {
$url .= $path .$dirs[$i];
} else {
$url .= "/".$dirs[$i];
}
//ファイルが index.php の場合はスキップ(index.php を表示しない)
if($i === count($dirs) -2) {
if(strtolower($dirs[$i + 1]) === 'index.php') {
//それぞれのページに設定してある $title を表示
$html .= $separator. $li_current .$dir_titles[$dirs[$i]] .'</li>';
if($is_en && $i === 0 ){
//英語トップページ
$html =$dir_titles[$dirs[$i]] ;
}
break;
}else{
$html .= $separator . $li. '<a href="' .$url.'">' .$dir_titles[$dirs[$i]].'</a></li>';
}
} else {
//英語ページの先頭ではセパレータを非表示
if($is_en && $i === 0 ){
$html .= $li. '<a href="' .$url.'">' .$dir_titles[$dirs[$i]].'</a></li>';
}else{
if($i === count($dirs) -1) {
//それぞれのページに設定してある $title を表示
$html .= $separator. $li_current . $GLOBALS['title'] .'</li>';
} else {
$html .= $separator . $li. '<a href="' .$url.'">' .$dir_titles[$dirs[$i]].'</a></li>';
}
}
}
}
//ol 要素で囲んでマークアップを作成して出力
echo '<ol class="breadcrumbs">'. $html .'</ol>';
//ホームでは出力しない場合は上記をコメントアウト(削除)し、以下のコメントを外す
/*if(!isset($GLOBALS['is_home'])) {
echo '<ol class="breadcrumbs">'. $html .'</ol>';
}*/
}
独自テンプレートで出力
以下はパンくずリストのテンプレートを作成して出力する例です。
但し、全てのページでテンプレートに渡すパラメータを設定しなければならないので、単純に HTML で個別に出力する方が簡単だと思います。
テンプレートを使う利点は、パンくずリストのマークアップを変更する場合、テンプレートを変更すれば全てのパンくずリストに変更を反映させることができます。但し、パラメータの渡し方やパラメータを変更する場合は、全てのページで設定してあるパラメータを変更する必要があります。
以下は独自のテンプレートを作成してパンくずリストを出力する例です。
.
├── about
│ └── index.php
├── contact
│ └── index.php
├── inc
│ ├── breadcrumbs.php //パンくずリストのテンプレート
│ ├── footer.php
│ ├── head.php
│ ├── header.php
│ ├── side.php
│ └── vars.php //関数を記述するファイル
├── index.php
└── news
├── tech
│ ├── index.php
│ └── tech1.php
└── world
├── index.php
└── world1.php
以下はテンプレートファイルをロード(インクルード)するための関数 load_my_template() です。この関数の定義を記述したファイル(この例では vars.php)を全てのページで読み込みます。
function load_my_template($file, $attrs){
ob_start();
include $file; //テンプレートファイルのインクルード
$html = ob_get_contents();
ob_end_clean();
echo $html; //出力
}
以下はパンくずリストのテンプレートファイルです。
パンくずリストのマークアップが記述されています。$attrs は load_my_template() に渡すパラメータで各ページで定義します。
<ol class="breadcrumbs">
<?php for($i = 0; $i < count($attrs); $i++){ ?>
<li class="breadcrumb-item<?php echo isset($attrs[$i]['item_active']) ? ' active': ''; ?>"<?php echo isset($attrs[$i]['item_active']) ? ' aria-current="page"': ''; ?>>
<a href="<?php echo $attrs[$i]['item_link']; ?>">
<?php echo $attrs[$i]['item_title']; ?>
</a>
</li>
<?php if( $i !== count($attrs) -1) echo ' / '; ?>
<?php } ?>
</ol>
パンくずリストを出力する場所で以下を記述します。
load_my_template() の最初の引数には読み込むテンプレートファイルを指定し、2番目の引数にはテンプレートに渡すパラメータ指定します。
<?php load_my_template( "inc/breadcrumbs.php", $attrs_breadcrumbs ); ?>
以下はヘッダー部分を header.php として外部ファイル化している場合の例です。
<header>
<h1>My Site</h1>
<div class="container">
<nav class="navbar-menu">
<ul class="navbar-navigation">
・・・中略・・・
</nav>
<div class="breadcrumbs_wrapper">
<!-- テンプレートをロード -->
<?php load_my_template( "inc/breadcrumbs.php", $attrs_breadcrumbs ); ?>
</div>
</div>
</header>
パンくずリストを表示する各ページで、load_my_template() に渡す2番目の引数 $attrs_breadcrumbs を設定します。
以下の例では、各ページでそのページのタイトルを変数 $title に、ルートディレクトリまでのパスを変数 $path に設定していて、それらの値を load_my_template() に渡す引数 $attrs_breadcrumbs で使用しています。
<?php
$title = 'Techニュース';
$path = '../../';
//load_my_template() に渡すテンプレートのパラメータ
$attrs_breadcrumbs = [
[
'item_link' => $path,
'item_title' => 'HOME',
],
[
'item_link' => $path.'news/',
'item_title' => 'ニュース',
],
[
'item_link' => $path.'news/tech/',
'item_title' => 'テクノロジー',
],
[
'item_link' => '#',
'item_title' => $title,
'item_active' => true,
],
];
//load_my_template() の定義を記述したファイルのインクルード
include $path.'inc/vars.php';
include $path.'inc/head.php';
?>
</head>
<body>
<div class="wrapper">
<!-- header.php のインクルード -->
<?php include $path.'inc/header.php'; ?>
<div class="container">
</div>
</div>
<?php include $path.'inc/footer.php'; ?>
</body>
</html>
上記のページの場合、以下のようなパンくずリストが出力されます。
<ol class="breadcrumbs">
<li class="breadcrumb-item">
<a href="../../"> HOME </a>
</li>/
<li class="breadcrumb-item">
<a href="../../news/"> ニュース </a>
</li>/
<li class="breadcrumb-item">
<a href="../../news/tech/"> テクノロジー </a>
</li>/
<li class="breadcrumb-item active" aria-current="page">
<a href="#"> Techニュース </a>
</li>
</ol>
JSON-LD での構造化マークアップを出力
検索エンジンにパンくずリストを認識させる方法として、microdata または JSON-LD を使った構造化マークアップがあります。
関連項目:JSON-LD で構造化マークアップ
以下は JSON-LD を使った構造化マークアップを動的に出力する例です。
この方法の場合、パンくずリストはサイトのフォルダ構造に一致していることが前提です。
以下はこの例のサイトのフォルダ構造で、ディレクトリごとにインデックスファイルがある構成になっています。
.
├── about //会社概要
│ └── index.php
├── contact //お問い合わせ
│ └── index.php
├── inc
│ ├── footer.php
│ ├── head.php
│ ├── header.php
│ ├── side.php
│ └── vars.php //変数や関数を記述するファイル
├── index.php //トップページ(HOME)
└── news //ニュース
├── index.php
├── news1.php
├── tech //テクノロジー
│ ├── index.php
│ └── tech1.php
└── world //ワールド
├── index.php
└── world1.php
この例では、パンくずリストとその構造化マークアップは関数を作成して出力します。共通で使える変数などがあるので共通のファイル(この例では vars.php)に記述します。
以下は共通で使用する変数とパンくずリストを出力する関数 breadcrumbs() の定義です。
breadcrumbs() の内容は リンクを相対パス(URL)で出力 での例とほぼ同じですが、構造化マークアップを出力する関数と共通で使用する値は関数外に定義して、関数内では $GLOBALS[ ] でアクセスしています。また、ホームではパンくずリストを出力しないようにしています。
//サイトをインストールしているディレクトリ(ルートディレクトリの場合は空文字 '')
//先頭にスラッシュ(/)を付け、最後はスラッシュなし
$intalled_dir = '/example/test';
//このスクリプトを実行しているページのホームディレクトリからのパス(ファイル名を含む)
$file_path = $_SERVER['SCRIPT_NAME'];
//ディレクトリ名の代わりに表示する文字列を指定した配列
$dir_titles = [
'about' => '会社案内',
'contact' => 'お問い合わせ',
'news' => 'ニュース',
'tech' => 'テクノロジー',
'world' => 'ワールド',
];
function breadcrumbs( $separator=' / ') {
//ホームディレクトリからのパス(関数外で定義してあるので $GLOBALS でアクセス)
$file_path = $GLOBALS['file_path'];
//$_SERVER['SCRIPT_NAME'] のパス($file_path)からインストールされたディレクトリまでの文字を削除
if($GLOBALS['intalled_dir'] !== '') {
$file_path = str_replace($GLOBALS['intalled_dir'], "", $file_path);
}
// パスをスラッシュで区切った値(ディレクトリ名)の配列
$dirs = explode("/", $file_path);
// 配列の空の要素を削除
$dirs = array_values(array_filter($dirs,"strlen"));
//このページのルートディレクトリへのパス(各ページの先頭で定義)
$path = $GLOBALS['path'];
$li = '<li class="breadcrumb-item">';
$li_current = '<li class="breadcrumb-item active" aria-current="page">';
//リンクを相対パス($path)に
$html = $li. '<a href="' .$path . '">HOME</a></li>';
$url = "";
//ディレクトリ名の代わりに表示する文字列
$dir_titles = $GLOBALS['dir_titles'];
for($i = 0; $i < count($dirs); $i++ ) {
if($i === 0 ) {
//リンク文字列の先頭に相対パスを追加
$url .= $path .$dirs[$i];
} else {
$url .= "/".$dirs[$i];
}
//ファイルが index.php の場合はスキップ(index.php を表示しない)
if($i === count($dirs) -2) {
if(strtolower($dirs[$i + 1]) === 'index.php') {
//それぞれのページに設定してある $title を表示
$html .= $separator. $li_current .$dir_titles[$dirs[$i]] .'</li>';
break;
}else{
$html .= $separator . $li. '<a href="' .$url.'">' .$dir_titles[$dirs[$i]].'</a></li>';
}
} else {
if($i === count($dirs) -1) {
//それぞれのページに設定してある $title を表示
$html .= $separator. $li_current . $GLOBALS['title'] .'</li>';
} else {
$html .= $separator . $li. '<a href="' .$url.'">' .$dir_titles[$dirs[$i]].'</a></li>';
}
}
}
//ol 要素で囲んでマークアップを作成して出力(ホームでは出力しない)
if(!isset($GLOBALS['is_home'])) {
echo '<ol class="breadcrumbs">'. $html .'</ol>';
}
}
以下は JSON-LD を使った構造化マークアップを動的に出力する関数 breadcrumbs_jsonld() です。
breadcrumbs_jsonld() では前述の関数外で定義されている変数($intalled_dir、$file_path、$dir_titles) も使用します。
2〜4行目はサーバーが $_SERVER['HTTPS'] の値を返さない環境用で、URL の組み立ての際、プロトコル部分の判定に使用します。
構造化マークアップにホームを含めるかや、ホームで構造化マークアップを出力するか、インデックスファイルの拡張子、ホームの文字(ラベル)などを設定し、更に関数外で定義されている変数の値を関数内で使用する変数に代入しています。
大まかな内容としては、ドキュメントルート以外にインストールした場合も考慮して $_SERVER['SCRIPT_NAME'] から取得したパスからサイトをインストールしたパスの部分を削除します。
そしてそのパスをスラッシュで分割して取得したディレクトリ名(ファイル名を含む)を配列に入れます。
構造化マークアップの @id には URL を指定するのでホームの URL を $_SERVER['HTTP_HOST'] を使って組み立てておきます。
ディレクトリ名(及びファイル名)の配列の各要素を for 文でループし、ディレクトリ名の場合は表示する文字列の配列($dir_titles)の対応する値を name に設定しています。
ファイル名の場合は、ページで設定してある変数 $title の値を name に設定していますが、ファイル名がインデックスファイルの場合はその項目はすでにディレクトリ名で出力しているので、何もしません。
また、ページの拡張子を表示しないようにしている場合は78行目のコメントアウトを外します。
詳細はコードにコメントを入れてあります。
//サーバーが $_SERVER['HTTPS'] の値を返さない場合で、SSL化されいる場合は $_SERVER['HTTPS'] に 'on' を設定
if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] === "https") {
$_SERVER['HTTPS'] = 'on';
}
//Home の URL の組み立て
$host_url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://'). $_SERVER['HTTP_HOST'];
function breadcrumbs_jsonld() {
//構造化マークアップにホームを含めるかどうか(含めない場合は false に変更)
$include_home = true;
//ホームで構造化マークアップを出力するかどうか(出力する場合は true に変更)
$show_at_home = false;
//ファイルの拡張子(必要に応じて変更)
$extension = '.php';
//インデックスファイル名
$index_file = 'index' . $extension;
//ホームの文字(必要に応じて変更)
$home = 'HOME';
//Home の URL
$host_url = $GLOBALS['host_url'];
//ディレクトリ名の代わりに表示する文字列(関数外で定義→ $GLOBALS[] でアクセス)
$dir_titles = $GLOBALS['dir_titles'];
//ホームディレクトリからのパス(関数外で定義)
$file_path = $GLOBALS['file_path'];
//インストールされたディレクトリまでの文字(関数外で定義)
$intalled_dir = $GLOBALS['intalled_dir'];
//そのページのタイトル(各ページで定義)
$page_title = $GLOBALS['title'];
//ホームかどうかの判定用変数(ホームのみで定義)
$is_home = isset($GLOBALS['is_home']) ? true : false;
//出力文字列の初期化(構造化マークアップの先頭部分)
$str ='{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement":
['."\n";
//position カウンター
$count = 1;
//パス($file_path)からインストールされたディレクトリまでの文字を削除
if($intalled_dir !== '') {
$file_path = str_replace($intalled_dir, "", $file_path);
}
// パスをスラッシュで区切った値(ディレクトリ名)の配列
$dirs = explode("/", $file_path);
// 配列の空の要素を削除(先頭は常に空)
$dirs = array_values(array_filter($dirs));
//ホスト($host_url)以降のパス
//ルートディレクトリにサイトがインストールされていれば $intalled_dir は空 ''
$url_path = $intalled_dir;
//カンマ部分に使用する変数
$comma =',';
if($include_home) {
//構造化マークアップにホームを含める場合(デフォルト)
if($show_at_home && $is_home) $comma ='';
$home_str = '{"@type": "ListItem",
"position": '.$count.',
"item":{
"@id":"'. $host_url. $url_path . '/",
"name":"'.$home. '"}}' .$comma. "\n";
$count++;
$str.= $home_str;
}
for ( $i = 0; $i < count( $dirs ); $i++ ) {
//ホスト($host_url)以降のパス
$url_path = $url_path . '/' . $dirs[ $i ];
//"name" に表示する値(ホームの場合は $home に指定した文字)
$name = '';
//インデックスファイル以外の場合
//インデックスファイルの場合はそのディレクトリで出力されるので何も出力しない
if(strpos($dirs[$i], $index_file) === false) {
if($i === count($dirs) - 1) {
//ファイルの拡張子を表示しない場合は、以下のコメントアウトを外す
//$url_path = str_replace( $extension, '' , $url_path );
$str.= '{"@type": "ListItem",
"position": '.$count.',
"item":{
"@id":"'. $host_url. $url_path. '",
"name":"'.$page_title. '"}}' ."\n";
//ファイルの場合はそのページで設定されているタイトル($page_title)を使用
}else{
$comma =',';
if($i === count($dirs) - 2 && (strpos($dirs[$i + 1], 'index.php') !== false)) $comma ='';
$str.= '{"@type": "ListItem",
"position": '.$count.',
"item":{
"@id":"'. $host_url. $url_path. '/",
"name":"'.$dir_titles[$dirs[$i]]. '"}}' .$comma. "\n";
//配列 $dir_titles からディレクトリ名をキーとして表示する文字列を取得
}
$count ++;
}
}
$str.= "\n".']'."\n".'}'."\n";
if($show_at_home) {
echo '<script type="application/ld+json">' ."\n". $str . '</script>'."\n";
}else{
//ホームでは表示しない
if(!$is_home) {
echo '<script type="application/ld+json">' ."\n". $str . '</script>'."\n";
}
}
}
使い方は出力したい場所で breadcrumbs_jsonld() を呼び出します。
例えば、全てのページの共通ファイル footer.php などに記述します。
<footer>
<div class="container">
<p><small>©Copyright</small></p>
</div>
</footer>
<script src="<?php echo $path; ?>js/main.js?<?php echo filemtime($path.'js/main.js'); ?>"></script>
<?php
breadcrumbs_jsonld(); //構造化マークアップを出力
?>
出力例
以下はローカル環境(http://localhost/example/news/)での出力例です。$intalled_dir にはサイトをインストールした '/example' を指定しています。
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement":
[
{"@type": "ListItem",
"position": 1,
"item":{
"@id":"http://localhost/example/",
"name":"HOME"}},
{"@type": "ListItem",
"position": 2,
"item":{
"@id":"http://localhost/example/news/",
"name":"ニュース"}}
]
}
</script>
以下は http://localhost/example/news/world/world1.php での出力例です。
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement":
[
{"@type": "ListItem",
"position": 1,
"item":{
"@id":"http://localhost/example/",
"name":"HOME"}},
{"@type": "ListItem",
"position": 2,
"item":{
"@id":"http://localhost/example/news/",
"name":"ニュース"}},
{"@type": "ListItem",
"position": 3,
"item":{
"@id":"http://localhost/example/news/world/",
"name":"ワールド"}},
{"@type": "ListItem",
"position": 4,
"item":{
"@id":"http://localhost/example/news/world/world1.php",
"name":"World ニュース 1 (日本語)"}}
]
}
</script>
サンプルページ(出力はページのソースを表示して確認できます。但し、ホームでは出力していません。)
出力のテスト
構造化マークアップに問題がないかは Google の「リッチリザルトテスト」で確認することができます。
テストページでは URL を指定することも、構造化マークアップを入力することもできます。
テストを実行してエラーが表示されなければ問題ありません。
エラーが表示されたら、詳細を確認して修正します。
詳細の行番号が表示されているところをクリックするとその箇所がハイライトされます。
以下の例の場合、「行 12: 1」とあり、原因は11行目の最後にカンマがないことでした。
2ヶ国語サイトの例
パンくずリストの出力の 2ヶ国語サイトの例 と同じ構成のサイトでの、構造化マークアップを出力する例です。
以下がサイトの構成です。
.
├── about //日本語(会社概要)
│ └── index.php
├── contact //日本語(お問い合わせ)
│ └── index.php
├── en //英語ページ
│ ├── about //英語(About Us)
│ │ └── index.php
│ ├── contact //英語(Contact Us)
│ │ └── index.php
│ ├── index.php //英語トップページ(Top)
│ └── news //英語(News)
│ ├── index.php
│ ├── news1.php
│ ├── tech //英語(Technology)
│ │ ├── index.php
│ │ └── tech1.php
│ └── world //英語(World)
│ ├── index.php
│ └── world1.php
├── index.php //日本語トップページ(HOME)
└── news //日本語(ニュース)
├── index.php
├── news1.php
├── tech //日本語(テクノロジー)
│ ├── index.php
│ └── tech1.php
└── world //日本語(ワールド)
├── index.php
└── world1.php
構造化マークアップの出力方法は、日本語だけの場合とほとんど同じです。
以下の例では、全ての英語ページで英語ページかどうかの判定用の変数 $is_en = true; を設定してあります。また、パンくずリストを出力する関数と構造化マークアップを出力する関数では共通の値を使用するので、関数の外側でそれらの変数を定義し、関数の中では $GLOBALS[ ] でアクセスするようにしています。
パンくずリストを出力する関数 breadcrumbs() と構造化マークアップを出力する関数 breadcrumbs_jsonld() は同じファイル(vars.php)に記述してあります。
//サイトをインストールしているディレクトリ(ルートディレクトリの場合は空文字 '')
//先頭にスラッシュ(/)を付け、最後はスラッシュなし
$intalled_dir = '/example/test';
//このスクリプトを実行しているページのホームディレクトリからのパス(ファイル名を含む)
$file_path = $_SERVER['SCRIPT_NAME'];
//$_SERVER['SCRIPT_NAME'] のパス($file_path)からインストールされたディレクトリまでの文字を削除
if($intalled_dir !== '') {
$file_path = str_replace($intalled_dir, "", $file_path);
}
// パスをスラッシュで区切った値(ディレクトリ名)の配列
$dirs = explode("/", $file_path);
// 配列の空の要素を削除(先頭は常に空)
$dirs = array_values(array_filter($dirs,"strlen"));
//ディレクトリ名の代わりに表示する文字列を指定した配列
//日本語ページ用
$dir_titles = [
'about' => '会社案内',
'contact' => 'お問い合わせ',
'news' => 'ニュース',
'tech' => 'テクノロジー',
'world' => 'ワールド',
'en' => 'Top'
];
if(isset($is_en)) {
//英語ページ用
$dir_titles = [
'about' => 'About Us',
'contact' => 'Contact Us',
'news' => 'News',
'tech' => 'Technology',
'world' => 'World',
'en' => 'Top'
];
}
function breadcrumbs( $separator=' / ') {
//ホームディレクトリからのパス(関数外で定義)
$file_path = $GLOBALS['file_path'];
// パスをスラッシュで区切った値(ディレクトリ名の配列。関数外で定義)
$dirs = $GLOBALS['dirs'];
// 英語ページかどうかの判定用変数(全ての英語ページでは $is_en を設定してある)
$is_en = isset($GLOBALS['is_en']) ? true: false;
//このページのルートディレクトリへのパス(各ページの先頭で定義)
$path = $GLOBALS['path'];
$li = '<li class="breadcrumb-item">';
$li_current = '<li class="breadcrumb-item active" aria-current="page">';
//リンクを相対パス($path)に
$html = $li. '<a href="' .$path . '">HOME</a></li>';
if($is_en) {
//英語ページでは HOME を表示しない
$html = '';
}
$url = "";
//ディレクトリ名の代わりに表示する文字列を指定した配列(関数外で定義)
$dir_titles = $GLOBALS['dir_titles'];
for($i = 0; $i < count($dirs); $i++ ) {
if($i === 0 ) {
//リンク文字列の先頭に相対パスを追加
$url .= $path .$dirs[$i];
} else {
$url .= "/".$dirs[$i];
}
//ファイルが index.php の場合はスキップ(index.php を表示しない)
if($i === count($dirs) -2) {
if(strtolower($dirs[$i + 1]) === 'index.php') {
//それぞれのページに設定してある $title を表示
$html .= $separator. $li_current .$dir_titles[$dirs[$i]] .'</li>';
if($is_en && $i === 0 ){
//英語トップページ
$html =$dir_titles[$dirs[$i]] ;
}
break;
}else{
$html .= $separator . $li. '<a href="' .$url.'">' .$dir_titles[$dirs[$i]].'</a></li>';
}
} else {
//英語ページの先頭ではセパレータを非表示
if($is_en && $i === 0 ){
$html .= $li. '<a href="' .$url.'">' .$dir_titles[$dirs[$i]].'</a></li>';
}else{
if($i === count($dirs) -1) {
//それぞれのページに設定してある $title を表示
$html .= $separator. $li_current . $GLOBALS['title'] .'</li>';
} else {
$html .= $separator . $li. '<a href="' .$url.'">' .$dir_titles[$dirs[$i]].'</a></li>';
}
}
}
}
//ol 要素で囲んでマークアップを作成して出力(ホームでは出力しない)
if(!isset($GLOBALS['is_home'])) {
echo '<ol class="breadcrumbs">'. $html .'</ol>';
}
}
//SSL化されいる場合は $_SERVER['HTTPS'] に 'on' を設定
if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] === "https") {
$_SERVER['HTTPS'] = 'on';
}
//Home の URL の組み立て
$host_url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://'). $_SERVER['HTTP_HOST'];
function breadcrumbs_jsonld() {
//構造化マークアップにホームを含めるかどうか(含めない場合は false に変更)
$include_home = true;
//ホームで構造化マークアップを出力するかどうか(出力する場合は true に変更)
$show_at_home = false;
//ファイルの拡張子(必要に応じて変更)
$extension = '.php';
//インデックスファイル名
$index_file = 'index' . $extension;
//ホームの文字(必要に応じて変更)
$home = 'HOME';
//Home の URL
$host_url = $GLOBALS['host_url'];
//ディレクトリ名の代わりに表示する文字列(関数外で定義→ $GLOBALS[] でアクセス)
$dir_titles = $GLOBALS['dir_titles'];
//ホームディレクトリからのパス(関数外で定義)
$file_path = $GLOBALS['file_path'];
//インストールされたディレクトリまでの文字(関数外で定義)
$intalled_dir = $GLOBALS['intalled_dir'];
//そのページのタイトル(各ページで定義)
$page_title = $GLOBALS['title'];
//ホームかどうかの判定用変数(ホームのみで定義)
$is_home = isset($GLOBALS['is_home']) ? true : false;
// 英語ページかどうかの判定用変数(★★追加★★)
$is_en = isset($GLOBALS['is_en']) ? true: false;
//出力文字列の初期化(構造化マークアップの先頭部分)
$str ='{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement":
['."\n";
//position カウンター
$count = 1;
//パス($file_path)からインストールされたディレクトリまでの文字を削除
if($intalled_dir !== '') {
$file_path = str_replace($intalled_dir, "", $file_path);
}
// パスをスラッシュで区切った値(ディレクトリ名)の配列
$dirs = explode("/", $file_path);
// 配列の空の要素を削除(先頭は常に空)
$dirs = array_values(array_filter($dirs));
//ホスト($host_url)以降のパス
//ルートディレクトリにサイトがインストールされていれば $intalled_dir は空 ''
$url_path = $intalled_dir;
//カンマ部分に使用する変数
$comma =',';
//$include_home(ホームを含めるかどうか)が true(デフォルト)で、英語ページでない場合
if($include_home && !$is_en) {
if($show_at_home && $is_home) $comma ='';
$home_str = '{"@type": "ListItem",
"position": '.$count.',
"item":{
"@id":"'. $host_url. $url_path . '/",
"name":"'.$home. '"}}' .$comma. "\n";
$count++;
$str.= $home_str;
}
for ( $i = 0; $i < count( $dirs ); $i++ ) {
//ホスト($host_url)以降のパス
$url_path = $url_path . '/' . $dirs[ $i ];
//"name" に表示する値(ホームの場合は $home に指定した文字)
$name = '';
//インデックスファイル以外の場合
//インデックスファイルの場合はそのディレクトリで出力されるので何も出力しない
if(strpos($dirs[$i], $index_file) === false) {
if($i === count($dirs) - 1) {
//ファイルの拡張子を表示しない場合は、以下のコメントアウトを外す
//$url_path = str_replace( $extension, '' , $url_path );
$str.= '{"@type": "ListItem",
"position": '.$count.',
"item":{
"@id":"'. $host_url. $url_path. '",
"name":"'.$page_title. '"}}' ."\n";
//ファイルの場合はそのページで設定されているタイトル($page_title)を使用
}else{
$comma =',';
if($i === count($dirs) - 2 && (strpos($dirs[$i + 1], 'index.php') !== false)) $comma ='';
$str.= '{"@type": "ListItem",
"position": '.$count.',
"item":{
"@id":"'. $host_url. $url_path. '/",
"name":"'.$dir_titles[$dirs[$i]]. '"}}' .$comma. "\n";
//配列 $dir_titles からディレクトリ名をキーとして表示する文字列を取得
}
$count ++;
}
}
$str.= "\n".']'."\n".'}'."\n";
if($show_at_home) {
echo '<script type="application/ld+json">' ."\n". $str . '</script>'."\n";
}else{
//ホームでは表示しない
if(!$is_home) {
echo '<script type="application/ld+json">' ."\n". $str . '</script>'."\n";
}
}
}
出力例
以下はローカル環境にバーチャルホストを設定した場合の http://example.localhost/en/news/tech/tech-news1.php での出力例です。$intalled_dir には空文字列 '' を指定しています。
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement":
[
{"@type": "ListItem",
"position": 1,
"item":{
"@id":"http://example.localhost/en/",
"name":"Top"}},
{"@type": "ListItem",
"position": 2,
"item":{
"@id":"http://example.localhost/en/news/",
"name":"News"}},
{"@type": "ListItem",
"position": 3,
"item":{
"@id":"http://example.localhost/en/news/tech/",
"name":"Technology"}},
{"@type": "ListItem",
"position": 4,
"item":{
"@id":"http://example.localhost/en/news/tech/tech-news1.php",
"name":"Tech News 1 (English)"}}
]
}
</script>
以下は日本語ページ http://example.localhost/news/tech/tech-news1.php での出力例です。
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement":
[
{"@type": "ListItem",
"position": 1,
"item":{
"@id":"http://example.localhost/",
"name":"HOME"}},
{"@type": "ListItem",
"position": 2,
"item":{
"@id":"http://example.localhost/news/",
"name":"ニュース"}},
{"@type": "ListItem",
"position": 3,
"item":{
"@id":"http://example.localhost/news/tech/",
"name":"テクノロジー"}},
{"@type": "ListItem",
"position": 4,
"item":{
"@id":"http://example.localhost/news/tech/tech-news1.php",
"name":"Tech ニュース 1(日本語)"}}
]
}
</script>
サンプルページ(出力はページのソースを表示して確認できます。但し、ホームでは出力していません。)



