Share on FacebookTweet about this on TwitterShare on Google+

この記事はconcrete5 Japan Advent Calendar 2016の19日目の記事です。12日の記事はtomoya.phさんのconcrete5.6.x の逆襲!です。
concrete5.7.*でPage Selector Attributeを使ってページの相互連携は以外と簡単だったという話です。

プログラムを書ける人には、なんだそれ?って話かもしれませんが、フロントエンドやデザインの人はこんな事でも役立つかと思います。
自分が調べた事を残しておくようにconcrete5のアドオンを日本語紹介するサイトを作っています。

http://c5addon.com/

年末は追われて更新が滞ってますか..(汗)
さて、このサイトまずアドオンの紹介をほぼconcrete5.orgと同じような内容で日本語の少し解説をつけて「アドオン(addon)」というページタイプで作っています。

http://c5addon.com/addon/tweet-feed-1

それとは別に「レビュー(review)」というページタイプで機能の紹介ページを作成しています。

http://c5addon.com/review/twitter

別にした理由は、1つのアドオンに対してレビューを複数作る場合があるためです。
思いついた時に使うシーンごとに追加できるようにしたかったのと、これから複数のアドオンを使ったレビューも想定されるからです(ほんとにやれよ俺!)。

こんな感じの構成です。

flow

レビュー側には、どのアドオンの事なのかアドオンのページへの連携がされています。
page_selector_attribute_iconこれはPage Selector Attributeを使っています。

Page Selector Attributeはページ選択を属性(Attribute)に追加できるアドオンです。

ページとテーマの属性メニューを選択

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-12-19-11-11-44

「レビュー(review)」というページタイプに使用アドオンという属性を追加します。
そうすることで、他のページへの連携をコンポーザーや属性設定からサイトマップで選択することが可能です。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-12-19-11-14-09
リンクした情報はページIDで保持されるために、ページの階層を移動しても問題ありません。

さて今度はアドオン側にこのアドオンに関わるレビューを出したいわけですが、これもPage Selector Attributeで設定していってもいいのですが、せっかくレビュー側でリレーションを貼っているのでだから、それを使えないの?と思いました。
つまりPage Selector Attributeで自分を設定したページをページリストで自動で検索するという事です。
そこで、下記のページリストオブジェクトの記事を参考に

http://concrete5-japan.org/help/5-7/developer/working-with-pages/searching-and-sorting-with-the-pagelist-object/

PHPなんちゃっての私でもconcrete5のPageList オブジェクトを使えば、こんなのでいいの?ってコードでできちゃいました。

flow_connectこういう構成です。
concrete5の構造の恩恵を受けれるありがたみです。

$page = Page::getCurrentPage();
$list = new \Concrete\Core\Page\PageList();

まずは今のページのオブジェクトを$pageに格納します。この$pageで様々な現在表示しているページの属性を取得できます。
次に$listというページリストオブジェクトを作成。この時点ですべてのページのリストを表示するオブジェクトです。ただし実際に検索をかけているわけではありません。実行したら、そうなるよという事です。

$list->filterByPageTypeHandle('review');

次にレビューのページだけが対象なので、ページタイプのハンドル名でフィルターをかけます。これでレビューページだけのリストになりました。

$list->filterByAttribute('use_addon', $page->getCollectionID());

そしてPage Selector Attributeで作った使用アドオンという属性が自分のページであるページを絞り込みます。filterByAttributeは属性で絞り込みをかけるもので、使用アドオンのハンドルタイプをuse_addonにしましたので、その値に$page からgetCollectionID()でページIDを入れます。
sortByPublicDateDescendingで日付の降順でソート。
最後にgetResultsで実行してページリストのデータを取得します。

$list = new \Concrete\Core\Page\PageList();
$list->filterByPageTypeHandle('review');
$list->filterByAttribute('use_addon', $page->getCollectionID());
$list->sortByPublicDateDescending();
$pages = $list->getResults();

全部書いてもたったこの5行で、それだけのデータが取得できます。すごいですね〜PageListオブジェクト。
あとは

foreach ($pages as $reviewpage):
echo $reviewpage->getCollectionName();
endforeach;

などでデータを表示できます。
リンクをそれぞれのページオブジェクトから取り出すのは、ヘルパーが用意されています。

$nh = Loader::helper('navigation');//ナビゲーションヘルパー
//
//
//
foreach ($pages as $reviewpage):
$hrf = $nh->getLinkToCollection($reviewpage);//リンクのURLを取得
$pname = $reviewpage->getCollectionName();//ページ名を取得
endforeach;

Loader::helper(‘navigation’)でナビゲーションヘルパーで、getLinkToCollectionでページオブジェクトからそのページのリンクするURLの属性を抽出できます。
ページ送りを表示するのも標準的なコードであれば、コードを書く必要はありません。

$pagination = $list->getPagination();
if($pagination->getTotalPages() > 1):
print $pagination->renderDefaultView();
endif;

getPaginationでリストからページ送りのオブジェクトを取得。getTotalPagesでもしページ数が1ページ以上なら、renderDefaultViewでページ送りのコードを表示する。
あとフロントエンド側のCSSでいかようにも装飾できます。

Page Selector Attributeで選ばれたページを検索するという使い方は、まだまだ利用価値があると思っています。
是非活用例など、他にあればどんどん教えてください。

明日12/20はfujigoco2255さんです。インフォグラフィックとな!楽しみ楽しみ。