MODXでカテゴリー分け
Wordpressには標準でカテゴリー、タグの機能はついていますが、MODXの場合には自分でどうにかしなければなりません。いくつかの考え方として、
- コンテナごとにわけてサブリソースで記事を作成していく(カテゴリーの設定は一つのみ)
- テンプレート変数でカテゴリーを作成し、Dittoの&extenders=`tagging`を使用する
- 記事・カテゴリーは別のコンテナで管理し、テンプレート変数で関連付ける
今回は3番目の「記事・カテゴリーは別のコンテナで管理し、テンプレート変数で関連付ける」をおこないます。まずは下記を参考にしてください。
目標
- カテゴリーやタグを追加した際に自動でテンプレート変数の選択肢に追加される
- カテゴリーやタグの記事でのリンク表示
- カテゴリーやタグの記事一覧でのリンク表示
- 関連付けられている記事のカウント
- カテゴリーの多層化には対応しない
自動でテンプレート変数に追加
1.コンテナの作成
コンテナのリソースで、記事・カテゴリー・タグを作成します。記事は「ウェブリンク」で[(site_url)]にリダイレクトさせます。
2.テンプレート変数の作成
それぞれテンプレート変数の「カテゴリー」と「タグ」を作成します。
まずリソースの構成は下記のようになっています。
テンプレート変数「カテゴリー」
一つだけ選択できて、規定値を「未分類」(リソースID7)にします。
入力フォーム:Radio Options
オプション:@SELECT `pagetitle` AS `name`,`id` FROM `[+prefix+]site_content` WHERE `published` = 1 AND `deleted` = 0 AND `parent` = 3 ORDER BY `menuindex` ASC
規定値:@@EVAL:
$default = 'uncategorized';
$alias = 'category/'.$default;
return $modx->getIdFromAlias($alias);
プロセッサ:設定しない
テンプレート変数「タグ」
複数設定できて、規定値は設定しません。
入力フォーム:Check Box
オプション:@SELECT `pagetitle` AS `name`,`id` FROM `[+prefix+]site_content` WHERE `published` = 1 AND `deleted` = 0 AND `parent` = 4 ORDER BY `menuindex` ASC
プロセッサ:Delimited List
プロセッサの設定:,
両者ともにテンプレート「記事」に関連付けます。そうするとコンテナ「記事」のサブリソース新規作成時に下記のようになります。
これで目標の一つ目は達成。
記事にカテゴリーとタグのリンク表示
1.テンプレートの作成
親テンプレートは「xRay」を使用します。従って、実際に出力する部分だけ書いていきます。
テンプレート「記事」
「記事」コンテナのサブリソースに設定します。
<p>カテゴリー:[*カテゴリー*] / タグ:[*タグ*]</p>
[*content*]
適応されると下記になります。
リソースIDが表示されますね。Dittoのパラメータ「documents」で表示してもいいですが、今回はカスタムモディファイアを使います。
スニペット名:phx:category
スニペットコード:if($value == '')return ' - ';
if($opt == '')$opt = ',';
$delim = $opt;
if(strpos($value,$delim) !== false){
$out = array();
$ids = explode($delim,$value);
foreach($ids as $id){
$url = $modx->makeUrl($id);
$title = $modx->getField('pagetitle',$id);
$alias = $modx->getField('alias',$id);
$out[] = '<a href="'.$url.'" class="'.$alias.'">'.$title.'</a>';
}
return implode(',',$out);
}elseif(is_numeric($value)){
$url = $modx->makeUrl($value);
$title = $modx->getField('pagetitle',$value);
$alias = $modx->getField('alias',$value);
$out = '<a href="'.$url.'" class="'.$alias.'">'.$title.'</a>';
return $out;
}else{
return ;
}
これで、テンプレートのタグにモディファイアを付けて、[*カテゴリー:category*]、[*タグ:category*]に変更すると下記のようにリンクが表示されます。
これで目標二つ目が達成されました。
記事一覧にカテゴリーとタグのリンク表示
テンプレート「記事一覧」
ホーム(記事一覧)、カテゴリー(サブリソース含む)、タグ(サブリソース含む)に「記事一覧」をテンプレートに設定します。
<!--@IF:[*id:is(3):or:is(4)*]>
<ul>
[[Ditto
&parents=`[*id*]`
&tpl=`@CODE:<li><a href="[+url+]">[+title+]</a></li>`
]]
</ul>
<@ENDIF-->
<!--@IF:[*id:is(`[(site_start)]`)*]>
[[Ditto
&parents=`2`
&id=`entry`
&display=`5`
&orderBy=`publishedon DESC`
&paginate=`1`
&tpl=`post.item`
]]
<@ENDIF-->
<!--@IF:[*id:ne:(`[(site_start)]`):and:ne(3):and:ne(4)*]>
[[Ditto
&parents=`2`
&id=`entry`
&display=`5`
&orderBy=`publishedon DESC`
&filter=`[*parent:pagetitle*],[*pagetitle*],7`
&paginate=`1`
&tpl=`post.item`
]]
<@ENDIF-->
[+entry_previous+][+entry_pages+][+entry_next+]
チャンク:post.item
<div style="border:solid 1px #ccc;padding:20px;margin:10px;">
<h3><a href="[+url+]">[+title+]</a></h3>
<p>作成日:[+pub_date:ifempty(`[+publishedon+]`):date(%Y年%m月%d日)+] / カテゴリー:[+カテゴリー:category+] / タグ:[+タグ:category+]</p>
<p>[+content:summary+]</p>
</div>
カスタムモディファイアの「category」をすでに作成しているので、Dittoのテンプレートにもそのまま使用できます。結果は次のようになります。
きちんと記事一覧にもリンクで表示されています。
記事のカウント
カテゴリー、タグが関連付けられている記事をカウントします。
カスタムモディファイアを作成します。array_columnはPHP5.5以降です。それ以前の場合はforeachを入れ子にするなどの別の記述が必要です。
スニペット名:phx:docCount
スニペットコード:
$docId = $value;
if($docId == '')$docId = $modx->documentIdentifer;
$archives = $modx->getDocumentChildrenTVars($parentid= 2, $tvidnames= array('カテゴリー','タグ'), $published= 1, $docsort= 'menuindex', $docsortdir= 'ASC', $tvfields= 'name');
$list = array();
foreach($archives as $archive){
$list = array_merge($list, array_column($archive,'value'));
}
foreach($list as $ids){
if (substr($ids, 0, 1) != '@'){
$out[] = $ids;
}else{//規定値に@Bindingsを使用している場合
$out[] = $modx->ProcessTVCommand($ids);
}
}
$out = implode('||',$out);
$out = explode('||',$out);
$count = array_count_values($out);
return '('.$count[$docId].')';
テンプレート「記事一覧」を変更します。
<!--@IF:[*id:is(3):or:is(4)*]>
<ul>
[[Ditto
&parents=`[*id*]`
&tpl=`@CODE:<li><a href="[+url+]">[+title+]</a></li>` //変更前
&tpl=`@CODE:<li><a href="[+url+]">[+title+][+id:docCount+]</a></li>` //変更後
]]
</ul>
<@ENDIF-->
こうなります。
MODXは簡単なコードで機能が追加できるけれども、思い通りにやるにはPHPの勉強が必要かもしれませんね。