複数のグループで絞込み条件を指定したい

「まったく何も分からない・・・」そんなユーザーさんの為のフォーラムです。どんなご質問でもお気軽にどうぞ。
返信
bcacsato
パワーユーザー
記事: 233
登録日時: 2005年11月27日(日) 14:05

複数のグループで絞込み条件を指定したい

投稿記事 by bcacsato » 2012年7月31日(火) 17:59

マニュアル「6.3.6 URLパラメータからの動的な絞り込みの指定」のように、
「shopkind」「review」など複数のパラメータによる絞り込みを使ったページを作成中です。

そして、サイドバーに下記のようなナビゲーションを設け、
現在いるページが分かるよう、該当箇所はCSSで色を替えたいと思っています。

コード: 全て選択

<ul id="***">
 <li>中華
  <ul>
   <li>★★★</li>
   <li>★★</li>
   <li>★</li>
  </ul>
 </li>
 <li>和食
  <ul>
   <li>★★★</li>
   <li>★★</li>
   <li>★</li>
  </ul>
 </li>
 <li>洋食
  <ul>
   <li>★★★</li>
   <li>★★</li>
   <li>★</li>
  </ul>
 </li>
</ul>
そこで、パラメータの組み合わせによって<ul>にidを割り振り("***"部分)、
そのid値によって、特定の<li>のみにCSSを処理したいと考えています。

※例えば、「shopkind」が「中華」で「review」が「★★★」の場合は、
 id="chinese-3"のようなidを付与したい。

しかし、マニュアル「5.5.13 グループ絞込み条件を表示する。」では、
パラメータが1種類のみのため、複数のパラメータがある場合は
どうすればよいのかが分かりません。

各パラメータの組み合わせごとに埋め込みページを作ろうかと思ったものの、
パラメータの種類&それぞれの選択肢が非常に多いため、途方に暮れています。

いい方法がありましたら、ご教示くださいますようお願いします。

bcacsato
パワーユーザー
記事: 233
登録日時: 2005年11月27日(日) 14:05

複数のグループで絞込み条件を指定したい 2

投稿記事 by bcacsato » 2012年7月31日(火) 18:09

追記です。

今の質問の件ですが、<ul>に特定のidを割り振るのではなく、
該当する<li>にclassを付与する形でもかまいません。

※例えば、「shopkind」が「中華」で「review」が「★★★」の場合は、
 下記のように、「中華」の「★★★」の<li>に class="active" を付与する。

コード: 全て選択

<ul>
 <li>中華
  <ul>
   <li class="active">★★★</li>
   <li>★★</li>
   <li>★</li>
  </ul>
 </li>
どのような形でもかまいませんので、複数の条件がある場合に、
該当する組み合わせのページのナビのみデザインを変える方法がありましたら
教えてくださいませ。

webmaster
Site Admin
記事: 1451
登録日時: 2004年12月10日(金) 10:09

Re: 複数のグループで絞込み条件を指定したい

投稿記事 by webmaster » 2012年8月01日(水) 18:11

webmasterです。bcacsatoさん、いつもご質問ありがとうございます。また、回答が遅くなり申し訳ありません。

ご質問の件ですが、確かにこれはかなり複雑な部類のケースに入るかと思います。
XSLのいくつかの機能を組み合わせて、以下のように実現することが可能です。(動作チェックは行っておりませんので、ミスがありましたら申し訳ありません)

