murave

baserCMSのサイトマップをカスタマイズ

baserCMS のバージョンは 2.0.1 です。

baserCMSにはサイトマップを出力するヘルパーがあって、

sitemap() ?>

と書くと固定ページについてはサイトマップを自動で更新してくれて便利です。

なのですが、いろいろと不満もあるヘルパーです。

  • 固定ページ以外(Blogとかメールフォーム等)はダメ。
  • カテゴリのindexにページ名をつけるとカテゴリとページで同じURLが表示されてダブる。

てなわけでカスタマイズしました。

baser/views/helpers/bc_baser.php を読んでヘルパーの仕組みを調べると再帰的にページをたどっていること、テンプレート baser/views/elements/sitemap.php を使用していることが分かりました。

検討した結果、「固定ページ以外はダメ」に関して根本的な解決は出来ないのですがテンプレートのカスタマイズで対応することにしました。
データの取得方法から変更した独自ヘルパーの作成も考えたのですが、結局どこかに「Blogやメールフォームを何処に表示するか」という情報を持たせなければならないので完全自動化はできない。それならデータ取得は既存の方法を使って必要な追加設定はテンプレート内で配列にでももたせるか、と。

まず、baserCMS カスタマイズの常道としてbaserディレクトリのファイルを自分のテーマの同階層にコピー。これでコピーしたファイルが有効になるのでこのファイルを改造していきます。

改造した結果、こうなっちゃいました。

//ここから設定
//表示しないurl
$disables = array(
'/index_test',
);

//$inserts = array(before_url=>array(title, url),,,)
//before_urlの次に挿入url,titleで作成したアイテムを挿入
//ブログ、メールフォームなどpage以外を途中に挿入することが出来る。
$inserts = array(
'/sitemap' => array('新着情報', '/news'),
'/news' => array('お問い合わせ', '/contact'),
'/it-model/faq' => array('ダウンサイジングについてのお問い合わせ', '/contact_itmodel'),
);
//設定ここまで

//関数
$outputPageItem = function ($recursive, $title, $url) use (&$bcBaser) {
?>link($title, $url) ?>link($title, $url);
else:
echo $category_title;
endif;
echo PHP_EOL;
};
$outputCategoryItemTail = function () {
?>
element('sitemap', array(
'pageList' => $pageCategories['children'],
'category_title' => $category_title,
'category_url' => $category_url,
'recursive' => $recursive+1
));
endif;
if($outputed_category_li):
$outputCategoryItemTail();
endif;
endforeach;
endif; ?>


「カテゴリのindexにページ名をつけるとカテゴリとページで同じURLが表示されてダブる」のは解消。
追加設定に特定ページを表示したくない時のための$disables配列、Blogやメールフォームを思い通りの場所に挿入するための$inserts配列を用意することで希望する表示ができるようになりました。

しかし、元テンプレートからかけ離れているのはともかくとして、

basercmsのエレメント内で無名関数を定義して再帰呼び出しやってやったぜ〜。ワイルドだろ?
— murave (@murave) June 15, 2012

てなことをやってるので万人にはオススメできない。無名関数を使っているのでPHP5.3以降限定ですし。

関数を定義したのは「処理をパーツ化しないとコードがあまりにもカオス」「処理を再帰呼び出しする必要があった」からです。
無名関数を使ったのは「関数の影響範囲を限定したかった」から。テンプレートが複数回呼び出しされるので関数の再定義エラーがでるという問題もありましたが、これは無名関数にしなくても未定義の場合のみ関数を定義するようにすれば回避できると思います(試してませんが)。