公開XSLT

特に話題を問いません。お好きな話題をどうぞ。
返信
tsu
パワーユーザー
記事: 208
登録日時: 2006年1月16日(月) 12:00
お住まい: さいたま

公開XSLT

投稿記事 by tsu » 2006年10月12日(木) 01:10

CMSDesigner上での色々なXSLTの使い方をのんびり紹介するトピック

tsu
パワーユーザー
記事: 208
登録日時: 2006年1月16日(月) 12:00
お住まい: さいたま

menuitemのカテゴリ表示

投稿記事 by tsu » 2006年10月13日(金) 17:39

webmasterさんが紹介してくださった定義を自分用に変えた程度のものです。
http://cms.al-design.jp/phpbb/viewtopic.php?t=546
カテゴリ(5)などを表示させたい場合に使います。

自分なりに頑張って説明を書いたのですが、意味が間違ってる可能性が高いのであまり参考にしないで下さい。
変な箇所がありましたら指摘して下さると助かります。

#########################################
※070306コード修正
<data name="select"〜を
<data name="categoryselect"〜へ
もしかすると動かない可能性アリなので動かなかったらごめんなさい。
近いうちにテストサイトを改造するのでその時にでも試してみます。
#########################################

使用するスキーマ

コード: 全て選択

<?xml version="1.0" encoding="UTF-8"?>
<schema name="test" caption="menuitemでカテゴリ実験用スキーマ" title="select" >
    <data name="title" type="text" output="html1" caption="タイトル" />
	<data name="description" type="textarea" output="html1" caption="本文" />
    <data name="categoryselect" type="menu" caption="カテゴリ選択" group="True">
		<menuitem id="other">その他</menuitem>
		<menuitem id="perl">Perl</menuitem>
		<menuitem id="xml">XML</menuitem>
		<menuitem id="js">JavaScript</menuitem>
		<menuitem id="xslt">XSLT</menuitem>
		<menuitem id="ruby">Ruby</menuitem>
		<menuitem id="php">PHP</menuitem>
	</data>
</schema>
デザイン定義

コード: 全て選択

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="EUC-JP" omit-xml-declaration="yes" />

<!-- スキーマファイルからmenuitem要素を読み込み、$category という変数に格納する -->
<xsl:variable name="category" select="document('test.schema.xml')/schema/data[@name='categoryselect']/menuitem" />

<!-- エントリ一覧のテンプレート開始 -->
<xsl:template match="/entrylist">
<h2>カテゴリ</h2>

<!-- エントリのmenuitem要素を$categoryselectに格納 -->
<xsl:variable name="categoryselect" select="entry/categoryselect" />

<!-- カテゴリのリストを出力 -->
<ul>
<xsl:if test="not(entry)">
<li>まだ情報が登録されてません</li>
</xsl:if>
<!--登録されているエントリ数をカウント-->
<li><a href="testlist.php"><xsl:value-of select="concat('全(',(count(entry)),')件あります')" /></a></li>
<!--$categoryつまりmenuitem要素をループ処理-->
<xsl:for-each select="$category">
<!--menuitemの属性idを$categoryidに格納-->
<xsl:variable name="categoryid" select="@id" />

<!--menuitemのid属性とtext()が一致してる中身があるものだけ処理する、なければ処理しない-->
<!--/***********************************************************************************
説明するのが難しいですが、例えばmenuiteが100個あるとします。
そのうちの20個はエントリで指定して使っているが、残りの80個は使って無いので表示されなくてもいい。
つまり、エントリで指定されているmenuitem項目だけを表示したい場合。という意味です。
<xsl:if test="$select/text()">としてしまうとエントリが0件でも100個全て表示されます。
***********************************************************************************/-->
<xsl:if test="$categoryselect[text()=$categoryid]/text()">
<li>
<!--絞り込みするurlパラメータをidで指定-->
<a href="testlist.php?select={@id}">
<!--text()を出力しmenuitemのidと中身が一致するものをカウント-->
<xsl:value-of select="concat(text(),'(',(count($categoryselect[text()=$categoryid])),')')" />
</a>
</li>
</xsl:if>
</xsl:for-each>
</ul>   

