カスタマイズ講座

ホーム > カスタマイズ講座 > 【初級】カスタマイズ > なにかとお世話になるSmarty関数について(その3)

なにかとお世話になるSmarty関数について(その3)

【初級】カスタマイズ6
2008.11.06 (更新日: 2009.06.05)

みなさん、こんにちは。

先生、ちょっと前に自転車が壊れました。(いきなり脱線トーク)

マウンテンバイクなんですけども、なんかですねぇ・・・ペダル回してもタイヤ動かないんです。

前に回そうが後ろに回そうが・・・延々空回り(汗

かと思ったら唐突に、いきなり「ガキン!」と金属音を放って、今度はタイヤと連動してペダルが前や後ろに回る回る。

さらにチェーンが龍の如く暴れ回ったりなんかして・・・・・・ああもう、なんかもうすごいことになったわけです。

まぁ、結論としては、後輪の一番デリケートな部分がゴリゴリに錆付いてたのが原因だったらしく、タイヤホイール丸ごと交換で解決しました。

ちなみに自転車のタイヤホイールって、前輪と後輪セットで注文するんですよね。

というわけで、修理にかかった費用、しめて18,500円ナリ・・・(苦




キンタ先生の、最近買った高価なもの。




車輪。




せつない。





・・・さてさて。
「なにかとお世話になるSmarty関数について」シリーズも、今回で3回目になりました。

前回の授業では、「if」と「else」、ついでに「assign」と、基礎的なSmarty関数の読み書きについて学びました。

じゃあ今回は何かと言うと・・・「section」です。
EC-CUBE上で使われている関数の中でも、けっこうな頻度で登場するのがこの「section」。

今回はSmartyの読み書きの幅が広がりますよー!




「section」ってどういう意味?
簡潔に言ってしまえば、「ループ処理させる時に使う関数」ですね。
・・・と、言い切ってしまったらSmartyの勉強にならないので、もう少し詳しく説明しますw

「section」とは、データベースから何らかのデータを取得し、それを細かな条件付きでループ処理させて表示する際に利用する関数です。

ちなみに、同じループ処理をする関数として「foreach」というものがあります。
ここでは詳細な説明はしませんが(今回の主役は「section」ですのでw)、この2種の主な違いとしては、

「foreach」よりも、「section」の方が、細かな条件や設定を用いてループ処理することができる

という感じです。

・とりあえずループさせたい時は「foreach」
・表示するデータやデザインを細かく設定したい時は「section」

といった把握をしておくと良いでしょう。


では早速、ここでカンタンな「section」文の例を見てみましょう。

<!--{section name=data loop=$arrNews}-->
<dl>
<dt><!--{$arrNews[data].news_date_disp|date_format:"%Y年%m月%d日"}--></dt>
<dd>
<!--{$arrNews[data].news_title|escape|nl2br}--><br />
<!--{$arrNews[data].news_comment|escape|nl2br}-->
</dd>
</dl>
<!--{/section}-->


ちなみにこのsection文は、「新着情報」のブロックで実際に使われているものを、説明用に分かりやすくしたものです。

では、上から順に詳細説明していきましょう。

<!--{section name=data loop=$arrNews}-->


この冒頭の記述が、section関数ですね。
「name=data」と書かれた部分は、「セクション名」と言います。
基本的にここは、英数字であればどんな名前でも構いません。
「name=gundam」でもいいですし、「name=negitoro」でもOKです。

ただ、なんでもかんでも適当に付ければいいのかと言うと、そうでもありません。
上記の例の中をよーく見てみましょう・・・

<!--{$arrNews[data].news_title|escape|nl2br}-->


・・・このように、セクション名と同じ名称(data)が記述されている箇所がありますね。
セクション名は、こうやってループ処理上でも利用されるんです。

で、これはナゼかと言うと・・・例えば新着情報の場合を想像してみてください。
HTMLタグなどはループ処理して全部一緒でも構いませんが、記事タイトルなどはそれぞれ違いますよね?

つまり「セクション名」は、ループする度に違う情報を処理したり表示したりするための“印”のような感じで使われているワケです。

例えば、以下のような感じでsection文を書いた場合、セクション名が“印”の役割を果たしていないのでエラーが起こります。

<!--{section name=datadaze loop=$arrNews}-->
<!--{$arrNews[data1nano].news_title|escape|nl2br}-->
<!--{/section}-->

「datadaze?data1nano?セクション名はどっち?
統一されてねぇから、どうループしていいかわかんねぇよ!」 by Smarty



まぁ、ここは「name=data」のように解りやすい名前にしておきましょう、ってことですねw


さて、今度は「loop=$arrNews」と書かれた部分ですが、これは、「属性(引数)」と言います。
「loop=$arrNews」はその中でも「Loop属性」と呼ばれるものです。
まぁつまり、“何の情報をループさせるのか”を、指定しているような部分ですね。
ちなみにこの記述の場合は、「$arrNews(つまり新着情報)が全部表示しきるまで」という指定をしていることになります。

EC-CUBEをデフォルトでインストールした場合、「新着情報」が入力した分だけズラーーーーッとトップページに表示されますが、これはLoop属性が「loop=$arrNews」になっているのが理由です。

「新着情報」を、全データが尽きるまでループして表示しちゃってるワケです。

さて、次ページはもう少し属性について語ってみたいと思います。
ループ回数を制限する記述なんかも・・・あるんですよ。

さて、ここで「新着情報」が、どのような感じでデータベースに収まっているのかを、図に表してみました。



なんで飯の情報なのかは置いておいて・・・w
雰囲気は掴めますでしょうか?

では、この図をもとに、section関数をさらに掘り下げて説明しましょう。



「section」の属性にはいろいろある!
前のページで紹介した「loop属性」のほかにも、section関数にはいろいろな属性があります。

(1)start属性
…ループを開始するインデックス位置。なにも指定しない場合は「0」がデフォルトになります。
「start=3」にすると、3番のインデックスから情報を引き出します。

(2)step属性
…ループするインデックス位置を“飛び飛び”にします。
なにも指定しない場合は「step=1(つまり一個づつ)」と同じ動作をします。
また、「step=3」と指定した場合なら、「0,3,6,,,,」という風に、指定した数ずつステップしてインデックスから情報を引き出します。
ほか、「step=-1」と指定すると、ステップが逆順(新着情報なら、古い記事から順に)になります。
※当校の生徒さんのご意見を参考に「step=-1」の説明を追記しました。tonさん、ありがとうございます。

(3)max属性
セクションがループする最大の回数を指定します。
「max=3」にすると、インデックスが何個あろうが3回までしかループしません。


他にも「show属性」などがあったり、「section関数の外でも使える予約変数」なんてのもあったりしますが・・・とりあえず以上です。

ちなみにEC-CUBEデフォルトの新着情報で、「表示する件数を指定したい」といった場合、上の属性を参考にすると以下のような記述で可能になります。

<!--{section name=data loop=$arrNews max=5}-->


どうでしょう?
この「max=5」はループ回数を指定できる属性なので、ここで数字を調整すれば、任意の件数で新着情報を表示させることが可能なんですね。

素敵!

さてさて、今度は実際に、以下の例がどういう表示結果を生むのかを、タグで書いてみます。

<!--{section name=data loop=$arrNews}-->
<dl>
<dt><!--{$arrNews[data].news_date_disp|date_format:"%Y年%m月%d日"}--></dt>
<dd>
<!--{$arrNews[data].news_title|escape|nl2br}--><br />
<!--{$arrNews[data].news_comment|escape|nl2br}-->
</dd>
</dl>
<!--{/section}-->


で、これが、実際にどういう処理結果を生むのかというと・・・

<dl>
<dt>2008年11月06日</dt>
<dd>
今日の飯<br />
なに食おうかな。
</dd>
</dl>
<dl>
<dt>2008年11月05日</dt>
<dd>
昨日の飯<br />
水しか飲んでない。
</dd>
</dl>
<dl>
<dt>2008年11月04日</dt>
<dd>
一昨日の飯<br />
コロッケたべた。
</dd>
</dl>
<dl>
<dt>2008年11月03日</dt>
<dd>
その前の飯<br />
記憶が定かではない。
</dd>
</dl>
<dl>
<dt>2008年11月02日</dt>
<dd>
もっと前の飯<br />
キャビア三昧。
</dd>
</dl>
<dl>
<dt>2008年11月01日</dt>
<dd>
ずっと前の飯<br />
たぶん和食。
</dd>
</dl>


こういう感じになります。
もう少し解説を添えると・・・

<!--{section name=data loop=$arrNews}-->

から、

<!--{/section}-->

までが1セクション。

「section関数」とは、指定された回数の分だけ、1セクションをループさせる処理を行う関数です。


と、いうことですね。

上のHTMLタグを読んでみるのはちょっと面倒ではありますが・・・
よくよく読んでみると、「loop=$arrNews」、つまり新着情報の中身が続くまで、「section関数」に囲われたHTMLを計6回ループさせているのが解るかと思います。


では、次は追いの一手!ということで、

<!--{$arrNews[data].news_date_disp|date_format:"%Y年%m月%d日"}-->
<!--{$arrNews[data].news_title|escape|nl2br}-->
<!--{$arrNews[data].news_comment|escape|nl2br}-->

の3つについて解説します。

「$arrNews」でデータ呼び出し!
「section関数」を大体押さえたんだし、もう説明はいいんじゃない?
・・・というワケにはいきません!

「section関数」は、値をどう呼び出すのかも込みで把握しておかなければなりません。

この辺りは、「商品一覧」や「おすすめ商品」などの場所でも転用できる知識ですので、じっくり理解しておきましょう。

さて、今回例に出している「新着情報」には、section関数の中に以下のようなSmarty文があります。

<!--{$arrNews[data].news_date_disp|date_format:"%Y年%m月%d日"}-->
<!--{$arrNews[data].news_title|escape|nl2br}-->
<!--{$arrNews[data].news_comment|escape|nl2br}-->


これは実際に、データベースに収められている情報をループ中に呼び出している部分です。

つまり、section関数をエラーなく上手に記述できたとしても、この部分がしっかり記述されていなければ、狙い通りの表示を行うことはできない!・・・というワケです。

さてさて、では一個づつ、じっくり解説します。

<!--{$arrNews[data].news_date_disp|date_format:"%Y年%m月%d日"}-->


この部分は「$arrNews」で呼び出す中でも、「news_date_disp」にあたる情報・・・つまり“日付”を引っ張り出している部分です。

そして、ここでのポイントは「date_format:」のところですね。

これは「date_format修正子」と言います。

$arrNews[data].news_date_dispの記述後に「|」を挟んだのち、「date_format:」を利用すると、データベースに格納されている日付(タイムスタンプ)を、任意のフォーマットに直して表示することが可能になります。
EC-CUBE上のあちこちの日付フォーマットを、お好みのフォーマットにして表示できるので、なにかと便利な記述ですね。

なお、この記述には主に以下のような例があります。

(1)date_format:"%Y年%m月%d日" → 2008年07月06日
(2)date_format:"%Y/%m/%e" → 2008/07/ 6
(3)date_format:"%y年%m月%d日%A" → 08年07月06日水曜日
(4)date_format:"%y.%m.%d(%a)" → 08.07.06(水)
(5)date_format:"%y.%m.%d.%r" → 08.07.06.午前12時00分00秒
(6)date_format:"%c" → 2008年07月06日 00時00分00秒
(7)date_format:"%D" → 07/06/08


というわけで、みなさんのお手元にあるEC-CUBE(やっぱり教科書のよう・・・)で、いろんな日付表示を試してみましょう。


じゃあ、次はコレです。

<!--{$arrNews[data].news_title|escape|nl2br}-->
<!--{$arrNews[data].news_comment|escape|nl2br}-->


この2つは基本的に同じ記述ですね。
上が新着情報のタイトル部分、下がコメント部分を引っ張り出す記述・・・という感じです。

ここでのポイントは、「escape」「nl2br」のところです。

まず、「escape」ですが、これは、
HTMLタグを無効化し、“そのままテキスト”として表示する
という効果があります。

次に「nl2br」。これは、
改行を“<br />タグに置き換えて”表示する
という効果があります。

うん・・・

言うのは簡単です。

では、次ページで画面キャプチャを用いて、実際の実行例を出してみましょう。
百聞は一見にしかず、ですよ。

「escape」と「nl2br」の効果とは?
例えば、EC-CUBE管理画面「新着情報管理」で以下のように入力したとしましょう。




以下、「escape」と「nl2br」を、両方記述した例です。

<!--{$arrNews[data].news_title|escape|nl2br}-->
<!--{$arrNews[data].news_comment|escape|nl2br}-->




うーん。

痛々しいくらいにHTMLが無視されてますねぇ。
これ、Webサイトの更新担当者が見たら泣くでしょうね。

でも、「nl2br」のおかげで改行は生きてます。


では、今度は両方とも削ってみます。

<!--{$arrNews[data].news_title}-->
<!--{$arrNews[data].news_comment}-->




今度は「escape」が消えたおかげで、HTMLタグが無視されずちゃんと表示されてます。
その代わり、「nl2br」が改行を<br />に変換してくれなくなったんで、テキストがベタ書き状態になってます。


・・・以上このように、「escape」や「nl2br」は、使い方次第では非常に便利な記述です。

例えばEC-CUBE上でタグを用いて情報をPRしたい箇所については、「escape」を外してみたりするのも工夫の一つでしょう。

またはこの「EC-CUBEの学校」のように、読み物的に情報を掲載したい場合には、「nl2br」を活かして文章が読みやすいように配慮する・・・などなど、「escape」と「nl2br」はsection関数以外でも使えますので、場所によって使い分けるようにしましょう。



さて、そろそろ今回の授業のシメに入ります。
最後に以下のソースをご覧ください。

EC-CUBEの「新着情報」で、実際に使われているソース文です。
※なにも変更は加えてません。オーガニックなソースですw

<div id="newsarea">
<h2>
<img src="<!--{$TPL_DIR}-->img/top/news.jpg" width="400" height="29" alt="新着情報" />
</h2>

<p>☆★☆ 新着情報は<a href="<!--{$smarty.const.URL_DIR}-->rss/index.php" target="_blank">RSS</a>で配信しています。★☆★</p>

<!--{section name=data loop=$arrNews}-->
<dl>
<dt><!--{$arrNews[data].news_date_disp|date_format:"%Y年%m月%d日"}--></dt>
<dd>
<!--{if $arrNews[data].news_url}-->
<a href="<!--{$arrNews[data].news_url}-->"
<!--{if $arrNews[data].link_method eq "2"}-->
target="_blank"
<!--{/if}-->>
<!--{/if}-->
<!--{$arrNews[data].news_title|escape|nl2br}-->
<!--{if $arrNews[data].news_url}-->
</a>
<!--{/if}--><br />
<!--{$arrNews[data].news_comment|escape|nl2br}-->
</dd>
</dl>
<!--{/section}-->
</div>


以上、このように、実際はif文の混じったソース文ですが・・・今回のsection関数を復習しつつ読み込んでいくと・・・これくらいのSmartyならある程度読破できる気がしませんか?


もし読めるようになってきたら、そろそろ頃合ですねぇ。

次回は、「Smartyの読み書き基礎」も、そろそろ一回目の区切りということで・・・


どこか一個、ブロックをカッコよくカスタマイズしましょう!


【今日のひとこと】
『石の上にも3年、Smartyの上にも3記事読めば、そろそろカスタマイズできる頃合ナリ。』


ではまた次回!

このページを見ている人は、以下のページも参照しているようです・・・!

>> EC-CUBEの学校のページ参照は、レコメンドエンジン「楽レコ」でレコメンデーションしています!

レビュー

レビューによるご意見・ご質問は会員登録された方のみとなっております。
  • ★★★★ 質問です~。 2008/11/07
    レビュアー:ton

    楽しく読ませていただきました。ありがとうございます☆

    えっと、secionを使って、新着ニュースを5件表示したとします。
    で、それらの記事の昇順、降順を決めたいときは、どのようにコードをプラスすればいいでしょうか?
    デフォルトでは昇順(?新しいものから)になっているので、descを追加するのかな?と思ったのですが、sectionのescapeの後ろあたりに、「|desc」追加でいいのでしょうか?

    昇順・降順の変更は商品の並べ替えなどで結構使いたいものです。

    あと、ついでの1件で、ご要望なのですが、(すみません、次から次に。)homan先生とkinta先生の記事で、取り扱うec-cubeのバージョンが微妙に違うのですが、できれば、これを2.3同士とか、バージョンアップのタイミングを合わせていただけると、うれしいです。
    バージョンアップでどこの構造が変わったか分からないので、これは、2.2で、これは2.3で???とちょっと、迷ってしまいました;

    宜しくお願いします。
    新しい記事、いつも楽しみにしてます☆

  • 質問ありがとうございます 2008/11/07
    レビュアー:キンタ

    どうも、キンタです。
    なるほど、昇順の設定ですね。

    「desc」とはなかなかオイシイ所を突いてますねぇ・・・が、DESCといえば確か「SQL文」だったかと思います。
    この関数内ではSmartyで記述を行わなければなりませんので・・・オシイ!

    というわけで、Smartyでの表示順序の指定ですが、

    <!--{section name=datadaze loop=$arrNews step=-1}-->

    と、section関数の語尾に「step属性」を入れてみましょう。

    step属性とは授業で説明したとおり、「ループするインデックス位置を“飛び飛び”に」する属性ですが、これに「-1」などの負の値を入れると・・・なんとステップが逆順になります。
    ※というかコレ、授業で説明してなかったな・・・

    section関数はこうやって、工夫次第でいろいろな指定ができるのがポイントです。
    ぜひいろいろ試してみましょう。

    ほか、「バージョンアップのタイミングの件」了解です!大事なことですよね。

    ただ、僕もホマン先生もですが、動作保障の確認を一定のバージョンで取りつつ、随時カスタマイズ法を紹介しているので・・・いきなり最新版にバージョンアップとは行かないかもしれませんね。

    ともあれ、徐々に最新版を追っかけていきます。

    ではではtonさん、レビューありがとうございました。

  • ★★★★★ 教えていただきたいです! 2008/11/07
    レビュアー:konixile

    はじめまして♪
    ちょうど勉強していたところが記事になっていて
    大変参考になりました。ありがとうございます。

    この記事を読んで「オススメの商品」の部分を
    横に3つずつ表示させるようにさせました。
    (HPあるのでよかったら見てくださいね)

    この「オススメの商品」のように
    こんどは「商品一覧」のページに、
    画像を横1列に並べて4つずつ位並べて
    5つ目から折り返しまた横に4つずつならべ・・。
    というのを実装したいのですが
    自分にとってはまだまだ難しいようです、

    もしよかったらご教授ください。
    よろしくお願いします。

  • ★★★★ 教えて貰えますか! 2008/12/22
    レビュアー:ksm

    いつも大変参考にさせて頂いております。
    質問があるのですが・・・
    konixileさんのコメントにもありましたが、「商品一覧」のページに、画像を横1列に並べて3~4点ずつ並べて表示したいと思っております。
    ちなみに、konixileさんのサイトを拝見したところ、表示されてました!同じようにやりたいと思い
    EC-CUBEのコミュニティーサイトも見たのですが、どうしても解りません。
    宜しくお願いします!!
    ちなみに、Version 2.3.3です。

  • 教えていただきたいです。 2009/06/04
    レビュアー:yuka

    sectionは条件をつけてBreakさせることは可能でしょうか?
    可能であればどういう風にすればよいでしょうか?
    ぜひ教えてください。

  • キンタの代わりにお答します 2009/06/08
    レビュアー:homan

    お返事が遅くなり申し訳ありません!

    > sectionは条件をつけてBreakさせることは可能でしょうか?

    僕が知る限りでは、sectionにはbreakできる機能はなかったように思います。section内部でif文で処理を変えてしまう方法もありますが、あまりスマートではないですね・・・。

    そもそもSmartyはあくまでもテンプレート(デザイン)側なので、あまり複雑な処理をすべきでなく、PHP側で条件によってテンプレート側へ渡す値を調整する方がよいと思います。

  • ★★★★ メーカー名や発注先名を.... 2009/10/04
    レビュアー:nomu

    いつも、いろいろなカスタマイズに活用させて頂き有難うございます。

    商品情報としてメーカー名や発注先名を商品マスタ(dtb_products)のcomment1,comment2欄を利用し、取り急ぎはurl等のチェックを外して登録していますが、smartyの中のtpl内の記述をアレンジすることで商品詳細ページには出力出来るのですが、その後のカートページやショッピングページに出力することが出来ません。また、最終的には発注確認メールや管理画面側のあらゆるところにこのメーカー名や発注先名(comment1,comment2)を使いたいのですが全く検討がつきません。
    phpやsmartyについては殆ど素人なのでカスタマイズ箇所を教えていただきたいのですがよろしくお願いします。

この記事に対するトラックバック

この記事のトラックバック先URL

ECの「勝ち組」だけが知っている 売り上げUPの秘密はこちら