1252528222 Smartyに関する質問です。


Smartyのテンプレート側でクエリ情報のついたページを
読み込みたいと思っております。

例えば読み込みたいページが「http://xxx.jp/test.php」の場合はtpl側で

<!--{include file="test.tpl"}-->

とすればできるのですが、「http://xxx.jp/test.php?id=99」の場合はtpl側で

<!--{include file="test.tpl?id=99"}-->

はエラーになり読み込めません。またSSIなどでも

<!--#include virtual="test.php?id=99"-->

とhtmlファイルなどに書き込めば読み込めるのですが
tplファイルになるとうまく読み込めません。

このような場合はどうすればいいのでしょうか?
宜しくお願いします。

※以下のような回答以外でお願いします。
・tplで読み込まず「iframe」「object」使えば?(読み込むファイルの縦の長さがまちまちで綺麗に読み込めないため)
・読み込まずにtplに直接書き込めば?(とにかく読み込みたい)

回答の条件
  • 1人1回まで
  • 登録:2009/09/10 05:30:23
  • 終了:2009/09/10 16:43:21

ベストアンサー

id:tdoi No.3

tdoi回答回数174ベストアンサー獲得回数752009/09/10 14:24:59

ポイント100pt

ようやく何となくやりたいことは分かりました。

ですが、「原則的に」とか「構造がうんぬん」についての話について、テンプレートエンジンについては勘違いされていると思います。

原則的に、テンプレートエンジンは与えられたデータを*どのように表示するか*を担うものなので。

つまり、データの取得をすべて終わらせてから、テンプレートエンジンに処理させます。

たぶん、イメージされていることは、テンプレートエンジンで処理させながら、部分部分のデータを作成するものになっていると思います。

これ以上、この話をしても、ご理解されるかどうかわからないので、一般的な話はこのくらいにして、

では、どうするかですが、大ざっぱですが3つあると思います。


・方法1

最初にすべての情報を取得する。

つまり、高さなども含めて各タイムテーブルの情報をPHPスクリプトで配列にでも格納しておいて、idではなくそれらの情報をSmartyのテンプレート側で、

{include file="timetable.tpl" height=$entry.height ・・・}

のような形で渡す方法です。

>タイムテーブル自体の高さは登録されたクラスの内容によって

>随時変化するため、親要素のタイムテーブルに高さを持たせることが難しいと

>思っていましたが、タイムテーブルに「高さ」の項目を追加し

>ダンスクラスの登録or編集or削除するごとに全体の高さを求め、

>タイムテーブルに格納することで解決できることに気づきました。

たぶん、これはこの方法に当たります。

タイムテーブルに乗っけるクラスも、同様にパラメタとして指定する必要があるかもしれません。

この方法が一番無難と言えば、無難です。


・方法2

PHPスクリプト側で、タイムテーブルごとの断片をHTTPアクセスして取得しておき、それをテンプレートに渡す。

PHPスクリプト側で、HTTP/Requestなり、file関数なりを使用して、HTML断片を取得します。

PHP側

$timetable1 = file_get_contetns("http://www.todash.jp/school/TimeTable.php?timetable_id=1");
$timetable2 = file_get_contetns("http://www.todash.jp/school/TimeTable.php?timetable_id=2");
$timetable3 = file_get_contetns("http://www.todash.jp/school/TimeTable.php?timetable_id=3");

$smarty->assign('timetables', array($timetable1, $timetable2, $timetable3));

テンプレート側

{foreach from=$timetables item=timetable}

{$timetable}

{/foreach}

のような感じです。


・方法3

テンプレートで、HTTPアクセスを行う。

おすすめはしないですが、おそらく、一番、gelgelgelさんの考えに近いと思います。

