#author("2022-04-25T22:15:15+09:00","","")
#author("2022-04-25T22:16:40+09:00","","")
** jsonld.inc.php [#p3a5a41b]
|RIGHT:100|LEFT:360|c
|~サマリ|JSON-LD構造化データを生成・出力|
|~リビジョン|1.04|
|~対応バージョン|1.5.4|
|~投稿者|[[M.Taniguchi]]|
|~投稿日|&new{2020-04-19 (日) 05:07:10};|
**概要 [#yd20b678]
JSON-LDを出力するプラグイン。~

ページの情報に基づくJSON-LD構造化データを生成し出力します。~
具体的には、記事情報 Article とパンくずリスト情報 BreadcrumbList を生成します。~
ウィキの構造を検索エンジンにより良く伝えるため(SEO)に役立ちます。

PukiWiki 1.5.4/PHP 8.1 で動作確認済み。旧バージョンでも1.5.2以上なら動くと思いますが、PHPは5.2以上が必要です。

**使い方 [#pdd0ef88]

#jsonld

本プラグインは、MenuBar など全画面共通で表示されるページに挿入してください。~
もしくは、次のコードをスキンファイル(skin/pukiwiki.skin.php等)HTML内の</body>閉じタグ直前に挿入してください。~
 <?php if (exist_plugin_convert('jsonld')) echo do_plugin_convert('jsonld'); ?>
なお、本プラグインを挿入できるのは1ページにつき1箇所のみです。

**コード [#s0c8fd29]

jsonld.inc.php~
(下記のコードをコピーして、plugin ディレクトリに jsonld.inc.php というファイル名で保存してください)

 <?php
 /*
 PukiWiki - Yet another WikiWikiWeb clone.
 jsonld.inc.php, v1.04 2020 M.Taniguchi
 License: GPL v3 or (at your option) any later version
 
 JSON-LDを出力するプラグイン。
 
 ページの情報に基づくJSON-LD構造化データを生成し出力します。
 具体的には、記事情報 Article とパンくずリスト情報 BreadcrumbList を生成します。
 ウィキの構造を検索エンジンにより良く伝えるため(SEO)に役立ちます。
 
 【使い方】
 #jsonld
 
 本プラグインは、MenuBar など全画面共通で表示されるページに挿入してください。
 もしくは、次のコードをスキンファイル(skin/pukiwiki.skin.php等)HTML内の</body>閉じタグ直前に挿入してください。
  <?php if (exist_plugin_convert('jsonld')) echo do_plugin_convert('jsonld'); ?>
 なお、本プラグインを挿入できるのは1ページにつき1箇所のみです。
 */
 
 if (!defined('PLUGIN_JSONLD_ARTICLE'))                    define('PLUGIN_JSONLD_ARTICLE',        1); // 1:Article (記事情報)を出力, 0:無効
 if (!defined('PLUGIN_JSONLD_BREADCRUMBLIST'))             define('PLUGIN_JSONLD_BREADCRUMBLIST', 1); // 1:BreadcrumbList (パンくずリスト情報)を出力, 0:無効
 if (!defined('PLUGIN_JSONLD_BREADCRUMBLIST_NOTEXISTPOS')) define('PLUGIN_JSONLD_BREADCRUMBLIST_NOTEXISTPOS', 0); // パンくずリストにおいて、ページとして存在しない階層の扱い。0:上位階層のURLを記載, 1:存在しない階層のURLをそのまま記載, 2:その階層を無視
 if (!defined('PLUGIN_JSONLD_ENCODEFLAGS'))                define('PLUGIN_JSONLD_ENCODEFLAGS',    (JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT)); // json_encode関数のJSONエンコードフラグ指定
 
 function plugin_jsonld_convert() {
 	if (!PLUGIN_JSONLD_ARTICLE && !PLUGIN_JSONLD_BREADCRUMBLIST) return '';
 	// if (!PKWK_ALLOW_JAVASCRIPT) return '';	// JavaScriptではなくJSONなので無視
 
 	global	$modifier, $defaultpage, $page_title, $title;
 
 	// 二重起動禁止
 	static	$included = false;
 	if ($included) return '';
 	$included = true;
 
 	$script = get_script_uri();
 	$isHome = ($title == $defaultpage);
 
 	// Article(記事情報)生成
 	if (PLUGIN_JSONLD_ARTICLE) {
 		$long_title = (!$isHome ? $title . ' | ' : '') . $page_title;
 		$thisPageUri = ($isHome)? $script : get_page_uri($title, PKWK_URI_ABSOLUTE);
 		$modifiedDate = date('Y-m-d\TH:i:sP', get_filetime($title));
 
 		$article = array(
 			'@context' => 'http:'.'//schema.org',
 			'@type' => 'Article',
 			'mainEntityOfPage' => array(
 				'@type' => 'WebPage',
 				'@id' => $thisPageUri
 			),
 			'datePublished' => $modifiedDate,
 			'dateModified' => $modifiedDate,
 			'author' => array(
 				'@type' => 'Person',
 				'name' => $modifier
 			),
 			'publisher' => array(
 				'@type' => 'Organization',
 				'name' => $page_title
 			),
 			'headline' => $long_title
 		);
 		$article = '<script type="application/ld+json">' . json_encode($article, PLUGIN_JSONLD_ENCODEFLAGS) . '</script>';
 	} else $article = '';
 
 	// BreadcrumbList(パンくずリスト)生成
 	if (PLUGIN_JSONLD_BREADCRUMBLIST && !$isHome ) {
 		$names = explode('/', $title);
 		$path = '';
 		$item = $script;
 		$i = 0;
 
 		$bread = array();
 		$bread[] = array(
 			'@type' => 'ListItem',
 			'position' => ++$i,
 			'name' => $defaultpage,
 			'item' => $item
 		);
 
 		foreach ($names as $name) {
 			$path .= (($path != '')? '/' : '') . $name;
 			if (PLUGIN_JSONLD_BREADCRUMBLIST_NOTEXISTPOS != 1 && !is_page($path)) {
 				if (PLUGIN_JSONLD_BREADCRUMBLIST_NOTEXISTPOS != 0) continue;
 			} else {
 				$item = get_page_uri($path, PKWK_URI_ABSOLUTE);
 			}
 			$bread[] = array(
 				'@type' => 'ListItem',
 				'position' => ++$i,
 				'name' => $name,
 				'item' => $item
 			);
 		}
 
 		$bread = array(
 			'@context' => 'http:'.'//schema.org',
 			'@type' => 'BreadcrumbList',
 			'itemListElement' => $bread
 		);
 		$bread = '<script type="application/ld+json">' . json_encode($bread, PLUGIN_JSONLD_ENCODEFLAGS) . '</script>';
 	} else $bread = '';
 
 	return $article . $bread;
 }

**設定 [#r5971045]
ソース内の下記の定数で動作を制御することができます。

|定数名|値|既定値|意味|h
|PLUGIN_JSONLD_ARTICLE| 0 or 1| 1|1:Article (記事情報)を出力, 0:無効|
|PLUGIN_JSONLD_BREADCRUMBLIST| 0 or 1| 1|1:BreadcrumbList (パンくずリスト情報)を出力, 0:無効|
|PLUGIN_JSONLD_BREADCRUMBLIST_NOTEXISTPOS| 0 ~ 2| 0|パンくずリストにおいて、ページとして存在しない階層の扱い&br;0:上位階層のURLを記載, 1:存在しない階層のURLをそのまま記載, 2:その階層を無視(飛ばす)|
|PLUGIN_JSONLD_ENCODEFLAGS| ビットフラグ| (JSON_UNESCAPED_UNICODE &#x7c; JSON_UNESCAPED_SLASHES &#x7c; JSON_HEX_TAG &#x7c; JSON_HEX_AMP &#x7c; JSON_HEX_APOS &#x7c; JSON_HEX_QUOT)|json_encode関数のJSONエンコードフラグ指定|

**ライセンス [#uc35c653]

GPL v3

** コメント [#yd21e0e7]
-  タイトルにスラッシュが入っているページ(つまりディレクトリ下のページ)でパン屑リストを出力すると、スラッシュまでエスケープされてしまってリンクがおかしくなるような気がします。URLはエスケープしなくて良いのではないでしょうか? -- [[m0370]] &new{2022-04-23 (土) 08:15:48};
-- 自己解決しました。40行目付近の $jsonOption に多数入っているJSONのオプションに JSON_UNESCAPED_SLASHES を加えればエスケープしないようにすることができました。 -- [[m0370]] &new{2022-04-23 (土) 10:31:53};
- ご指摘ありがとうございます。クローラーの実装が正しければ、JSONデコードした後のURLを解釈するため、仕様としてはスラッシュがエスケープされていてかまわないはずです(むしろエスケープされているのが正しいJSON)。とはいえ、書式として違和感があり、人間が読みにくいのも確かです。もともと JSON_UNESCAPED_UNICODE などは単に好みで指定してましたし、対象処理系の都合で変えたい場合もありそうなので、エンコードオプションを定数化して書き換えやすくしました(PLUGIN_JSONLD_ENCODEFLAGS)。また、JSON_UNESCAPED_SLASHES もデフォルトで入れておきました。 -- [[M.Taniguchi]] &new{2022-04-23 (土) 12:34:32};
-- ちなみに、気になってW3CのJSON-LD文書を見てみると、記述例にあるURLはスラッシュをエスケープしてませんね。JSONの定義(RFC8259)でも、文字列内のスラッシュはエスケープ対象であると明記されている一方、やはり記述例にあるURLではスラッシュをエスケープしていません。基本的にはエスケープなしで、もし問題が生じたらエスケープするよう指定する、という運用でよさそうです。 -- [[M.Taniguchi]] &new{2022-04-23 (土) 13:09:59};
-- なお、そもそもなぜスラッシュがエスケープ対象になっているかというと、それを含む文字列がブラウザによってHTMLタグの一部(</...>)と誤解されるのを避けるためのようです。 -- [[M.Taniguchi]] &new{2022-04-23 (土) 13:32:38};
- Pukiwiki 1.5.4からs.inc.phpが標準装備となり短縮URLが利用できますが、デフォルトのjsonld.inc.phpのパンくずリストは短縮されていないURLを出力しますので、これを短縮URLに対応できるよう微修正しました。詳細は → https:// oncologynote.com/?66728a7710#f7926b39 -- [[m0370]] &new{2022-04-23 (土) 14:35:40};
-- 情報ありがとうございます。一つ訂正させてください。[[s.inc.php>Plugins/s.inc.php]] はPukiWiki 1.5.4でも標準装備ではありません (配布パッケージに同梱されていません)。 URLをカスタマイズしたい人が個別に導入するプラグインのままです。URLカスタマイズページに、もう少しわかりやすく書いておきます。 -- [[umorigu]] &new{2022-04-23 (土) 15:26:03};
- m0370さんの改造を参考に get_page_uri 関数に対応しました(要PukiWiki1.5.2以上)。なお、ページとして存在しない階層の扱いは好みが分かれそうなので、定数 PLUGIN_JSONLD_BREADCRUMBLIST_NOTEXISTPOS で制御できるようにしてあります。 -- [[M.Taniguchi]] &new{2022-04-24 (日) 05:46:05};
-- ちょっと気になったのが、s.inc.php を利用し、かつリダイレクトするよう設定した場合のURLです。JSON-LD・サイトマップ・OGPやcanonical指定に載せるべきなのはリダイレクト先の正規URLのため、「リダイレクト先URLがあればそちらを優先して返し、なければカスタマイズURLを返す」汎用手段が欲しいところ。なくても致命的ではありませんが気持ち悪く(JSON-LD等使うのはSEOに敏感な人たちなので)、クロール効率も若干落ちるでしょう。もっとも、この場合はURLカスタマイズ機能を使わずs.inc.phpのみ導入すればよいのかもしれませんが。 -- [[M.Taniguchi]] &new{2022-04-24 (日) 06:10:56};
-- 「ページに対してcanonical url を何にするか」の指定をするのがURLカスタマイズですので、ほぼ、そのような動作(リダイレクト先をcanonical urlにする)になっているはずです。s.inc.php の標準動作であれば、存在しないページに対しては短縮URL(のためのpage_id)が生成されず、PukiWiki標準のURLになります。[[dev:PageURI#summary]]#summary にプラグインでのページURL取得方法をまとめました。 -- [[umorigu]] &new{2022-04-24 (日) 14:41:08};
-- すみません、書き方が悪かったようです。ページの有無ではなく、カスタムURLとは別にcanonical URLがあるかないか、を問題にしていました。たとえば、あるページのcanonical URL「A」と、そこへリダイレクトする短縮URL「A'」があるとします(URLカスタマイズ機能とs.inc.php併用のリダイレクト設定)。このとき、get_page_uri関数で取れるのが「A'」のほうだとすると、「A」はどの関数で取れるのか、という疑問です。 -- [[M.Taniguchi]] &new{2022-04-24 (日) 19:24:35};
-- いろんな設定バリエーションがあるのですが、『たとえば、あるページのcanonical URL「A」と、そこへリダイレクトする短縮URL「A'」があるとします』→これが、[[パターン(7)>dev:BugTrack/2525#b55ec583]]だとすると、get_page_uri($page) で取得できるのは短縮URL A'でなく、リダイレクト先のAのURLになります。実のところパターン(7)は少し特殊で、ページURL自体は変わっておらず (「URLカスタマイズ」はしておらず) 、特定のURLパターンを捕まえてプラグイン呼び出しへ変換しているものです。これが(短縮URLをcanonical urlとする)[[パターン(6)>dev:BugTrack/2525#dee2c813]]や[[パターン(8)>dev:BugTrack/2525#t0659104]]になると、get_page_uri($page)で取得できるのは短縮URLの方になります。 -- [[umorigu]] &new{2022-04-24 (日) 22:58:35};
-- なるほどです、それなら問題ありませんね。試せばわかることなのに失礼しました。ご説明ありがとうございます。 -- [[M.Taniguchi]] &new{2022-04-25 (月) 03:42:51};
-- いえいえ実際試すのは試すのは大変ですし、、ページ名取得やURLカスタマイズについてはいろいろ考えて作ったところなので、こうやってうまく適用できることがわかるとうれしいです。ありがとうございます。 -- [[umorigu]] &new{2022-04-25 (月) 22:15:15};
-- いえいえ実際試すのは試すのは大変ですし、、ページ名取得やURLカスタマイズについてはいろいろ考えて作ったところなので、こうやってうまく適用できることがわかるとうれしいです。ありがとうございます。気になるところはどんどんコメントをお願いします。 -- [[umorigu]] &new{2022-04-25 (月) 22:15:15};

#comment

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Site admin: PukiWiki Development Team

PukiWiki 1.5.4+ © 2001-2022 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u12. HTML convert time: 0.109 sec.

OSDN