コード: 全て選択

	<!-- エントリ一覧のテンプレート開始 -->
	<xsl:template match="/entrylist">
	
		<!-- URLパラメータで指定された"shopkind"の絞込み値を取得し、$shopkindという変数に格納する -->
		<xsl:variable name="shopkind" select="group[@key='shopkind']/@value" />
		
		<!-- URLパラメータで指定された"review"の絞込み値を取得し、$reviewという変数に格納する -->
		<xsl:variable name="review" select="group[@key='review']/@value" />
		
		<!-- ナビゲーションの表示 -->
		<ul id="***">
			<li>中華
				<ul>
					<li><xsl:if test="($shopkind = 'chinese') and ($review = '3')"><xsl:attribute name="class">active</xsl:attribute></xsl:if>★★★</li>
					<li><xsl:if test="($shopkind = 'chinese') and ($review = '2')"><xsl:attribute name="class">active</xsl:attribute></xsl:if>★★</li>
					<li><xsl:if test="($shopkind = 'chinese') and ($review = '1')"><xsl:attribute name="class">active</xsl:attribute></xsl:if>★</li>
				</ul>
			</li>
			<li>和食
				<ul>
					<li><xsl:if test="($shopkind = 'japanese') and ($review = '3')"><xsl:attribute name="class">active</xsl:attribute></xsl:if>★★★</li>
					<li><xsl:if test="($shopkind = 'japanese') and ($review = '2')"><xsl:attribute name="class">active</xsl:attribute></xsl:if>★★</li>
					<li><xsl:if test="($shopkind = 'japanese') and ($review = '1')"><xsl:attribute name="class">active</xsl:attribute></xsl:if>★</li>
				</ul>
		</li>
各々の説明をさせて頂きます。非常にややこしいので、よくわからなければ、分かる範囲でそのままコピーしてお使いください。

まず、xsl:variableというタグですが、これはselect属性に指定した内容を、name属性に指定した名前の「変数」に格納し、他の場所で使えるようにするためのものです。
ここで、「group[@key='shopkind']/@value」というパスをselectに指定していますが、このパスは、「複数あるgroup要素(絞込み条件を指定した数だけこのgroup要素が存在します)のうち、keyが'shopkind'のものだけ抜き出し、そのgroup要素のvalue属性の値を選択せよ」というものになります。今回ですと、これでshopkindの絞込み条件を取得できます。このパスによって選択された絞込み条件を、「shopkind」という名前の変数に格納しています。変数名が絞り込み条件と同じになっているのは、単にわかりやすさの為で、ここは別の名前になっていても構いません。この「shopkind」という変数には、このデザイン定義の任意の場所で「$shopkind」と、先頭にドルマークをつけてアクセスすることができるようになります。

ともかくも、「$shopkind」という名前で、shopkindの絞込み条件を取得できるようになりました。

同じ方法で、「group[@key='review']/@value」というパスを使って「keyが'review'」の絞込み条件の値(@value)を選択し、$reviewという変数に格納しています。

そしてその下で、ナビゲーションの表示を行っています。
ここでは、それぞれのli要素について、たとえば「中華の★★★」を出力するli要素の中で、「もし、shopkindが'chinese'で、reviewが'3'なら」という条件分岐処理(xsl:if)を入れています。そして、「もしそうなら、li要素のclass属性に'active'を出力せよ」という命令を入れています。これがxsl:attribute要素です。

xsl:attribute要素は、直前の親要素に対して、任意の属性値を追加します。例えば次のように書くことができます。

コード: 全て選択

<a>
    <xsl:attribute name="href">http://cms.al-design.jp</xsl:attribute>CMS Designer
</a>
上記のように書くと、

コード: 全て選択

<a href="http://cms.al-design.jp">CMS Designer</a>
と出力されます。もちろん通常はxsl:ifと組み合わせて、ある条件のときに属性値を追加したりします。

以上のような方法で、今回のご要望は実現できるかと思います。

ところで今回、$shopkindと$reviewを、直接id名やclass名として出力させる、という方法も、やり方によっては有効かと思いますが、これは避けてください。

コード: 全て選択

<li class="concat($shopkind, '-', $review)">★★★<li> <!-- ※この内容にあまり意味はありませんが… -->
concat関数は、それぞれの引数に指定された文字列を全部連結して1つの文字列として出力します。この場合だと、'chinese-3'のような文字列を作ってclass名として出力できます。

しかしこうすると、非常に危険なセキュリティホールになります。$shopkindや$reviewは、URLパラメータとして任意の値を指定できますから、ページ中に攻撃者が任意の文字列を表示できることになってしまいます。絞込み条件を使う場合には、URLパラメータとして渡された内容を直接出力しないよう、十分ご注意ください。

