Templates 带资源的嵌入式控制器视图

Templates 带资源的嵌入式控制器视图,templates,symfony,Templates,Symfony,我目前正在开发symfony2应用程序,并使用嵌入式控制器。我的嵌入式控制器就像小部件,它应该封装自己的一组功能,可以嵌入任何地方,并且仍然可以正常工作 我有一个名为“在线用户”的控制器。它生成的视图很简单,只是一个在线用户列表。但是,我想在该视图中添加一些javascript,这样我就可以使用ajax为单击的用户检索信息 控制器基本上返回一个视图: return $this->render('AppBundle:Users:usersOnline.html.twig', array('s

我目前正在开发symfony2应用程序,并使用嵌入式控制器。我的嵌入式控制器就像小部件,它应该封装自己的一组功能,可以嵌入任何地方,并且仍然可以正常工作

我有一个名为“在线用户”的控制器。它生成的视图很简单,只是一个在线用户列表。但是,我想在该视图中添加一些javascript,这样我就可以使用ajax为单击的用户检索信息

控制器基本上返回一个视图:

return $this->render('AppBundle:Users:usersOnline.html.twig', array('somedata' => $data);
以下是该控制器的视图:

{% 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 %}
{% "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 %}
以下是嵌入控制器的主页面:

{% 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 %}
{% "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 %}
{%”base.html.twig“%}
{%block title%}Main{%endblock%}
{%block content%}
…这里有一些标记
{%render“AppBundle:Users:usersOnline”与{'max':4}%}
{%endblock%}
{%block scripts%}
…一些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>

{%block title%}{%endblock%}-App
…一些样式表
{%block content%}{%endblock%}
{%block scripts%}{%endblock%}
我现在面临的问题是包含来自嵌入式控制器的Java脚本。在我的例子中,视图扩展为部分视图,并在插入主页之前完全呈现为1个单元。在这种情况下,我只能将javascript放在
内容
块中,这意味着我将在
标记中有
标记。我还希望在正文的末尾有脚本,以提高用户界面性能


我应该如何构造我的模板(或者甚至是可能的),以便能够将嵌入控制器的视图中的适当片段渲染到嵌入控制器的模板中的适当块中?在我当前的模板中,YUI库将在嵌入式控制器呈现的HTML标记之后加载,因此不可能在嵌入式控制器中使用YUI库进行访问。

我编写了一个扩展,它本质上是一个令牌解析器来处理此问题。令牌解析器的文档非常稀少,代码也大多没有注释,因此需要花点时间才能开始工作

我构造了解析器,以便在开始时声明一些东西(类似于
{%use%}
):

然后像
xyzcontent
这样的块将可用,然后您只需使用{{block('xyzcontent')}在适当的位置渲染它们。它工作得很好。但是,以下情况不起作用:

{% set max = 4 %}
{% myparser "AppBundle:Users:usersOnline" with {'max': max} as xyz %}
我找不到一种方法来计算表达式并直接在令牌解析器中获取其值。在大多数情况下,除了这个问题,它工作正常


如果有人知道如何在令牌解析器中获取变量的值,那就太好了:)

经过一天的寻找令人满意的解决方案,我最终选择以下方法:

  • 为小部件的功能呈现控制器(就像您已经在做的那样)
  • 渲染模板以嵌入小部件的资产(不需要控制器,这将浪费您的性能)。如果模板不存在,则忽略包含
  • 使用一致的命名约定使小部件功能更加动态
一个小部件的示例:

{% "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 %}
我的结论

在一个页面中呈现多个控制器,同时“合并”其模板块,无法在Symfony2中实现开箱即用。Symfony2始终关注每个请求的一个控制器,这解释了为什么多个控制器输出是分离的,并且很难组合

我认为symfonycmf已经(或者将会)有一个合适的解决方案,因为整个widget主题更多地应用于动态内容管理网站

无论如何,我认为我将嵌入式控制器和包含的模板相结合的方法是目前为止Symfony 2的最佳方法

在我看来,替代方案确实有许多缺点:

  • 使用多个控制器:太重,不需要,因为资产不需要任何控制器
  • 直接在页面中加载小部件资产:更改小部件/资产时很难维护

虽然更容易阅读。我不认为嵌入式控制器的结果可以分为多个模块。返回的结果只是呈现的html,而不是细枝模板。我认为您需要两个嵌入式控制器,一个用于内容,一个用于javascript。在某些情况下,css.Hm甚至可能有一个。拥有两个嵌入式控制器比idea要少,而且在我看来也不是很优雅。实际上,您不需要两个控制器,只需要对同一个控制器进行两次调用,并使用一个参数指定所需内容,即{“generate”:“html”或“js”或“css”}。然后相应地调整你的模板。我正在拼命寻找一个类似问题的解决方案:在我的例子中,我正在编写一个“小部件”包,它能够嵌入多个控制器(这意味着,包括其他模板),但我希望能够将资产(js/css/less)“注册”到正确的块(“样式表”/“javascripts”)。不管怎样,你能分享一下你的小枝分机码吗?编写自己的令牌解析器非常困难(没有使用它的经验)。谢谢你。
{% "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 %}