</xsl:template>
</xsl:stylesheet>
また、各カテゴリ別エントリ、全エントリ、を表示する際にmenuitemの中身を表示させたい場合のデザイン定義

コード: 全て選択

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="EUC-JP" omit-xml-declaration="yes" />

<!--スキーマファイルの読み込み-->
<xsl:variable name="category" select="document('test.schema.xml')/schema/data[@name='categoryselect']/menuitem" />

<!--テンプレート開始-->
<xsl:template match="/entrylist">
<xsl:variable name="categoryselect" select="entry/categoryselect" />

<!--コードの場所を探すのが面倒なので、エントリ1件分を表示させるURLを変数に格納しておく-->
<xsl:variable name="entry_1">http://cmsd.pdy.jp/test.php</xsl:variable>

<!--タイトル部分-->
<h1>日記
	<xsl:if test="(count(entry/categoryselect['@id'])<=2) or (count(entry/categoryselect['@id']) =1)">
	<xsl:value-of select="concat(':カテゴリ【',$category[$categoryselect=@id]/text(),'】の一覧')" />
	</xsl:if>
	<xsl:if test="not((count(entry/categoryselect['@id']))<=2)">
	:全件表示
	</xsl:if>
</h1>

<!--カテゴリ説明-->
<div>
<xsl:if test="not(entry)">
<p>まだ情報が登録されてません</p>
</xsl:if>
</div>

<!--エントリ出力-->
<xsl:for-each select="entry">
<div>
	<div><xsl:value-of select="concat(@year,'年',@month,'月',@day,'日')"/></div>
	<h5><xsl:value-of select="title" disable-output-escaping="yes" /></h5>

	<div>
	<xsl:if test="string-length( description ) > 100">
	<xsl:value-of select="substring( description, 1, 100 )" disable-output-escaping="yes" /><a href="{$entry_1}{@href}">続きを読む</a>
	</xsl:if>
	
	<xsl:if test="string-length( description ) < 100">
	<xsl:value-of select="description" disable-output-escaping="yes" />
	</xsl:if>
	</div>

</div>

</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
最後に編集したユーザー tsu on 2009年1月24日(土) 15:15 [ 編集 4 回目 ]

tsu
パワーユーザー
記事: 208
登録日時: 2006年1月16日(月) 12:00
お住まい: さいたま

concat関数

投稿記事 by tsu » 2006年10月13日(金) 18:13

日時を表示させたいときは

コード: 全て選択

<div>
(<xsl:value-of select="@year" />-<xsl:value-of select="@month" />-<xsl:value-of select="@day" />)
</div>
とすれば「 (2006-10-13) 」と表示されます。
個人的になのですが、テキストエディタを使って書いている都合、
上記のように書くと長くて見づらいのです。

なのでconcat関数を使い少しすっきりさせます。

コード: 全て選択

使い方:
文字列は「'」で囲います。繋げ方は「,」を使います。
<xsl:value-of select="concat('文字列',title)" />

上記の例
<div>
<xsl:value-of select="concat('(',@year,'-',@month,'-',@day,')')" />
</div>

tsu
パワーユーザー
記事: 208
登録日時: 2006年1月16日(月) 12:00
お住まい: さいたま

listitemのソート

投稿記事 by tsu » 2006年10月13日(金) 19:00

リスト項目を追加すると、追加した項目は昇順で1.2.3.4.5.........と並びます。
新しいものが後ろになってしまいます。

エントリを並べ替えたりする場合にはコンテンツマネージャで出来るのでとても便利ですが、新しい順で並べる場合には並べ替え機能は使いません。
新しい順で並べ替える場合は<xsl:sort />を使います。

コード: 全て選択

<!--リストをループ処理-->
<xsl:for-each select="listname/listitem">
<!--idでソートする orderで昇順/降順を指定する。デフォルトは昇順「ascending」-->
<xsl:sort select="@id" order="descending" />
.
.
.
.
</xsl:for-each>


