このページで、紹介している Breadcrumb NavXTは、WordPress公式テーマRaindrops にアドオンとして、付属しています。
テーマをインストールしてから、プラグインをインストールアクティベートしていただくと、テーマカスタマイザーの設定だけで、テンプレートを編集することなく自動的に表示されます。(すでにアクティベート済みの場合は、テーマインストール後、停止、再アクティベートしてください)
また、和暦表示機能をカスタマイザーで有効にした場合、アーカイブページ等でパンくずリストが、和暦で表示されます。
簡単にこのプラグインの機能を使いたい方や、テーマで独自実装をする場合に、お役に立つかもしれませんので、一度お試しください。
Breadcrumb NavXTパンくずリストのカスタマイズを考える
WordPressにパンくずリストプラグインBreadcrumb NavXTを設置する
たくさんのプラグインがあるようですが、ここでは、breadcrumb NavXTの利用について考えて行きたいと思います
具体的なインストールの方法等は、解説サイトがたくさんありますのでそちらを参照してください。
プラグインを有効化して、テンプレートの適当な場所に、関数を記述すると、簡単に使い始める事が出来ますが、使っていくうちに、物足りなかったり、特別な動作が必要になったりします。
このページでは、カスタマイズのサンプル事例を交えながら、パンくずリストの利用を考えてみたいと思います。
パンくずリストを使っている人が、なんとからなないかと思っている事
1. 複数カテゴリに属する投稿の場合、カテゴリの表示が常に一つ、状況によって、他のカテゴリへのリンクを表示したい
2. ページを表示した場合には、トップページの表示は必要ないといった事柄、
3. 画像でリンクを表示したいとか、デザイン上の観点からの変更
このような、ユーザーインターフェースの設計上や視覚的な問題に対する対応が、どのように可能なのか、むしろ、1から作ったほうが簡単なのか、メモに残そうと思います。
パンくずリストを表示するためのテンプレート関数について、
最も簡単な例。
関数を一つ記述するだけで、自動的にパンくずリストを表示する事が出来ます。
<?php if ( function_exists( 'bcn_display' ) ) { bcn_display(); } ?>
パンくずリストを変数に入れる
では、次に、パンくずリストの出力を、変数の中に入れてみます
第一引数がtrue だと、returnします
<?php if ( function_exists( 'bcn_display' ) ) { $my_bread= bcn_display(true); echo $my_bread; } ?>
なので、
正規表現などでの抽出や置換も出来そうです。
if ( function_exists( 'bcn_display' ) ) { $bread= bcn_display(true); preg_match( '!([^(> |<)]+$)!', $bread ,$regs); echo $regs[1]; }
パンくずリストを出力する関数は、bcn_display()だけでなく、bcn_display_list()もあり、同様の引数が使えます。
なのでCSSによる表示のコントロールも工夫次第かもしれません。
パンくずリストのテンプレートとは
では、次に、管理画面のオプションからの設定項目の テンプレートに着目してみます。
上の画像は、設定画面の一部ですが、このプラグインの設定項目の各所に、この templateという項目を見つけることが出来ます。
これは、リンクを記述するhtmlのプレースホルダになります。
画像の例だと、サイトホームのリンクは以下のhtmlに%link%など、%を両端に持つ項目が、出力の時にURLなどに置換されます。
<a title="Go to %ftitle%." href="%link%" class="%type%">%htitle%</a>
テンプレートで利用できるタグと拡張方法
設定項目としてテンプレートのカスタマイズが許されているわけですが、どんなタグが許容されるのでしょうか?
このフィールドは、wp_kses()によって、入力値がチェックされていて、利用可能なタグと属性が決められています。
このフィールドには、以下の要素が利用できるようになっているようです。
<a>, <img>, <span>
項目によっては 以下も許可されているようです。
<h1>, and <h2>
これらの要素以外を利用可能にするためには、以下のようなフィルタを使う事で解決できます。
function my_bcn_allowed_html($allowed_html){ $allowed_html['li']= array( 'title'=> true, 'class'=> true, 'id'=> true, 'dir'=> true, 'align'=> true, 'lang'=> true, 'xml:lang'=> true, 'aria-hidden'=> true, 'data-icon'=> true, 'itemref'=> true, 'itemid'=> true, 'itemprop'=> true, 'itemscope'=> true, 'itemtype'=> true ); return $allowed_html; } add_filter('bcn_allowed_html', 'my_bcn_allowed_html');
詳細については、How to Add li and Other Tags to Breadcrumb Templatesを参照してください。
デフォルトで許可されている要素が、span と img である事を考えると、リンクの画像化できますよというはっきりとしたメッセージが伝わってきます。
CSSによるデザインの追加
img 要素を使ったナビゲーションだけでなく、CSSを使った画像ナビゲーションの例は、
をみてください。この表示には、bcn_display_list()を使います。
プラグインの特徴を知る事で、なんとなくいろんなことが出来そうだなという感じがしてきたと思います。
さらに、もう少し深度をさげて、プラグインの奥のほうをのぞいてみましょう。
パンくずリストを使っている人が、なんとからなないかと思っている事
1. 複数カテゴリに属する投稿の場合、カテゴリの表示が常に一つ、状況によって、他のカテゴリへのリンクを表示したい
フォーラムを探すと、同じ思いの人が見つかりました
リンクオブジェクトの操作
複数の親カテゴリが表示されるべきでないとしても、この場面でだけは、こっちのリンク使いたいよね等といった事はあるでしょう。
bcn_after_fill action hook
このフィルタは、リンクとして表示されるそれぞれの、リンクオブジェクトが格納されているので、リンク単位で、オーバーライドする事が出来るようになっています。
do_action('bcn_after_fill', $this);
では、アクションを作ってみます。
現在、なにもしていないパンくずリストは、以下のようになっています。
add_action('bcn_after_fill', 'foo_pop'); function foo_pop($trail){ //該当ページのタイトルが if( $trail->trail[0]->get_title()== 'mago' ){ unset( $trail->trail[2] ); } }
とすると
このように、2階層上のリンクを消す事が出来ました。
少し何かが見えてきた感じがします。
次に
add_action('bcn_after_fill', 'change_link'); function change_link($trail){ if( $trail->trail[0]->get_title()== 'mago' ){ $new_item= new bcn_breadcrumb( 'relate page', '<a title="%ftitle%." href="%link%">%htitle%</a>', array('external-link'), 'http://www.tenman.info') ; $trail->trail[2]= $new_item; } }
パンくず構造を変更するためのヘルパープラグイン
- http://ja.forums.wordpress.org/topic/25300?replies=11(b:@quot)
- http://mtekk.us/archives/wordpress/plugins-wordpress/specifying-a-preferred-category-hierarchy/(b:Specifying a Preferred Category Hierarchy「好ましいカテゴリー階層の指定」)というプラグインがあるようです。
投稿でカテゴリを指定するようです。
実用的なパンくずリストSEOと設置のドタバタ
パンくずリストの表示と、カスタマイズの可能性について、ここまで、少し乱暴ではありますが、みてきました。
私たちが、このパンくずリストを実際に使用する場合に、どんな事をしなければならないでしょうか?
例えば、このパンくずリストによって作られたリンクが、他のナビゲーションリンクと重複したり、title属性でのうまいタイトルになっているかなど、アクセシビリティの観点や、検索エンジンがより理解しやすくなるような、html構造を作り出す努力も必要になります。
その入り口になる例をリンクしておきます、それぞれの現場での工夫の参考になればいいと思います。
ドタバタ 日付階層に年や日が表示されない
さらに、ここまで書いてしまったので、実際にこのサイトに、パンくずリストを設置する上での、試行錯誤についても、触れておきたいと思います。
ここで使っているワードプレステーマは、Raindropsというテーマで、チャイルドテーマを使っています。
このテーマの場合、hook-after-nav-menu.php というテンプレートファイルを作成して、パンくず用のコードを書いてしまえば、今表示されているようにみる事が出来ます。
実際にテンプレートに記述したコードは、以下のようなものです。
<div class="breadcrumbs"> < ?php if(function_exists('bcn_display')){ $bread= bcn_display( true ); if( ! is_home() ){ echo $bread; } } ?> </div>
これで、一見正常に表示が行えているようでした。
投稿の階層設定を、日付にした時に問題が発生しました。
上の画像を見ると、2013には、年 日付の 21には、日が表示されていません。
ここで、再び、慌てふためくわけです。
年と日を追加する作業が必要になりました。
最初に、とにかく問題を回避するために、書いたコードは、以下のようなものでした。
theme/hook-after-nav-menu.php
<div class="breadcrumbs"> <?php if ( function_exists( 'bcn_display' ) ) { $bread= bcn_display( true ); $before= array( '!>([0-9]{4})<!', '!m=([0-9]{8})">([0-9]{1,2})<!', '!m=([0-9]{8})">([0-9]{1,2})<!', '!([0-9]{4}$)!', '!([0-9]{1,2}$)!' ); $after= array( '>${1}年<', 'm=$1">${2}日<', 'm=$1">${2}日<', '${1}年', '${1}日' ); $bread= preg_replace( $before, $after, $bread ); if( ! is_home() ){ echo $bread; } } ?> </div>
何とか、表示が正常になるように出来たので、次にまた、コードを読むことになりました。
それぞれのリンクのデータを、テンプレートに反映させる function assemble()というメンバー関数を見つけて、そこにあるフィルターを使う事にしました。
書いたコードは、以下のようなものです。
theme/functions.php
add_filter( 'bcn_template_tags', 'my_template_tags_change_date', 10, 3 ); function my_template_tags_change_date( $replacements, $type, $id ){ if( WPLANG== 'ja' ){ $this_type= implode( ',',$type ); if( preg_match( '!date-year!',$this_type ) ) { $replacements["%htitle%"]= $replacements["%htitle%"].'年'; } if( preg_match( '!date-day!',$this_type ) ) { $replacements["%htitle%"]= $replacements["%htitle%"].'日'; } return $replacements; } return $replacements; }
なぜ、このようなコードをさらし、既に表示の修正は、一つ目でうまくいっているのに、もう一度コードを書き直そうとしたのか、その理由もこの際書いてみたいと思います。
一度目のコードは、PHPの正規表現で、とにかく年と日を追加してしまえ、というコードです。
表示は、うまくいっていても、パンくずリストが書き出すhtmlがちょっと代わってしまっただけで、どのように表示されるか検討もつきません。
また、この表示は、このテンプレートを修正する事でしか変更できません。プラグインやテーマのfunctions.phpから更に修正を加えるといった道が閉ざされます。
パーマリンクの設定を変更したりすれば、表示は正常に行われなくなる事は、容易に理解していただけると思います
なので、このコードだと、パンくずリストのアップデートなど怖くて出来ないわけです。
2番目のコードは、WordPressのカスタマイズでは基本の フィルタ を使っています。
フィルタを使うコードを書く事で、更に表示を書き換える事もできるようになり
カスタマイズの柔軟性があがります。
例えば、このブログのタイトル下の日付表示には、和暦表示を行っていますが、このような表示方法に変更変更する事も出来るようになるかもしれません
この変更は、他のプラグインからでも、テーマのfunctions.phpからでも、コントロールが出来るようになります。
なにより、このパンくずリストの制作者は、そのようなカスタマイズの可能性を理解したうえで、既にその方法を提供してくれています。
よいプラグインやテーマは、何らかの事情で問題が発生しても、そこで動かなくなってしまうだけでなく、問題回避するためのいろいろな方法を準備しています。
オープンソースは、残念ながら詳細な解説書が準備されている事はまれですが、私たちが思う以上に、様々な事を考慮してくれているという事を書いておきたい
Aside
WordPress snippet では、これまで、ワードプレスに関するアイディアなどのメモを中心にお届けしてきました。
特定のプラグインに関する話題を提供するのが、おそらく初めての事になると思います。
たった一行で表現されるパンくずリストですが、実際にコードを読み始めると、作者のいろいろな思いがちりばめられている事が解ります。
たいていの場合、( 私を含めて、)プラグインを利用する人たちは、コードを読むなんて事はありません。
プラグインをインストールし、「自分が使うに値するかどうか」をすばやくチェックし、他のプラグインと比較して、優劣を即座に決めるのが普通の姿だと思います。
この点は、制作者にとっては、まるで欠席裁判を受けるような、過酷な決定である事は少なくありません。
WordPressコアも、サードパーティのプラグインやテーマも、コードそのものは、古い書き方であったり、遅れている感があったりする事もあります。
数年前、WordPressをはじめて使うようになった頃、何年も使い続けられているだけに、ちょっと古臭くて、なんだかなぁと思っていた時期がありました。
よりよいものは、膨大にあります。
でも、よいものだからといって、みなが支持し、ファンになり、使い続けるかというとそうではありません、
オープンソースのほとんど99パーセント以上は、失敗に終わるという事を、私は依然として信じています
無償で、誰でも簡単に使い捨てられるオープンソースの世界に、果敢に挑戦し続けている多くの制作者に思いをはせると、「誰かに支持されて、利用される」ということの重さを改めて感じる機会になりました。
付録 アクションフック・フィルタリスト
Breadcrumb NavXT Action hooks and filters
- Plugin Name: Breadcrumb NavXT
- Plugin URI: http://mtekk.us/code/breadcrumb-navxt/
- Description: Adds a breadcrumb navigation showing the visitor’s path to their current location. For details on how to use this plugin visit
Breadcrumb NavXT.
- Version: 4.4.0
- Author: John Havlik
- Author URI: http://mtekk.us/
- License: GPL2
- TextDomain: breadcrumb-navxt
- DomainPath: /languages/
Note: protected $unique_prefix= 'bcn';
- breadcrumb_navxt_admin.php
$this->opt= apply_filters($this->unique_prefix . '_settings_init', $this->opt);
- breadcrumb_navxt_admin.php
do_action($this->unique_prefix . '_settings_general');
- breadcrumb_navxt_admin.php
do_action($this->unique_prefix . '_settings_current_item');
- breadcrumb_navxt_admin.php
do_action($this->unique_prefix . '_settings_home');
- breadcrumb_navxt_admin.php
do_action($this->unique_prefix . '_settings_blog');
- breadcrumb_navxt_admin.php
do_action($this->unique_prefix . '_settings_mainsite');
- breadcrumb_navxt_admin.php
< ?php do_action($this->unique_prefix . '_after_settings_tab_general'); ?>
- breadcrumb_navxt_admin.php
if(!apply_filters('bcn_show_tax_private', $taxonomy->public, $taxonomy->name))
- breadcrumb_navxt_admin.php
if(!apply_filters('bcn_show_cpt_private', $post_type->public, $post_type->name))
- breadcrumb_navxt_admin.php
if(!apply_filters('bcn_show_tax_private', $taxonomy->public, $taxonomy->name))
- breadcrumb_navxt_admin.php
do_action($this->unique_prefix . '_after_settings_tab_post');
- breadcrumb_navxt_admin.php
if(!apply_filters('bcn_show_tax_private', $taxonomy->public, $taxonomy->name))
- breadcrumb_navxt_admin.php
do_action($this->unique_prefix . '_after_settings_tab_taxonomy'); ?>
- breadcrumb_navxt_admin.php
< ?php do_action($this->unique_prefix . '_after_settings_tab_miscellaneous'); ?>
- breadcrumb_navxt_admin.php
if(!apply_filters('bcn_show_cpt_private', $post_type->public, $post_type->name))
- breadcrumb_navxt_admin.php
if(!apply_filters('bcn_show_tax_private', $taxonomy->public, $taxonomy->name))
- breadcrumb_navxt_admin.php
if(!apply_filters('bcn_show_tax_private', $taxonomy->public, $taxonomy->name))
- breadcrumb_navxt_class.php
$this->allowed_html= apply_filters('bcn_allowed_html', wp_kses_allowed_html('post'));
- breadcrumb_navxt_class.php
$this->title= apply_filters('bcn_breadcrumb_title', $title, $this->type, $this->id);
- breadcrumb_navxt_class.php
$this->url= esc_url(apply_filters('bcn_breadcrumb_url', $url, $this->type, $this->id));
- breadcrumb_navxt_class.php
$this->template= wp_kses(apply_filters('bcn_breadcrumb_template', $template, $this->type, $this->id), $this->allowed_html);
- breadcrumb_navxt_class.php
$replacements= apply_filters('bcn_template_tags', $replacements, $this->type, $this->id);
- breadcrumb_navxt_class.php
$breadcrumb= $this->add(new bcn_breadcrumb(apply_filters('the_author', $curauth->$author_name),...
- breadcrumb_navxt_class.php
return apply_filters('post_type_archive_title', $object->labels->name);
- breadcrumb_navxt_class.php
do_action('bcn_before_fill', $this);
- breadcrumb_navxt_class.php
do_action('bcn_after_fill', $this);
- includes\mtekk_adminkit.php
$this->allowed_html= apply_filters($this->unique_prefix . '_allowed_html', wp_kses_allowed_html('post'));