エントリ一覧をランダムに表示

「まったく何も分からない・・・」そんなユーザーさんの為のフォーラムです。どんなご質問でもお気軽にどうぞ。
返信
nagashima
パワーユーザー
記事: 44
登録日時: 2007年5月26日(土) 15:52
お住まい: 東京

エントリ一覧をランダムに表示

投稿記事 by nagashima » 2007年10月17日(水) 18:44

いつもお世話になっております。

エントリリストのデータをランダムに並び替えることは可能でしょうか?

------------------------------------------------------------------
アーティスト詳細情報
<cmsd:entry name="artist1" design="default" />

アーティストが出しているCD
<cmsd:entrylist name="products1" design="default" cols="3" >
<cmsd:group key="artid" />
</cmsd:entrylist>
------------------------------------------------------------------

まずやりたいこととして
上記のようにアーティスト情報を表示させその下に
アーティストが出しているCDなどの情報をリストで
表示させます。

この時にアーティストが出しているCDを4つまで
表示させるようにしたいです。

「pageno="top" rows="4"」を埋め込みタグに追加すると
最新4件分が表示されますよね。

これだと4件より古くなってしまったCDはずっと
表示されなくなってしまうので、この部分を
ランダムに表示させたいということです。

xsl側でリストの中身をランダムに並べ替える方法が
あれば対応できるかなと漠然と思ったのですが
なかなか方法が見つかりませんでした。


ランダムで表示または古いCDもまったく表示されない
ということを回避する方法は何かありますでしょうか?


よろしくお願い致します。

以上です。

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

Re: エントリ一覧をランダムに表示

投稿記事 by webmaster » 2007年10月18日(木) 15:22

nagashimaさん、ご質問ありがとうございます。

一件分のランダム表示機能はあるのですが、一覧をランダムに表示する機能が無い為、
お手数をおかけしております。m(__)m

ランダム表示について、日付情報を使って擬似的にランダムを実現する方法を思いつき
ましたので、ご紹介します。
多分にプログラマ的発想になってしまいますのでデザイナーの方には難解かと思います
が、ご容赦下さい。最後にデザイン定義サンプルをまとめますので、そちらをご利用頂
くだけでもOKです。

まず、ver.1.1.5aより日付情報が取得できるようになっているので、これを利用します。
日付情報(today要素)の中には、@timeという、「1970年1月1日0時0分0秒」から
の経過秒数が取得できる項目があるので、まずこれを変数に入れます。

コード: 全て選択

<xsl:variable name="seed" select="/*/today/@time" />
「*」というのは「なんでもアリ」の意味で、/entry/today/@time でも
/entrylist/today/@time でもどちらでも動作するようにこうしました。今回は
エントリ一覧の話なので、/entrylist/today/@time でもOKです。

このseed変数は、画面を表示するたびに中身が変わります(例:1192688180)。
そこで、この値から、エントリの「n番目」のnを生成します。

nは1〜エントリ件数の範囲なので、seedをエントリ件数で割った「余り+1」が、
nとして使えそうです。

そこでエントリ件数を同じく変数に入れておきます。

コード: 全て選択

<xsl:variable name="entrycount" select="count(/entrylist/entry)" />
seed変数($seed)をエントリ件数で割った余りに1足したものが、ランダムな
エントリ番号になります。

コード: 全て選択

<xsl:variable name="randomindex" select="($seed mod $entrycount) + 1" />
これで準備が整いました。

コード: 全て選択

<xsl:for-each select="entry">
</xsl:for-each>
↑いつも書いているこの部分の代わりに、次のようにfor-eachを4つ作って下さい。

コード: 全て選択

<xsl:for-each select="entry[ $randomindex ]">
〜
</xsl:for-each>
<xsl:for-each select="entry[ $randomindex + 1 ]">
〜
</xsl:for-each>
<xsl:for-each select="entry[ $randomindex + 2 ]">
〜
</xsl:for-each>
<xsl:for-each select="entry[ $randomindex + 3 ]">
〜
</xsl:for-each>
select="entry" の部分を select="entry[ 数値 ]" と書くことで、指定番目の
エントリのみを選択することができるので、これを利用しています。
エントリ内の表示開始位置をランダムに決め、そこから4つ分、表示するように
なっています。

ただこのままですと、nの範囲が 1〜エントリ件数+3 になってしまう為、これを再度
エントリ件数で割った余りを求め、+1することで 1〜エントリ件数 の範囲に丸めます。

コード: 全て選択

<xsl:for-each select="entry[ (($randomindex) mod $entrycount) + 1 ]">
〜
</xsl:for-each>
<xsl:for-each select="entry[ (($randomindex + 1) mod $entrycount) + 1 ]">
〜
</xsl:for-each>
<xsl:for-each select="entry[ (($randomindex + 2) mod $entrycount) + 1 ]">
〜
</xsl:for-each>
<xsl:for-each select="entry[ (($randomindex + 3) mod $entrycount) + 1 ]">
〜
</xsl:for-each>
全てのデザイン定義をまとめると、以下のようになります。

