2012-02-11 15 views
1

我目前正在开发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 %} 

这是从延伸部分:

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

{% block scripts %}{% 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 %} 

这是,它的延伸基:

<!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块中,这意味着我将在<div>标签内有<script>标签。我还希望在用户界面性能的主体末尾有脚本。

我应该如何构建我的模板(或甚至可能),以便可以将嵌入控制器的模板中适当的块从嵌入式控制器的视图中渲染为适当的块?在我当前的模板中,YUI库将在嵌入式控制器呈现的HTML标记之后加载,因此在嵌入式控制器内使用YUI库是不可能的。

+0

[Duplicate](http://stackoverflow.com/q/9224347/1146363)虽然更易于阅读。我不认为嵌入式控制器的结果可以在多个块之间分配。返回的结果只是呈现的html而不是树枝模板。我认为你需要两个嵌入式控制器,一个用于内容,另一个用于JavaScript。在某些情况下,甚至可能只有一个用于CSS。 – Cerad 2012-02-11 14:17:39

+0

嗯。拥有2个嵌入式控制器不太理想,而且不是很优雅的imo。 – F21 2012-02-12 04:13:14

+0

那么你实际上并不需要两个控制器,只需要两个调用同一个控制器的参数,该参数指定你想要的内容,即{'generate':'html'或'js'或'css'}。然后相应地调整你的模板。 – Cerad 2012-02-12 13:10:03

回答

0

我写了一个扩展,它本质上是一个令牌解析器来处理这个问题。令牌解析器的文档非常稀少,并且代码也大部分是未注释的,因此需要花费一些时间才能开始工作。

我已经构造的解析器,以便在一开始,你就宣告的东西(类同{% use %}):

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

然后,像xyzcontent块是avaliable,然后你只使用使它们在合适的地方{{block('xyzcontent')}}。它工作得很好。但是,以下内容不起作用:

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

我找不到一种方法来评估表达式并直接在令牌解析器中获取其值。大多数情况下,它工作正常,除了这个问题。

如果有人有一些想法,如何获得令牌解析器中的变量的值,这将是巨大的:)

+0

我拼命寻找类似问题的解决方案:在我的情况下,我正在写一个能够嵌入多个控制器(这意味着包括其他模板)的'小部件'包,但我希望能够'注册' ('样式表'/'javascripts')的资产(js/css/less)。无论如何,你能分享你的Twig扩展代码吗?编写我自己的令牌解析器非常困难(没有经验)。谢谢你的优势。 – 2013-03-06 20:45:21

0

寻找一个令人满意的解决方案一天后,我终于选择以下方法:

  • 为你的小部件的功能呈现一个控制器(就像你已经在做);
  • 渲染模板以嵌入您的小部件的资产(不需要控制器,会浪费您的性能)。忽略包含模板不存在的情况。
  • 使用一致的命名约定可使窗口小部件功能更具动态性。

举例一个小部件:

{% "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 %} 

我的结论

在一个页面中渲染多个控制器,而“合并”模板块时,无法在Symfony2中实现。 Symfony2一直专注于每个请求的一个控制器,这就解释了为什么多个控制器输出分离并难以组合。

我认为Symfony CMF已经(或将要)为此提供了一个合适的解决方案,因为整个小部件主题更多地应用于动态内容托管网站。

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

的替代品,在我看来,确实有许多缺点:

  • 使用多个控制器:过重,而不是必要的,因为资产将不需要任何控制器。
  • 直接在页面中加载小部件资产:更改小部件/资产时很难维护。
相关问题