2012-02-11 10 views
1

現在、symfony2アプリケーションで作業しており、組み込みコントローラを使用しています。私の組み込みコントローラは、独自の機能セットをカプセル化して、どこにでも埋め込むことができ、機能することが期待されるウィジェットのようなものです。アセット付きの組み込みコントローラビュー

私はオンラインのユーザーと呼ばれるコントローラを持っています。それが生成するビューはシンプルで、オンラインユーザーのリストです。しかし、私はクリックしたユーザーの情報を取得するためにajaxを使用できるように、そのビューにいくつかのjavascriptを追加したいと思います。ここだ

{% block content %} 
{% endblock content %} 

{% block scripts %}{% endblock %} 

{% extends partial.html.twig" %} 
{% block content %} 
<ul> 
    <li><a href="site.com/ajax/user/1">User 1</a></li> (this would all be generated using 'somedata') 
    <li><a href="site.com/ajax/user/2">User 2</a></li> 
    .... 
<ul> 
{% endblock content %} 
{% block scripts %} 
    ..some javascript for interacting with this widget 
{% endblock %} 

これから延長された部分である:ここ

return $this->render('AppBundle:Users:usersOnline.html.twig', array('somedata' => $data); 

は、そのコントローラのビューの:

コントローラは基本的にビューを返しコントローラを埋め込んでいるメインページ:

{% "base.html.twig" %} 
{% block title %}Main{% endblock %} 

{% block content %} 
..some markup here 
<div id="usersonline"> 
    {% render "AppBundle:Users:usersOnline" with {'max': 4} %} 
</div> 
{% endblock %} 

{% block scripts %} 
    ..some javascript 
{% endblock %} 

これは、それが延びていることが基本である:

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <title>{% block title %}{% endblock %} - App</title>  
    ...Some stylesheets 
    </head> 
    <body> 
     {% block content %}{% endblock %} 
     <script src="http://yui.yahooapis.com/3.5.0pr2/build/yui/yui-min.js"></script> 
     {% block scripts %}{% endblock %} 
    </body> 
</html> 

私が今直面しています問題は、組み込みコントローラからのJavaScriptを含めています。私の場合、ビューは部分的に拡張され、メインページに挿入される前に完全に1単位としてレンダリングされます。この場合、私はJavaScriptをcontentブロックに入れることができます。つまり、<script>タグを<div>タグ内に持つことになります。また、ユーザーインターフェイスのパフォーマンスのために、本文の最後にスクリプトを置くことをお勧めします。

エンベデッドコントローラのビューから、コントローラを埋め込んだテンプレート内の適切なブロックに適切な部分をレンダリングできるように、テンプレートをどのように構造化する必要がありますか?現在のテンプレートでは、埋め込みコントローラのHTMLマークアップの後にYUIライブラリが読み込まれるため、埋め込みコントローラ内のYUIライブラリを使用したアクセスは不可能です。

+0

[Duplicate](http://stackoverflow.com/q/9224347/1146363)でも読みやすいですが。私は組み込みコントローラの結果を複数のブロックに分割することはできないと思います。返される結果は、レンダリングされたhtmlであり、小枝のテンプレートではありません。私は、コンテンツ用とJavaScript用の2つの組み込みコントローラーが必要だと思います。そして、場合によっては、おそらくcssのための1つです。 – Cerad

+0

Hm。 2つのエンベデッドコントローラを持つことはアイデアよりも少なく、あまりエレガントではありません。 – F21

+0

実際には2つのコントローラーは必要ありません。つまり、{'generate': 'html'または 'js'または 'css'}を使用して、必要なものを指定する引数を持つ同じコントローラーを2回呼び出すだけです。それに応じてテンプレートを調整します。 – Cerad

答えて

0

私は本質的にこれに対処するトークンパーサーである拡張を書いています。トークンパーサのドキュメントは非常にまばらであり、コードもほとんどコメントされていないので、少しでも手間取って作業する必要がありました。

初めに、あなたは( {% use %}に似)何かを宣言なるように、私はパーサを構造化している

{% myparser "AppBundle:Users:usersOnline" with {'max': 4} as xyz %} 

その後xyzcontentのようなブロックがavaliableになり、その後、あなただけ使用して適切な場所でそれらをレンダリング{{ブロック( 'xyzcontent')}}それはかなりうまくいく。しかし、以下は動作しません。

{% set max = 4 %} 
{% myparser "AppBundle:Users:usersOnline" with {'max': max} as xyz %} 

式を評価し、その値をトークンパーサー内で直接取得する方法が見つかりませんでした。ほとんどの場合、この問題以外は正常に動作します。

誰かがトークンパーサ内の変数の値を取得する方法についてのいくつかのアイデアを持っている場合、それは私が最終的には、以下のために選択し、満足のいく解決策を探しての1日を過ごした後:)

+0

私は似たような問題の解決策を探し求めています。私の場合、複数のコントローラ(他のテンプレートを含む)を組み込むことができる「ウィジェット」バンドルを作成していますが、右ブロック( 'stylesheets'/'javascripts')のアセット(js/css/less)とにかく、Twig拡張コードを共有していただけますか?私自身のトークンパーサー(経験はない)を書くのはかなり難しいです。ありがとう、ありがとう。 –

0

素晴らしいことですアプローチ:

  • (既に行っているように)あなたのウィジェットの機能性のためのコントローラをレンダリングします。
  • ウィジェットのアセットを埋め込むためのテンプレートをレンダリングします(コントローラは不要で、パフォーマンスが浪費されます)。テンプレートが存在しない場合はインクルードを無視します。
  • ウィジェット機能をよりダイナミックにするために、一貫した命名規則を使用してください。

例1つのウィジェット用:

{% "base.html.twig" %} 
{% block title %}Main{% endblock %} 

{% block content %} 
..some markup here 
<div id="usersonline"> 
    {{ render(controller("AppBundle:Users:usersOnline", {'max': 4})) }} 
</div> 
{% endblock %} 

{% block scripts %} 
    {{ include("AppBundle:Users:usersOnline_js.html.twig" ignore missing }} 
{% endblock %} 

{% block stylesheets %} 
    {{ include("AppBundle:Users:usersOnline_css.html.twig" ignore missing }} 
{% endblock %} 

または、ウィジェットのレンダリングのよりダイナミックな方法を(あなたが見ることができるように、私を含むと埋め込みのsymfonyの2.2の方法を使用します):

{% "base.html.twig" %} 
{% block title %}Main{% endblock %} 

{% block widgets %} 
..some markup here 
    {% for widget in widgets %} 
    {{ render(controller(widget.controller ~ ':widget', widget.options)) }} 
    {% endfor %} 
{% endblock %} 

{% block scripts %} 
    {% for widget in widgets %} 
    {{ include(widget.controller ~ ':widget_js.html.twig' ignore missing }} 
    {% endfor %} 
{% endblock %} 

{% block stylesheets %} 
    {% for widget in widgets %} 
    {{ include(widget.controller ~ ':widget_css.html.twig' ignore missing }} 
    {% endfor %} 
{% endblock %} 

私の結論

1つのページに複数のコントローラをレンダリングしても、テンプレートブロックを「マージ」している間は、Symfony2でそのまま使用することはできません。 Symfony2は常に各リクエストごとに1つのコントローラに焦点を当ててきました。なぜなら、複数のコントローラ出力が分離され、組み合わせが難しい理由が説明されています。

Symfony CMFは、このウィジェットの全体的なトピックが動的コンテンツ管理のウェブサイトに多く適用されているため、適切なソリューションを持っていると思います。

とにかく、組み込みコントローラと組み込みテンプレートを組み合わせる私のやり方は、今までのところSymfony 2にとって最良のアプローチだと思います。

選択肢、私の意見では、多くの欠点を持っているか:

  • を複数のコントローラを使用した:重すぎると資産が任意のコントローラを必要としないので、必要ありません。
  • ウィジェットのアセットをページに直接ロードする:ウィジェット/アセットを変更するときに維持しにくい。