ページ 11

更新日から月別バックナンバーを作りたいのですが・・・

Posted: 2007年6月27日(水) 09:35
by mi
はじめまして。こんにちは。
CMS Designer を試用中の初心者です。

更新日を元に月別のバックナンバーを作ってみたいと思っています。
ブログでよくあるようなタイプのものです。
フォーラムを読みながら試してみたのですが
うまく実現できないので、ご教授いただければ幸いです。

一番近い考え方は
http://cms.al-design.jp/phpbb/viewtopic.php?t=714
の記事にあるようなことだと思います。
前の年月を変数に取っておいて
比較するという処理でいいのかとは思うのですが
一度設定した変数にもう一度値を代入するようなことができないようで
初期値を設定して、ループ内で前の年をセットしようとすると
以下のようなエラーになってしまいます。

Warning: Sablotron error on line 87: conflicting variable bindings 'saveyear' in

また、初期値なしで、ループさせようとしても
変数がありませんよ、というメッセージが出てしまうようで
どう処理してよいものか模索しています。

Warning: Sablotron error on line 24: variable 'saveyear' not found in


ソースコードは以下のようなもので実験中です。

コード: 全て選択

<!--初期値をセット(年月としてありえないものを初期値として一回目の値と比較する)-->
<xsl:variable name="saveyear" select="9999" />
<xsl:variable name="savemonth" select="99" />

<!--バックナンバー表示開始-->
<xsl:for-each select="entry">
	<xsl:if test="$saveyear!=@year">
	<xsl:value-of select="@year" />
		<xsl:if test="$savemonth!=@month">
		<xsl:value-of select="@month" />
		</xsl:if>
	</xsl:if>
<xsl:variable name="saveyear" select="@year" />
<xsl:variable name="savemonth" select="@month" />
</xsl:for-each>

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

Posted: 2007年6月27日(水) 10:00
by tsu
後者の場合だと、xsl:varibleを先に置いておかないとエラーになると思います。

コード: 全て選択

<!--バックナンバー表示開始-->
<xsl:for-each select="entry">
<xsl:variable name="saveyear" select="@year" />
<xsl:variable name="savemonth" select="@month" />
   <xsl:if test="$saveyear!=@year">
   <xsl:value-of select="@year" />
      <xsl:if test="$savemonth!=@month">
      <xsl:value-of select="@month" />
      </xsl:if>
   </xsl:if>
</xsl:for-each>

Re: 更新日から月別バックナンバーを作りたいのですが・・・

Posted: 2007年6月27日(水) 10:55
by webmaster
 miさん、ご質問ありがとうございます。
 miさんはきっととてもセンスのあるプログラマーなのだと思います。
 私もプログラミングを長くやっているので、以前同じ事で躓いたことが
あります。
 
 仰る通り、xsl:variableは一般のプログラミング言語における「変数」
とはちょっとちがいます。
 これは単なる一時的なデータ保管場所であり、上書きすることができません。
 
 xsl:for-eachなどのループの中で作った変数はループの度に新しく作られる為、
上書きするような感じで使用することができます。しかし、「前回のループの
時の値」を保存しておこうとしても、不可能です。
 
 この為、「前回のループの時の値」は、別の視点から取得します。
 
 「前回のループ」を、「1つ前のposition()」という式で取得します。
 具体的にはfor-eachループの中で次の式を使って取得します。
 

コード: 全て選択

<xsl:variable name="position" select="position()" />
<xsl:variable name="preyear" select="/entrylist/entry[$position-1]/@year" />
 
 "/entrylist/entry[1]" と書くと、1つめのエントリデータを取得できます。
 この仕組みを使って、現在の位置の1つ前($position-1)のエントリデータを
取得しています。
 
 positionは1から開始する為、最初のエントリでは「0番目」のエントリを参照
しにいってしまいますが、存在しないエントリの場合は自動的に空文字が入ります
ので問題ありません。

 以上、ちょっと動作を試している時間がない為ソースコードに誤りがある
かもしれませんが、一度お試し下さい。

 ご不明な点がありましたら再度ご質問頂ければ幸いです。

Re: 更新日から月別バックナンバーを作りたいのですが・・・

