人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

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に直接書き込めば?(とにかく読み込みたい)

1252528222
●拡大する

●質問者: gelgelgel
●カテゴリ:インターネット ウェブ制作
✍キーワード:HTML object Smarty TPL エラー
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● kka
●10ポイント

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");

?>

◎質問者からの返答

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

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

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

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


2 ● rouge_2008
●10ポイント

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

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

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個用意した場合になっています。)

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

◎質問者からの返答

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

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に指定できない)

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


3 ● tdoi
●100ポイント ベストアンサー

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

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

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

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

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

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

では、どうするかですが、大ざっぱですが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}

こんな感じです。


何かの参考になれば。

◎質問者からの返答

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」などを用いることで決着したいと思います。

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

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

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

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

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