タイムテーブル1
{php}readfile("http://www.todash.jp/school/TimeTable.php?timetable_id=1"{/php}
タイムテーブル2
{php}readfile("http://www.todash.jp/school/TimeTable.php?timetable_id=2"{/php}
タイムテーブル3
{php}readfile("http://www.todash.jp/school/TimeTable.php?timetable_id=3"{/php}

こんな感じです。


何かの参考になれば。

id:gelgelgel

tdoi様

様々ご回答ありがとうございます。

>ですが、「原則的に」とか「構造がうんぬん」についての話について、

>テンプレートエンジンについては勘違いされていると思います。

私的にはきちんと概念は把握しているつもりです。

説明不足が悪かったのですが、tdoiさんが想像されているのと

私が実際にやろうとしていることが違うのだと思います。

普通は

index.php → index.tpl+timetable.tpl

だと思うのですが、私は

index.php → index.tpl+(timetable.php→timetable.tpl)

とphp側で処理されたtplを読み込みたいのです。


>・方法1

これだと高さは渡せてもtable_idがGETで渡せないと思うのですが・・

>・方法2

まだ試していませんが、このようなことだと思います

>・方法3

こちらも近いと思います。

>方法3の延長で、それをJavaScriptにやらせてしまうという方法もあります。

これはうっすら考えました。でもJavaScript用のソースにするのが

面倒でやめました(笑)慣れていればなんてことないんでしょうけど・・

  • - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

で私も振り返って考えたのですが、「http://www.todash.jp/school/TimeTable.php?timetable_id=3」自体に

もう<html>や<body>などのタグが含まれているため、

『include file=』やtdoiさんに教えて頂いた方法で読み込むことは

<html>や<body>が重複し文法的に問題ありそうですので

やはり「iframe」などを用いることで決着したいと思います。

結局質問で除外した方法で解決することになり大変申し訳ありませんでした。

教えて頂いた方法どれも大変参考になりました。

今後の作業に活用させて頂きます。

ご丁寧に答えていただきありがとうございました。

2009/09/10 16:41:17

その他の回答(2件)

id:kka No.1

kka回答回数1ベストアンサー獲得回数02009/09/10 10:22:06

ポイント10pt

URLに?でつけるGET変数はHTTPプロトコルでプログラムが受け取るためのものですから、

PHPでインクルードしても、"test.tpl?id=99"全体をファイル名と解釈してエラーになります。

そもそもSmartyはHTMLデザインに特化するためのテンプレートエンジンなので、

.tplファイル側での変数の作成や書き換えなどは推奨されていません。

ロジカルな部分は.phpファイル側で完了させておいたほうがスッキリしますよ。

というか.tplファイルを.tplからインクルードする場合、変数はSmartyが持っているから

わざわざ変数を渡さなくてもそのまま使えるのではないですか?

さなみに

.tplファイルにGET変数を渡す場合は.phpファイル側で?以降の値を変数にしておく必要があります。

◆URL

http://xxx.jp/test.php?id=99

◆test.phpソース

require_once("MySmarty.class.php");

//GET変数id値を$idに変更

$id=$_GET["id"];

//テンプレート

$o_smarty=new MySmarty();

$o_smarty->assign(array(

"id"=>$id

));

$o_smarty->display("test.tpl");

?>

id:gelgelgel

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

でもまさしく私が恐れていた回答なんですね・・。

上記の方法があることはもちろん知っております。

これでは私がやりたいことが解決できないのです。

2009/09/10 11:43:48
id:rouge_2008 No.2

rouge_2008回答回数594ベストアンサー獲得回数3512009/09/10 11:20:55

ポイント10pt

表示するコンテンツの切り替えに利用するのでしょうか?

以下のページの例のように変数で呼び出してはいかがでしょうか?

http://www.smarty.net/manual/ja/language.basic.syntax.php

テンプレート側

{include file=$includeFile}

PHPファイル側

$includeFile = 'standard.tpl';
$request_no = $_GET['id'];
// クエリで渡された値が適正かどうかの処理はここでは省略します。

if($request_no) {
$includeFile = 'select'. $request_no .'.tpl';
}
// ここでは初期適用されるテンプレートを設定して、リクエストされた場合に上書き処理しています。
$smarty->assign('includeFile', $includeFile);

リクエストされない状態で何も表示したくない場合は、初期表示されるテンプレートは白紙にすると良いです。

※テンプレートファイルの名前の接頭語を同じにする必要があります。

※リクエストされた番号のテンプレートがない場合に表示するテンプレートも用意しておいた方がいいかもしれません。

例えば・・・

if($request_no) {
    if($request_no <= '10'){
        $includeFile = 'select'. $request_no .'.tpl';
    } else {
        $includeFile = 'no_message.tpl';
    }
}

リクエストされたテンプレートをセットする処理の部分を、上記のように用意したテンプレートの数で分岐処理するのが簡単だと思います。(※例では10個用意した場合になっています。)

※呼び出して表示するテンプレートは、すべて続き番号にしてください。

id:gelgelgel

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

http://xxx.jp/test.php?id=99の部分は利用者が自動で生成しますので

自分でテンプレートを用意する必要があるため無理です・・。

というか私の文章だけでは分かりにくいですね・・。

以下追記しましたので宜しくお願い致します。

  • - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

※追記

今現在テストで以下のようなDBを使ってダンスクラスのタイムテーブルを

クラス情報から生成して表示する仕組みを作っています。

http://www.todash.jp/school/TimeTable.php?timetable_id=3

上記の場合は「timetable_id」が「3」のに登録されたダンスクラスを読み込み表示します。

このクラスの表示にあたりCSSの「position:absolute;」を使って縦・横の差から

「top」「left」を指定して位置表示をしています。

この都合上タイムテーブルの上に何か情報を置けません。(topからの位置が分からなくなるため)

そのためこの部分のみを別ファイルとして読み込みたいと思っております。

「iframe」「object」を使用してもいいのですが、高さがイレギュラーなためあまり使いたくありません。

(タイムテーブル自体の高さを求めることはできますがiframeに指定できない)

何かいい方法があれば宜しくお願い致します。

2009/09/10 12:22:57
id:tdoi No.3

tdoi回答回数174ベストアンサー獲得回数752009/09/10 14:24:59ここでベストアンサー

ポイント100pt

ようやく何となくやりたいことは分かりました。

ですが、「原則的に」とか「構造がうんぬん」についての話について、テンプレートエンジンについては勘違いされていると思います。

原則的に、テンプレートエンジンは与えられたデータを*どのように表示するか*を担うものなので。

つまり、データの取得をすべて終わらせてから、テンプレートエンジンに処理させます。

たぶん、イメージされていることは、テンプレートエンジンで処理させながら、部分部分のデータを作成するものになっていると思います。

これ以上、この話をしても、ご理解されるかどうかわからないので、一般的な話はこのくらいにして、

では、どうするかですが、大ざっぱですが3つあると思います。


・方法1

最初にすべての情報を取得する。

つまり、高さなども含めて各タイムテーブルの情報をPHPスクリプトで配列にでも格納しておいて、idではなくそれらの情報をSmartyのテンプレート側で、

{include file="timetable.tpl" height=$entry.height ・・・}

のような形で渡す方法です。

>タイムテーブル自体の高さは登録されたクラスの内容によって

>随時変化するため、親要素のタイムテーブルに高さを持たせることが難しいと

>思っていましたが、タイムテーブルに「高さ」の項目を追加し

>ダンスクラスの登録or編集or削除するごとに全体の高さを求め、

>タイムテーブルに格納することで解決できることに気づきました。

たぶん、これはこの方法に当たります。

タイムテーブルに乗っけるクラスも、同様にパラメタとして指定する必要があるかもしれません。

この方法が一番無難と言えば、無難です。


・方法2

PHPスクリプト側で、タイムテーブルごとの断片をHTTPアクセスして取得しておき、それをテンプレートに渡す。

PHPスクリプト側で、HTTP/Requestなり、file関数なりを使用して、HTML断片を取得します。

PHP側

$timetable1 = file_get_contetns("http://www.todash.jp/school/TimeTable.php?timetable_id=1");
$timetable2 = file_get_contetns("http://www.todash.jp/school/TimeTable.php?timetable_id=2");
$timetable3 = file_get_contetns("http://www.todash.jp/school/TimeTable.php?timetable_id=3");

$smarty->assign('timetables', array($timetable1, $timetable2, $timetable3));

テンプレート側

{foreach from=$timetables item=timetable}

{$timetable}

{/foreach}

のような感じです。


・方法3

テンプレートで、HTTPアクセスを行う。

おすすめはしないですが、おそらく、一番、gelgelgelさんの考えに近いと思います。

タイムテーブル1
{php}readfile("http://www.todash.jp/school/TimeTable.php?timetable_id=1"{/php}
タイムテーブル2
{php}readfile("http://www.todash.jp/school/TimeTable.php?timetable_id=2"{/php}
タイムテーブル3
{php}readfile("http://www.todash.jp/school/TimeTable.php?timetable_id=3"{/php}

こんな感じです。


何かの参考になれば。

id:gelgelgel

tdoi様

様々ご回答ありがとうございます。

>ですが、「原則的に」とか「構造がうんぬん」についての話について、

>テンプレートエンジンについては勘違いされていると思います。

私的にはきちんと概念は把握しているつもりです。

説明不足が悪かったのですが、tdoiさんが想像されているのと

私が実際にやろうとしていることが違うのだと思います。

普通は

index.php → index.tpl+timetable.tpl

だと思うのですが、私は

index.php → index.tpl+(timetable.php→timetable.tpl)

とphp側で処理されたtplを読み込みたいのです。


>・方法1

これだと高さは渡せてもtable_idがGETで渡せないと思うのですが・・

>・方法2

まだ試していませんが、このようなことだと思います

>・方法3

こちらも近いと思います。

>方法3の延長で、それをJavaScriptにやらせてしまうという方法もあります。

これはうっすら考えました。でもJavaScript用のソースにするのが

面倒でやめました(笑)慣れていればなんてことないんでしょうけど・・

  • - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

で私も振り返って考えたのですが、「http://www.todash.jp/school/TimeTable.php?timetable_id=3」自体に

もう<html>や<body>などのタグが含まれているため、

『include file=』やtdoiさんに教えて頂いた方法で読み込むことは

<html>や<body>が重複し文法的に問題ありそうですので

やはり「iframe」などを用いることで決着したいと思います。

結局質問で除外した方法で解決することになり大変申し訳ありませんでした。

教えて頂いた方法どれも大変参考になりました。

今後の作業に活用させて頂きます。

ご丁寧に答えていただきありがとうございました。

2009/09/10 16:41:17
  • id:tdoi
    >上記の方法があることはもちろん知っております。
    >これでは私がやりたいことが解決できないのです。

    これが想像できません。
    具体的に示して頂かないと、回答できないですよ。

    極端な話、{php}タグを使ってしまえば何でもできちゃいますし、
    {include}タグで変数を渡すのでも良い気がします。

    たぶん、PHPスクリプトは操作せずにテンプレートだけで対応したい、XXXなデータを扱うためにYYYな形で記述すると複雑になりすぎる、自分のポリシーでXXXな書き方は避けたい。などがあるんでしょうが、それは、書いてもらわないと分かりません。
  • id:tdoi
    連続のコメントすみません。
    PHP側で計算をして、{include}タグで、top、leftなどを渡せばいいだけでは?

    $class = array('height' = 90, 'top' = 257', 'left' = 121')

    のような状態で、

    {include file="class.tpl" height="$class.height" top="$class.top" left="$class.left"}

    みたいな感じです。

    class.tplでは、

    <table class="classBlock genre14" style="height:{$height}px; top:{$top}px; left:{$left}px;">
    ・・・省略・・・
    </table>

    で済むかと。

    こういうことですか?
  • id:gelgelgel
    tdoi様

    コメントありがとうございます。

    ><table class="classBlock genre14" style="height:{$height}px; top:{$top}px; left:{$left}px;">
    >・・・省略・・・
    ></table>
    >
    >で済むかと。

    私が設定したいのはこのタイムテーブル全体の高さであって
    上記のような個別のクラスの高さではありません。

    あえてかくなら

    {include file="timetable.tpl" $_GET['title_id']="3"}

    ということです(もちろん上記ではできませんけど)

    最初に質問にあるとおりとにかく「http://xxx.jp/test.php?id=99」という形式で
    読み込みたいということなのです。

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    タイムテーブル自体の高さは登録されたクラスの内容によって
    随時変化するため、親要素のタイムテーブルに高さを持たせることが難しいと
    思っていましたが、タイムテーブルに「高さ」の項目を追加し
    ダンスクラスの登録or編集or削除するごとに全体の高さを求め、
    タイムテーブルに格納することで解決できることに気づきました。

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    他にもっとシンプルでいい方法があればご教授お願い致します。
  • id:tdoi
    まだ、いまいちよく分からないのですが、

    >最初に質問にあるとおりとにかく「http://xxx.jp/test.php?id=99」という形式で
    >読み込みたいということなのです。

    この意味がわからないのですが、これを読み込んでどう使いたいのですか?
    原則的に言えば、テンプレートでDBにアクセスなんかすべきじゃないですので、id=99を渡したところで意味はないと思うのですが。

    テンプレートエンジンの処理と、PHPの処理とを混同されていませんか?

    仮に、{include file="timetable.tpl" $_GET['title_id']="3"}ができたとして、timetable.tplはどんなテンプレートにしたいのですか?

    それを示してもらうのが一番だと思います。
  • id:gelgelgel
    何度もありがとうございます。

    >この意味がわからないのですが、これを読み込んでどう使いたいのですか?
    >原則的に言えば、テンプレートでDBにアクセスなんかすべきじゃないですので、id=99を渡したところで意味はないと思うのですが。

    例えば
    http://www.todash.jp/school/TimeTable.php?timetable_id=3を
    http://www.a-tanz.com/dance/regular.html/kdsrjb0000001yut.htmlのように
    ページに組み込みたいのです。

    でなぜタイムテーブル部分のみ別にするかは前コメントのCSSに由来します。

    >仮に、{include file="timetable.tpl" $_GET['title_id']="3"}ができたとして、timetable.tplはどんなテンプレートにしたいのですか?

    上記のタイムテーブルです。$_GET['title_id']がなければ以下のような感じになってしまうので値を持たせる必要があるのです。
    http://www.todash.jp/school/TimeTable.php

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    もう一度まとめると

    http://www.todash.jp/school/TimeTable.php?timetable_id=3を
    別ページから読み込みたいと

    でも「iframe」「object」は使いたくない。高さがイレギュラーだから。
    普通の.htmlならSSIなどで読み込めますが、.tplだと読み込めない。

    ではどうすればいいのか?ということです。

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    「原則的に」とか「構造がうんぬん」についての話は切りがないので
    ご遠慮ください。

    とにかく『綺麗に効率よく読み込む方法が知りたい』
    これについての回答・コメントのみでお願い致します。

  • id:tdoi
    回答に書き忘れましたが、

    方法3の延長で、それをJavaScriptにやらせてしまうという方法もあります。
  • id:tdoi
    いるかまでありがとうございます。

    > index.php → index.tpl+(timetable.php→timetable.tpl)

    こういうことは基本的にはテンプレートエンジンをそのまま利用してもできません。
    やるとすれば、{php}タグを使わざる負えません。
    逆にいえば、{php}タグを使えば何でもできます。ただ、それをやりすぎると、そもそもテンプレートエンジンを使う必要があるか?ということに行きついてしまうのだと思います。


    >これだと高さは渡せてもtable_idがGETで渡せないと思うのですが・・

    timetable.phpでやりたい処理も、index.phpの中、あるいは、index.phpから呼び出す関数などでやってしまうということです。


    >もう<html>や<body>などのタグが含まれているため、
    >『include file=』やtdoiさんに教えて頂いた方法で読み込むことは
    ><html>や<body>が重複し文法的に問題ありそうですので

    サンプルで書いたものは、示してもらったページのURLをそのまま記述しましたが、phpのスクリプトは正しいHTMLを返す必要はありません。<table>タグだけを返すPHPスクリプトを用意して、それを読み込みます。


    このコメント書きながら、たぶん、一番正しいのではないかなと思う方法を書きます。


    index.phpにおいて、

    $timetables = array();
    foreach ($list as $id) {
    $timetables[] = generateTimetables($id);
    }
    $smarty =& new Smarty();
    $smarty->assign('timetables', $timetables);
    $smarty->display('index.tpl');

    function generateTimetables($id) {
    $smarty =& new Smarty();
    /** timetable.phpで行いたい処理 */
    return $smarty->fetch('timetable.tpl');
    }

    としておき、

    index.tplで、

    {foreach from=$timetables item=timetable}
    {$timetable}
    {/foreach}

    みたいなのが一番よいような気がします。


    何かの参考になれば。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません