LoginSignup
7
4

More than 5 years have passed since last update.

[Practical BEAR.Sunday] リソース単位でレンダラーを変更する方法

Last updated at Posted at 2017-05-28

はじめに

リソースは表現(Representation)のためのリソースレンダラーを持っています。
文字列評価されるとリソースはリソースレンダラーに表現されてレスポンスになります(文末[※1])。

通常はアプリケーションコンテキスト([※2]) の単位でデフォルトのレンダラーを選びますが(例:app コンテキストでは JSONレンダラーを使う、など)、リソース単位でレンダラーを変更することもできます。

たとえば oEmbed のような埋め込みHTMLを返すWebAPIを開発しているとしたら、JSONレスポンスの一部の値だけはHTMLテンプレートで返したいというケースもあるでしょう。

リソース単位でレンダラーを変更する

単純な例で考えます。APIで下記のJSONレスポンスを返したいとします。

{"html":"<html><h1>this is embed. bar<\/h1><\/html>"}

デフォルトのままでは下記のようにすべてがJSONになってしまいます。

スクリーンショット 2017-05-28 18.14.39.png

"html" キーの値だけTwigテンプレートでレンダリングされたHTMLビューに変えます。

サンプルプロジェクト

kumamidori/ExampleChangeRenderer

クラス図

renderer.png

実装

埋め込みHTMLリソースの RenderInterface (名前 "html") に TwigRenderer をバインド

class Embed extends ResourceObject
{
    /**
     * @Inject
     * @Named("html")
     */
    public function setRenderer(RenderInterface $renderer)
    {
        return parent::setRenderer($renderer);
    }

    public function onGet()
    {
        //・・・
    }
}

APIリソースで埋め込みHTMLリソースを文字列評価

namespace Kumamidori\ExampleChangeRenderer\Resource\Page\Api;

//・・・
class Example extends ResourceObject
{
    //・・・
    public function onGet()
    {
        $embed = $this->resource->get->uri('page://self/embed')->eager->request();
        $this['html'] = (string) $embed; // < 文字列評価する

        return $this;
    }
}

補足: レンダラーによる文字列評価のタイミングの違い

  • (string) 評価をすればレンダラーでレンダリングされる
  • (string) 評価をしない場合に、TwigRenderer と JsonRenderer で評価が異なる
  • TwigRenderer の場合: 各要素を文字列評価しようとするので __toString() が呼ばれてそれぞれインジェクトされたレンダラーでレンダリングされる
  • JsonRenderer の場合: JsonSerializable インターフェイスで実装されたjsonSerializeメソッドが呼ばれてJSONになるので明示的に (string) で文字列評価しなければならない(ref. https://github.com/bearsunday/BEAR.Resource/blob/1.x/src/ResourceObject.php#L207) ([※3])

おわりに

  • 当初自分では分からなくて BEAR の Issue / gitter で教えて頂きました。ありがとうございます。

参照リンク

関連リンク

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4