以上、大変長く複雑で申し訳ありません。ご不明な点などありましたらなんなりとご質問ください。

bcacsato
パワーユーザー
記事: 233
登録日時: 2005年11月27日(日) 14:05

Re: 複数のグループで絞込み条件を指定したい

投稿記事 by bcacsato » 2012年8月02日(木) 06:22

webmasterさま
詳しいご回答ありがとうございます。

実際にはグループがもっとたくさん(10以上)あるのですが、その数だけ記述を増やせばよいということですね。
(増やしすぎると処理速度がかなり落ちるのでしょうか?)

さっそく試してみます!
取り急ぎ、お礼まで。

webmaster
Site Admin
記事: 1451
登録日時: 2004年12月10日(金) 10:09

Re: 複数のグループで絞込み条件を指定したい

投稿記事 by webmaster » 2012年8月02日(木) 19:11

webmasterです。お返事ありがとうございます。

グループの数が10以上というのは、shopkindの種類が10種類以上ある、というような感じでしょうか?
その場合であれば、特にパフォーマンスに大きく影響することはないと思います。

もし、shopkind以外にも絞込み条件がたくさんある、ということですと、場合によっては組み合わせの数が膨大になって、パフォーマンスというよりは記述量がとんでもないことになってしまうかもしれません…。

またご不明な点がございましたら、お手数ですがご質問頂ければ幸いです。

bcacsato
パワーユーザー
記事: 233
登録日時: 2005年11月27日(日) 14:05

Re: 複数のグループで絞込み条件を指定したい

投稿記事 by bcacsato » 2012年8月02日(木) 21:04

webmasterさま
ご回答ありがとうございます。

後者の場合で、絞込み条件が20近くあります。

記述量は多くなりましたが、おかげさまで、ご教示いただいた方法で、ほぼ希望通りの挙動とないました。

1点、分からないことがあるので、教えてください。

'review'の値に関係なく、'shopkind'ごとの全一覧も表示させたい場合もあるため、下記のように記述してみました。

コード: 全て選択

<ul>
	<li><xsl:if test="($shopkind = 'chinese') and ($review = '')"><xsl:attibute name="class">active</xsl:attribute></xsl:if><a href="list.php?shopkind=1">中華</a>
		<ul>
			<li><xsl:if test="($shopkind = '1') and ($review = '3')"><xsl:attibute name="class">active</xsl:attribute></xsl:if><a href="list.php?shopkind=1&review=3">★★★</a></li>
			<li><xsl:if test="($shopkind = '1') and ($review = '2')"><xsl:attibute name="class">active</xsl:attribute></xsl:if><a href="list.php?shopkind=1&review=2">★★</a></li>
			<li><xsl:if test="($shopkind = '1') and ($review = '1')"><xsl:attibute name="class">active</xsl:attribute></xsl:if><a href="list.php?shopkind=1&review=1">★</a></li>
		</ul>
	</li>
</ul>
このように、$review = '' としてみましたが、これではダメでした。
「パラメータの指定なし」という条件で絞込みをするには、どのように記述すればよいでしょうか?
最後に編集したユーザー bcacsato on 2012年8月03日(金) 05:31 [ 編集 1 回目 ]

webmaster
Site Admin
記事: 1451
登録日時: 2004年12月10日(金) 10:09

Re: 複数のグループで絞込み条件を指定したい

投稿記事 by webmaster » 2012年8月03日(金) 04:46

webmasterです。スペルミスおよび記述ミスの件、大変申し訳ありませんでした…。m(__;)m
余計にお時間を取らせてしまったかと思います。m(__;)m (元記事のほうは修正させて頂きます)

パラメータの条件が「なんでもいい」という場合には、xsl:ifのtest属性からその条件式そのものを削除してしまえば大丈夫です。
具体的には、

コード: 全て選択

 <li><xsl:if test="($shopkind = 'chinese')"><xsl:attibute name="class">active</xsl:attribute></xsl:if><a href="list.php?shopkind=1">中華</a>
