4
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

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

はじめに

リソースは表現(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 で教えて頂きました。ありがとうございます。

参照リンク

関連リンク

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
4
Help us understand the problem. What are the problem?