1

次の機能を持つシステムをプログラミングしています: 通常のユーザー (プログラマーや管理者ではない) は、「プレースホルダー」を挿入できるコンテンツを作成できます。これらのプレースホルダーは、ページがレンダリングされるときに、さまざまなコンテンツ タイプ (16 進カラー コード、スライダー、画像など) に置き換えられます。プレースホルダーの置換は少し複雑で、いくつかの追加機能があります (たとえば、デフォルト値の定義、プレースホルダーを正しい言語のコンテンツに置き換えるなど)。このため、「プレースホルダーフィルター」を使用して小枝拡張を作成しました。この関数は、正しいコンテンツを取得してプレースホルダーを置き換え、追加機能を処理する必要があります。

コンテンツ タイプは非常に異なるため、コントローラでコンテンツをレンダリングするためのロジックを含むコンテンツ タイプごとに、「プラグイン」と呼びましょう。

今私の問題:

プラグインのコントローラ アクションは、レンダリングされたコンテンツを返します。プレースホルダーを小枝拡張機能のコンテンツに置き換えるため、この小枝拡張機能でコントローラー アクションを呼び出す方法が必要です。

今までの私の考え:

この方法でテンプレートでコントローラーアクションを呼び出すことができることを知っています (ソース: http://symfony.com/doc/current/book/templating.html ):

{{ render(controller(
        'AppBundle:Article:recentArticles',
        { 'max': 3 }
    )) }}

そのため、小枝でコントローラーアクションを呼び出すことは問題ないようです。しかし、小枝拡張でこの関数呼び出しが必要です。

また、コントローラーをサービスとして実装するときに、コントローラー アクションを呼び出すことができることも知っています。しかし、プラグインはシステムに動的に組み込まれるため、すべてのプラグイン コントローラーをサービスとして定義することはできません。新しいプラグインをインストールするときにサービスも動的に処理するのは「難しい」でしょう(スクリプトでservice.ymlを編集する必要があると思います-または間違っていますか?)。これが、コントローラーをサービスとして使用できない理由です。-しかし、サービスを動的に実装する方法を教えていただければ、他のソリューションにもオープンです。

私がすでに試したことは、次の 2 つのページのソリューションを組み合わせることでした: http://symfony.com/doc/current/book/templating.html

echo $view['actions']->render(
    new \Symfony\Component\HttpKernel\Controller\ControllerReference(
        'AppBundle:Article:recentArticles',
        array('max' => 3)
    )
)

およびhttps://www.robinvdvleuten.nl/blog/rendering-templates-in-a-twig-extension/

twig-extension の placeholder-filter で Twig_Environment にアクセスできるようになりましたが、次のコードは機能しません。

$twig->render( new \Symfony\Component\HttpKernel\Controller\ControllerReference(
                            'Extensions'.$namespace.'Bundle:Index:getContent',
                            array('content'=>$contentObject)
                        ), array() );

ControllerReference を文字列に変換できないというエラーが表示されます (ControllerReference はオブジェクトであるため、これは理にかなっています...)。

コントローラーをサービスとして定義せずに、twig-extension でコントローラー アクションを呼び出す方法はありますか? それとも、ソリューション全体を再考する必要がありますか?

4

2 に答える 2

1

おそらく、ViewListener を定義して、コントローラーの $this->render によって返される Response の代わりに、必要な html をコントローラーに返させることができます。

コントローラーで $this->renderView を使用し、結果を拡張機能に返す必要があります。

このようにセットアップされたシステム全体は非常にハックであり、長期的に維持するのは難しいと正直に感じているので、再考することをお勧めします

于 2016-01-30T17:30:08.680 に答える
0

「問題について考えて」数時間後、私は主な質問に対する簡単な答えを見つけました。フィルター関数に Twig_environment を含めると ( https://www.robinvdvleuten.nl/blog/rendering-templates-in-a-twig-extension/を参照)、twig render() 関数にアクセスできます。この関数は、テンプレートと文字列で機能します。したがって、サービスなしで twig-extension でコントローラー アクションを呼び出す最も簡単な方法は、通常の twig-template-syntax を使用することです。

// $twig is the Twig_Environment in my filter-function
$myRenderedContent = $twig->render(
    "{{ render(controller( 'Extensions".$namespace."Bundle:Index:getContent', { 'content': content })) }}", 
    array('content'=>$contentObject)
);

追加の考え:

http://symfony.com/doc/current/book/templating.htmlでわかるように、このようなコントローラーの呼び出しは symfony ではまったく問題ないようです。したがって、この機能を twig-extension で使用することも問題ないと思います (twig-extension はテンプレート レンダリング用の追加のヘルパー関数を定義するため、これが私のフィルター関数で実行したいことで、特別なプレースホルダーを特別なものに置き換えますコンテンツ)。

プラグイン コントローラーをサービスとして含めないのはベスト プラクティスではないかもしれませんが、プラグイン コントローラーをこのように処理することの欠点は今のところ見当たりません。 「より良くする方法」を学ぶために;-)

于 2016-02-02T12:29:30.810 に答える