コード: 全て選択

<xsl:template match="/entrylist">
	<!-- time値をランダムシードとして利用 -->
	<xsl:variable name="seed" select="/*/today/@time" />
	<!-- エントリ件数を取得 -->
	<xsl:variable name="entrycount" select="count(/entrylist/entry)" />
	<!-- 1〜エントリ件数の範囲のランダムな値を生成 -->
	<xsl:variable name="randomindex" select="($seed mod $entrycount) + 1" />

	<!-- ランダム位置のエントリを4つ出力 -->
	<xsl:for-each select="entry[ (($randomindex) mod $entrycount) + 1 ]">
	〜
	</xsl:for-each>
	<xsl:for-each select="entry[ (($randomindex + 1) mod $entrycount) + 1 ]">
	〜
	</xsl:for-each>
	<xsl:for-each select="entry[ (($randomindex + 2) mod $entrycount) + 1 ]">
	〜
	</xsl:for-each>
	<xsl:for-each select="entry[ (($randomindex + 3) mod $entrycount) + 1 ]">
	〜
	</xsl:for-each>

</xsl:template>
cmsd:entrylistタグでは、rowsに99999等の大きな値を指定して下さい。

以上、試していないのでミスなどあるかもしれませんが、一度お試し下さい。
※cols属性を指定している場合、うまく動作しないと思います。その場合はまたご連絡下さい。

nagashima
パワーユーザー
記事: 44
登録日時: 2007年5月26日(土) 15:52
お住まい: 東京

Re: エントリ一覧をランダムに表示

投稿記事 by nagashima » 2007年10月18日(木) 17:34

webmaster様

詳しくご説明してくださりありがとうございます!!
大変勉強になります。
一件分のランダム表示機能はあるのですが、一覧をランダムに表示する機能が無い為、
お手数をおかけしております。m(__)m
一件分のランダム表示機能についてはマニュアルか他のトピックかなにかに
方法はかかれていますでしょうか?

今回は使用しないとおもいますが、今後のために知っておきたいと思いまして。

※cols属性を指定している場合、うまく動作しないと思います。その場合はまたご連絡下さい。
実は今回はCMSの組込みを依頼されておりまして、
どのようなコーディングの形式になるか特定できておりません。

ですがサンプルのHTMLを頂いておりまして、
おそらくテーブルを使用されるかと思われます。
なのでcols属性を指定することになると思います。

ちょっと思ったのですが、例えば2×2のテーブルの場合、
今回の場合エントリ1件ごとに<xsl:for-each>文を用意しているので、
埋め込みタグにcols属性を指定せずデザイン定義にて各<xsl:for-each>文に対応する
テーブルタグを記述すればできるものですかね?

すいません試す前に質問してしまいまして。

これから試してみますが一応考え方としてどうかなと思いましたので。

よろしくお願い致します。

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

Re: エントリ一覧をランダムに表示

投稿記事 by webmaster » 2007年10月18日(木) 18:07

 nagashimaさん、お返事ありがとうございます。

 一件分のランダム表示については、マニュアルにも記載されてはいるのですが、
cmsd:entryタグの説明のところにちょこっと書いてあるだけなので、気づかれない
ようです。分かりにくくて申し訳有りません。

 利用方法は、cmsd:entry要素のeid属性に、"random"と指定するだけです。

 もう一点、テーブルで表示する方法ですが、今回のサンプルのxsl:for-eachの
各々4つを、テーブルのセルの中に入れてやればOKです。

コード: 全て選択

<table>
  <tr>
    <td>
      <xsl:for-each select="entry[ 〜 ]" />
    </td>
    <td>
      <xsl:for-each select="entry[ 〜 ]" />
    </td>
  </tr>
  <tr>
    <td>
      <xsl:for-each select="entry[ 〜 ]" />
    </td>
    <td>
      <xsl:for-each select="entry[ 〜 ]" />
    </td>
  </tr>
</table>
 総エントリ数が4件未満の場合、該当のセルは空欄になりますので、それを想定
したCSS装飾を行って下さい。

 ただ、これぐらい単純であれば、CSSを使ってレイアウトした方が楽かも
しれません。
 この部分はCMS Designerとは離れてしまいますが、こちらで簡単に
解説しています。
 http://cms.al-design.jp/phpbb/viewtopic.php?t=448

 CSSを使えば、将来表示件数が増えても簡単に対応可能ですし、4件未満
だった場合にも問題なく表示できます。

nagashima
パワーユーザー
記事: 44
登録日時: 2007年5月26日(土) 15:52
お住まい: 東京

Re: エントリ一覧をランダムに表示

投稿記事 by nagashima » 2007年10月18日(木) 23:35

webmaster様

早速のお返事ありがとうございます。

試させていただきます。
結果がでましたら報告させていただきます。

一件分のランダム表示につきましてもありがとうございました。

返信