さとう
アクティブユーザー
記事: 24
登録日時: 2007年2月01日(木) 21:22

気がついたこと

投稿記事 by さとう » 2007年2月09日(金) 02:57

はじめまして、count関係の勉強中でこのログを見つけました。
なかなか難しくてまだ良く理解できていないのですが、
とても参考になり、助かっています。

1つ気になったのですが、

コード: 全て選択

<data name="select" type="menu" caption="カテゴリ選択" group="True">
nameがselectだとタグ?のselectと混同してしまいそうになるので、
別の名前にした方が良いのではないでしょうか。
そんな所でこんがらがるのは私だけかもしれませんが・・・。

tsu
パワーユーザー
記事: 208
登録日時: 2006年1月16日(月) 12:00
お住まい: さいたま

投稿記事 by tsu » 2007年2月28日(水) 20:10

あわわ、久しく見てませんでした。
CMSDのバージョンアップも知りませんでした(泣)

さとうさんご指摘ありがとうございます。
しばらく触ってないせいか、どれもゴチャゴチャしててわかりにくい気がしてきました。
その部分は「特に」ですね、書き直しておきます。

こんなグチャグチャしたのを参考にしてもらえるなんて嬉しいです。
今後も忘れないように書いていきます。


そういえばさっき思いついたのですが、コメント機能が出来そうで出来なさそうです。
出来なかったら恥ずかしいので「出来ません」と書いておきます。

tsu
パワーユーザー
記事: 208
登録日時: 2006年1月16日(月) 12:00
お住まい: さいたま

投稿記事 by tsu » 2007年3月07日(水) 01:56

さっき直したのですが久しぶりに触ったのでなんか緊張してしまいました。
ついでにPHPで作ったフォーム用のCGIも、久しぶりに見たらなんだかわからなくて悲しかったです。

サイトの改造するのでまた新しい事にも挑戦してみようと思います。
その中で使えそうなのがあったらまた少しずつ載せていこうと思います。

そういえば、雑談フォーラムで初めて絡みました。
他の方も何か気になる事があったら書いてくれると色々出来て面白いかもしれません。

luis
アクティブユーザー
記事: 20
登録日時: 2007年1月08日(月) 17:35

収集リスト

投稿記事 by luis » 2007年9月18日(火) 22:46

tsuさん、よろしくお願いします。

収集リストができました。使ってくださる方がいたらうれしいです。
例ではCDですが、スキーマを少し変えれば蔵書やご当地キティストラップとかいろいろできそうです。

[.htaccess]
RewriteEngine on
RewriteRule ^([a-z]+)([0-9]+)/toc([0-9]+)\.html$ contents/$1.table.php?pageno=$3&class=$2 [L]
RewriteRule ^([a-z]+)([0-9]+)/([0-9]+)\.html$ contents/$1.text.php?eid=$3&class=$2 [L]

[cmsd/config/schema/music/music.schema.xml] スキーマ
<schema name="music" caption="CD" title="title">
<data name="class" type="menu" caption="ジャンル" group="True">
<menuitem id="1">J-POP</menuitem>
<menuitem id="2">演歌</menuitem>
</data>
<data name="title" type="text" caption="アルバム名" />
<data name="artist" type="text" caption="アーティスト" />
<data name="note" type="textarea" caption="メモ" output="html2" />
</schema>

[cmsd/config/schema/music/music.list.top.design.xsl] トップの内容(エントリ一覧)用
[cmsd/config/schema/music/music.list.text.design.xsl] 目次の内容(エントリ一覧)用
[cmsd/config/schema/music/music.text.design.xsl] 記事の内容(個別エントリ)用

[cmsd/config/schema/music/music.list.title.design.xsl] 目次の上部ナビ・タイトル用
[cmsd/config/schema/music/music.title.design.xsl] 記事の上部ナビ用
<xsl:if test="class='1'">J-POP</xsl:if><xsl:if test="class='2'">演歌</xsl:if>

