在我的 Symfony2 项目中,我使用 Twig 模板来呈现 HTML,并且我需要一个“应用程序栏”来包含网站的每个页面。这个栏的内容取决于用户是谁,她有什么权限等(换句话说,有一点业务逻辑需要在幕后执行)。显而易见的解决方案似乎是在基本模板中添加应用栏(因为它需要出现在每个页面上)。然而,这个问题是不清楚如何从基本(父)Twig 模板执行业务逻辑。
@Flukey 在这个问题中遇到了类似的问题,他的解决方案是render
从树枝模板中访问子控制器,从而强制执行辅助控制器。明确地说,他的解决方案如下所示:
{# ::base:html.twig #}
<!DOCTYPE html>
<html>
<head>
<title>blah</title>
{% block stylesheets %}{# default styles #}{% endblock %}
</head>
<body>
{# Question: is there a way to do add the app-bar without "render"? #}
{% render url('app_bar_route') %}
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>
还有孩子:
{# AcmeDemoBundle:userpage.html.twig #}
{% extends '::base.html.twig' %}
{% block body %}user content here; Twig file rendered from "primary" PHP Controller.{% endblock %}
为了render
工作,我们还需要定义路由:
# routing.yml
app_bar_route:
pattern: /sitestructure/appbar
defaults: { _controller: SiteManagerBundle:AppBar:index }
但是这个解决方案让我很不安,原因如下:
- 首先,此解决方案意味着您必须为网站上的每个导航栏管理单独的新 URL
- 其次,网站上的每个导航栏都有一个单独的 URL(在
http://mysite/sitestructure/appbar
上面的示例中),这看起来很混乱 - 第三,还有这种对性能的担忧,我觉得这是非常明智的担忧。我不明白为什么每个单独的用户对 HTML 页面的请求都应该导致两个(或三个或四个)物理请求被发送到服务器——
render
站点上每个导航栏的额外请求(更多导航栏随着网站变得更加复杂,可能会添加)。
那么有没有更好的方法来做到这一点?是否可以使用 Twig 的{% include %}
功能代替{% render %}
,如果可以,如何执行基本模板的业务逻辑?
编辑:为了澄清,我所指的“业务逻辑”类型将需要进行数据库调用——这不是我想在模板中编码的逻辑类型,所以我需要以某种方式回到 PHP 类/函数.
EDIT2:我真的应该担心调用子控制器吗?也许我误解了render
引擎的工作方式。我假设这会向 Web 服务器生成第二个 HTTP 请求(显然不是来自 Web 浏览器,而是来自服务器本身的内部请求)。对我来说,这似乎意味着相当大的开销,更不用说增加产生某种响应错误的机会了。但是可能我对框架有误解,在这种情况下,请不吝赐教!