Laravel使ってみた (10) - Views & Response -
http://laravel.com/docs/responses 辺りのドキュメント読みつつやってみる的な事を遂行。部分的な事(ResponseとwithCookieとか)は既にやってるので省略。という事で主な所はViewsに関係する所くらいか
<?php
Route::get("/hoge", function() {
return Response::view("hoge", array("name" => "hoge"));
});
とか出来る。でView::makeした結果を返そうがResponse::viewでViewを作ったResponseを返そうが結局はResponseにViewが内包されるような形で処理されるのかも。んまぁここら辺な論理的な所はソース見てないので不明
でまぁ単純なビューなレスポンスの出し方は置いといて、View::shareをしないとイケないケースっていうどういう場合だろうと思ったら、View::make->nestで処理される子のViewに置いては親側で使用しているビュー変数等にはアクセス出来ない? んだろうと思ってるのだけど、例えば親ビューでも子ビューでも同一の値を共有したい等の場合に使うんじゃないかと。という事で
<?php
class TestController extends Controller {
public function show($id) {
return View::make(
"hoge",
array("name" => "hoge")
)->nest("child", "fuga");
}
}
っていうコントローラーを作って
@extends("layout")
@section("content")
{% raw %}{{ $name }}{% endraw %}
{% raw %}{{ $child }}{% endraw %}
@stop
っていうhoge.blade.phpなビューを作る。で$childな部分はnestで指定された子のビューをレンダリングした結果? を持つんだと思うのでそのまま出力評価として出す
{% raw %}{{ $name }} {% endraw %}
fuga.blade.phpではこうなってる。で例えばこのまま実行すると「Undefined variable: name」っていう風になる。んまぁView::makeで指定したビュー変数は子ビューまでには作用しないっていう感じかと。んまぁView::make->nestの第3引数に指定する事も出来る。
<?php
return View::make(
"hoge",
array("name" => "hoge")
)->nest("child", "fuga", array("name" => "fuga"));
的な感じで指定する事も出来るけど、上でも書いたように親ビューと子ビューでレンダリングに使用するビュー変数はView::shareを使う事で共有化する事も出来る模様。という事で上記を
<?php
View::share("name", "hoge fuga foobar");
return View::make("hoge")->nest("child", "fuga");
っていう感じにするとhoge.blade.phpとfuga.blade.phpで作用するビュー変数の$nameは同一の「hoge fuga foobar」になるっていう感じ。んまぁ全体で共有すべきビュー変数等はView::shareを使って共有化する事が出来る感じかなと。ちなみにapp/start/global.phpとかでもView::shareは出来る模様
でView::composer。composerを使えばビューが生成された際の処理を行える模様。例えば上記でView::shareをせずに
<?php
View::composer("fuga", function($view) {
$view->with("name", "fuga");
});
return View::make("hoge", array("name" => "hoge"))->nest("child", "fuga");
というようにfugaなビューが生成される際にあたっての処理を利用できるっていう感じかと。でView::composerの第2引数にはクラス名を指定出来るので、Composerなクラスを作っちゃって処理する事も可能。という事でapp/composersっていうディレクトリを作ってapp/start/global.phpで
ClassLoader::addDirectories(array(
app_path()."/composers"
));
っていう設定をしておく事でapp/composersにクラスな.phpを置く事で利用できるようにする
<?php
class FugaComposer {
public function compose($view) {
$view->with("name", "fuga");
}
}
引数にViewを持つcomposeっていうメソッド(引数の$viewの型はIlluminate\View\View)を実装。んまぁ特につっこみどころ無さそうなので(ry
とりまぁ今回のセクションはこんなもんで。一応余談がありますので
余談1: リダイレクト時にflashオブジェクトを利用できる
<?php
Route::get("/", function() {
return Redirect::action(
"EntryController@show",
array("id" => 1)
)->with("message", "hoge");
});
ってな感じでwithでflashオブジェクトを指定出来る模様
余談2: JSONレスポンスを出す
<?php
class EntryController extends Controller {
public function
return Response::json(["hoge", "fuga", "foobar"]);
}
}
Response::jsonの返り値はIlluminate\Http\JsonResponseな模様だけど、こいつの実体自体はSymfony\Component\HttpFoundation\JsonResponseな模様。でSymfonyなJsonResponse自体もSymfony\Component\HttpFoundation\Responseが実体なのでヘッダーとか書き換えるようなケースとかだと
<?php
$response = Response::json([]);
$response->headers->set("HeaderName", "HeaderValue");
というような感じかなと。あとsetCallbackっていうメソッドでコールバック先を指定するとJSONPな出力になる模様
余談3: Content-Dispositionなレスポンスを出す
デフォルトだとattachmentになる模様だけど、Response::downloadっていうメソッドを使えば可能な模様。でその実体自体はIlluminate\Support\Facades\Responseでこれ自体もSymfony\Component\HttpFoundation\BinaryFileResponseな模様
つっこみどころはあるんだけど思ってるだけで証明出来てないので(ry