Posted: 2007年6月27日(水) 14:34
by mi
tsuさん、webmasterさん、早速のお返事ありがとうございます。
レスが早いと、やる気のモチベーションが維持できていいですね♪

コード: 全て選択

<xsl:variable name="position" select="position()" />
<xsl:variable name="preyear" select="/entrylist/entry[$position-1]/@year" />
授けてくださった情報を元に試してみました。
このまま実行してみたら以下のようなエラーが表示されました。
「$position-1」のような書き方ができないのかな?と思います。

Warning: Sablotron error on line 10: variable 'position-1' not found in

そこで、少し考え方を変えて、記述を以下のようにしてみました。
こちらは成功です☆
<xsl:variable name="position" select="position()-1" />
<xsl:variable name="preyear" select="/entrylist/entry[$position]/@year" />
これらのことを踏まえて月別バックナンバーを作ることができました。
時間を割いてくださってありがとうございます。

私が目指したバックナンバーの表示は
記事の投稿のある月だけをナビゲーションとして設置し
その月をクリックしたら対象の月だけの見出しリストを表示するようなものでした。


■月別バックナンバー
2007年 06月 04月 01月 | 2006年 11月 | 2005年 03月



表示としては上のような感じです。
実行しているソースコードは以下のようになっています。

コード: 全て選択

<!--バックナンバー表示開始-->
<xsl:for-each select="entry">
	<xsl:variable name="position" select="position()-1" />
	<xsl:variable name="saveyear" select="/entrylist/entry[$position]/@year" />
	<xsl:variable name="savemonth" select="/entrylist/entry[$position]/@month" />
	<!--前の年が空の時-->
	<xsl:if test="not($saveyear)">
		<xsl:value-of select="/*/today/@year" />年
		<a href="infomation2.php?(ここに年と月の引数を書く)">
		<xsl:value-of select="@month" />月</a>
	</xsl:if>
	<!--前の年がエントリーの年と同じ時-->
	<xsl:if test="$saveyear=@year">
		<xsl:if test="$savemonth!=@month">
			<a href="infomation2.php?(ここに年と月の引数を書く)">
			<xsl:value-of select="@month" />月</a>
		</xsl:if>
	</xsl:if>
	<!--前の年がエントリーの年と違う時-->
	<xsl:if test="$saveyear!=@year">
		 <xsl:value-of select="@year" />年
		 <xsl:if test="$savemonth!=@month">
			<a href="infomation2.php?(ここに年と月の引数を書く)">
			<xsl:value-of select="@month" />月</a>
		</xsl:if>
	</xsl:if>
</xsl:for-each>
そこで、また問題が出てきました。
引数の受け渡し方がよくわからなくて、バックナンバーの記事リストが表示できません。
年と月から対象エントリーを絞り込もうと思っているところです。

ソースコード中に(ここに年と月の引数を書く)と書いた箇所が値を渡す部分を記しました。
また、受け方はどのようにすればいいのか・・・
説明書にあるような「@id」とはタイプが違うようで・・・

何かヒントになるようなことでもいいので
手がかりをご教授願えませんでしょうか?よろしくお願いします。

Re: 更新日から月別バックナンバーを作りたいのですが・・・

Posted: 2007年6月27日(水) 15:13
by webmaster
 miさん、お返事ありがとうございます。

 $position-1 については、おそらく「$position-1」という名前の変数として
扱われてしまっているのだと思います。すいません、確認不足でした。

 「$position - 1」のように、スペースを使ってマイナスの両側に空間を空ければ
問題ないと思いますが、miさんの解決方法もスマートですね。

 そして、次のご質問なのですが・・・申し訳ありません、現在、CMSDには
「月別」や「年別」に絞込みをするという機能がございません。m(__;)m

 デザイン定義を使って絞込みを行おうにも、任意のパラメータをデザイン定義側
へ渡す機能もまだ実装されていない為、実現することができません。

 最近、カレンダー関係のご要望が多く、皆さまにはご迷惑をおかけしております。
 機能追加に精進して参りますので、今回はどうかご容赦下さい。m(__)m

ありがとうございました

Posted: 2007年6月27日(水) 15:46
by mi
webmasterさま、ありがとうございました。
ちょっとした記述の違いで、できたり、できなかったりなのですね。
なるほど、厳密ですわ。

絞込みの件、今後の発展に期待しております。