とすれば大丈夫です。一般的な数学の四則演算のルールと同様に、式が1つなら()は不要なので、以下のようにしても大丈夫です(もちろん()をつけたままでもかまいません)

コード: 全て選択

 <li><xsl:if test="$shopkind = 'chinese'"><xsl:attibute name="class">active</xsl:attribute></xsl:if><a href="list.php?shopkind=1">中華</a>
いろいろとわかりにくく、ご不便をおかけしております。他にも、些細なことでも何かございましたらご連絡頂ければ幸いです。

bcacsato
パワーユーザー
記事: 233
登録日時: 2005年11月27日(日) 14:05

Re: 複数のグループで絞込み条件を指定したい

投稿記事 by bcacsato » 2012年8月03日(金) 05:30

webmasterさま
ご回答ありがとうございます。

ごめんなさい、私の書き方が悪かったです。
「'review'の値に関係なく」ではなく、「'review'の指定がないときのみ」で絞りこみたいです。
つまり、「パラメータの条件がなんでもいい」ではなく、「パラメータがない」場合のみで絞り込みたいのです。

例えば、URLが
『list.php?shopkind=1』 のときのみ class="active" を付与して
『list.php?shopkind=1&review=3』 のようなときは付与したくないのです。

このようなことも可能でしょうか?

webmaster
Site Admin
記事: 1451
登録日時: 2004年12月10日(金) 10:09

Re: 複数のグループで絞込み条件を指定したい

投稿記事 by webmaster » 2012年8月03日(金) 15:44

webmasterです。ありがとうございます、ご質問を理解できたと思います。

ご指摘のとおり、$review = '' という指定だと、「パラメータに空文字が指定されていた場合…(a)」に合致できますが、「パラメータそのものが指定されていない場合…(b)」には合致しないかと思います。

(a) 「パラメータに空文字が指定されていた場合」とは、具体的にはURL側で「http://sample.jp/page.php?shopkind=japa ... 終わっている場合です(=の後に何も指定されていない)。
(b) 「パラメータそのものが指定されていない場合」とは、URL側で「「http://sample.jp/page.php?shopkind=japa ... されていない場合です

(a)を検知するには、今回の場合ですと、「$review = ''」となり、(b)を検知するには、「not($review)」となります。not(データ名)の意味ですが、<xsl:if test="データ名">と書くと、そのデータ名が存在する場合、という意味になりますので、それをnotを使って否定し、「存在しない場合」を表現しています。

今回のケースに併せて、より具体的には、

コード: 全て選択

(a) <!-- shopkindが中華で、reviewパラメータに空文字が指定されている場合 -->
<li><xsl:if test="($shopkind = 'chinese') and ($review = '')"><xsl:attibute name="class">active</xsl:attribute></xsl:if><a href="list.php?shopkind=1">中華</a>

コード: 全て選択

(b) <!-- shopkindが中華で、reviewパラメータ自体がURLに指定されていない場合 -->
<li><xsl:if test="($shopkind = 'chinese') and not($review)"><xsl:attibute name="class">active</xsl:attribute></xsl:if><a href="list.php?shopkind=1">中華</a>
となるかと思います。今回、bcacsatoさんのご要望ですと、(b)が必要かと思いますので、何度も申し訳ありませんが、(b)のほうへ記述を変更してみてください。

<!-- --> の部分はコメントで、最終的なページには出力されません。おそらくここまで複雑になってくると、後でデザイン定義を見直したときに意味がわからなくなっている可能性があるので、できればこのサンプルのように、何をしているかを残しておいたほうが後々思い出すのに便利かもしれません。

もしうまく動作しなかった場合、お手数ですが再度ご連絡頂ければ幸いです。m(__)m

bcacsato
パワーユーザー
記事: 233
登録日時: 2005年11月27日(日) 14:05

Re: 複数のグループで絞込み条件を指定したい

投稿記事 by bcacsato » 2012年8月03日(金) 19:13

webmasterさま
ご回答ありがとうございます。

おかげ様で、期待通りの挙動となりました!!

今回もいろいろとお手数をおかけしまして、申し訳ありませんでした。
今後ともよろしくお願いいたします。

返信