[cmsd/config/schema/music/music.list.navi.design.xsl] 目次の下部ナビ用
<xsl:for-each select="navi"><xsl:for-each select="next"><a href="toc{@id}.html" rel="next">次へ</a></xsl:for-each> | <xsl:for-each select="prev"><a href="toc{@id}.html" rel="prev">前へ</a></xsl:for-each> | <a href="../" rel="start">トップへ</a></xsl:for-each>

[cmsd/config/schema/music/music.navi.design.xsl] 記事の下部ナビ用
<xsl:for-each select="navi"><xsl:for-each select="next"><a href="{@id}.html" rel="next">次へ</a></xsl:for-each> | <xsl:for-each select="prev"><a href="{@id}.html" rel="prev">前へ</a></xsl:for-each> | <a href="toc1.html" rel="contents">目次へ</a> | <a href="../" rel="start">トップへ</a></xsl:for-each>

[index.php] トップ
<?php require_once( "cmsd/include/view.php.inc" ); ?>
<body>
<h1>サイト名</h1>
<div id="toc"><ul><li><a href="music/toc1.html">J-POP</a></li>
<li><a href="music/toc2.html">演歌</a></li></ul></div>
<div id="news"><cmsd:entrylist name="music" design="top" rows="5" pageno="top" /></div>
</body>

[contents/music.table.php] 目次
<?php require_once( "../cmsd/include/view.php.inc" ); ?>
<body>
<div id="top_navi"><cmsd:entrylist name="music" design="title" rows="1"> < サイト名</div>
<h1><cmsd:entrylist name="music" design="title" rows="1"></h1>
<div id="body"><cmsd:entrylist name="music" design="text" rows="20"><cmsd:group key="class" /></cmsd:entrylist></div>
<div id="bottom_navi"><cmsd:entrylist name="music" design="navi" rows="20" navigation="on"><cmsd:group key="class" /></cmsd:entrylist></div>
</body>

[designs/bgi1.gif] J-POP記事用壁紙
[designs/bgi2.gif] 演歌記事用壁紙

[contents/music.text.php] 記事
<?php require_once( "../cmsd/include/view.php.inc" ); ?>
<head>
<style type="text/css"><!--
body {background:url('../designs/bgi<cmsd:entry name="music" dataname="class" />.gif')}
--></style>
</head>
<body>
<div id="top_navi"><cmsd:entry name="music" dataname="title" /> < <a href="toc1.html" rel="contents"><cmsd:entry name="music" design="title" /></a> < サイト名</div>
<h1><cmsd:entry name="music" dataname="title" /></h1>
<div id="body"><cmsd:entry name="music" design="text" navigation="on"><cmsd:group key="class" /></cmsd:entry></div>
<div id="bottom_navi"><cmsd:entry name="music" design="navi" navigation="on"><cmsd:group key="class" /></cmsd:entry></div>
</body>

問題点等
music.schema.xml: レーベル、曲目一覧、Amazonアソシエイトプログラムの個別商品リンク、評価など適当なものを追加。下記の実行時ソートをする場合は、アーティストカナをグループ指定。
index.php: 新着リストは絞り込みをしていないので全ジャンルの中から新着5件が表示されます。そのため、記事へのリンクがあると変になります。
music.table.php: 投稿順(新着順)になっているので、アーティスト順にしたい場合は実行時ソートをする。事前ソートだとトップの新着リストが変になります。
music.text.php: 同上。

tsu
パワーユーザー
記事: 208
登録日時: 2006年1月16日(月) 12:00
お住まい: さいたま

投稿記事 by tsu » 2007年10月09日(火) 03:03

しばらく見てませんでした、、、。

luisさん素敵なサンプルありがとうございます!
私も色々作りたいなーとか思うのですが時間&アイデア(+スキル不足)がなくグダグダです。
あ、出来ればコード部分はCodeで括って頂けると見易いかもしれません。

それとサイト見せてもらったのですがかわいくてきれいですね。
私はセンスないので見習いたいです。

そういえばCMSDって管理画面でshema編集出来たら良いのになぁと前から(ry
あああ、メニュー周りが使い易くなれば便利なのに。
PHP5に移行する際に実装されることを期待しない程度に祈ろう。

返信