从父Twig模板调用PHP业务逻辑

时间:2013-08-25 11:19:08

标签: php symfony twig

在我的Symfony2项目中,我使用Twig模板来呈现HTML,我需要一个“应用程序栏”来包含每个网站的页面。这个栏的内容取决于用户是谁,她有什么特权等等(换句话说,有一些需要在幕后执行的业务逻辑)。显而易见的解决方案似乎是在基本模板中添加app-bar(因为它需要出现在每个页面上)。然而,问题在于,不清楚如何从基础(父)Twig模板执行业务逻辑。

@Flukey在this question中遇到了类似的问题,他的解决方案是在{2}模板内的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 }

但是由于以下原因,这个解决方案对我非常不安:

  • 首先,此解决方案意味着您必须为网站上的每个导航栏管理单独的新网址
  • 其次,网站上每个导航栏的单独网址(上例中为http://mysite/sitestructure/appbar),这看起来非常混乱
  • 第三,还有this concern about performance,我觉得非常明智。我不明白为什么每个用户对HTML页面的请求都会导致两个(或三个或四个)物理请求被发送到服务器 - 对网站上的每个导航栏发出额外的render请求(随着网站变得越来越复杂,可能会添加更多的导航栏。)

那么有更好的方法吗?是否可以使用Twig的{% include %}功能而不是{% render %},如果是,那么基本模板的业务逻辑如何执行?

修改: 为了澄清,我所指的“业务逻辑”的类型将需要进行数据库调用 - 这不是我想要编写到模板中的逻辑类型,因此我需要以某种方式返回到PHP类/函数。 / p>

EDIT2 : 我真的应该担心打电话给子控制器吗?也许我误解了render引擎的工作方式。我假设这会向Web服务器生成第二个HTTP请求(显然不是来自Web浏览器,而是来自服务器本身的内部请求)。对我来说,这似乎意味着相当大的开销,更不用说产生某种响应错误的机会增加了。但是,也许我误解了框架,在这种情况下,请教育我!

1 个答案:

答案 0 :(得分:0)

我不确定我理解你的所有观点。

您当然可以创建app_bar模板并将其包含在基本模板中:

<body>
    {{ include('@MyBundle/app_bar.html.twig') }}
    {% block body %}{% endblock %}
</body>

您当然可以根据用户

在app_bar中显示不同的项目
{% if is_granted('ROLE_ADMINx') %}
    <li><a href="{{ path('zayso_natgames_admin') }}">Admin</a></li>
{% endif %}

目前尚不清楚您需要什么样的“业务逻辑”。如果它超出了简单的条件,那么你可以将代码放在一个枝条扩展中。

我觉得你需要更多的印象?也许有多种类型的app_bar?我不明白“每个导航栏”需要一些特别的东西。

您可能对如何实施子控制器存在误解。子控制器请求在内部完成。没有往返浏览器。性能影响很小。不需要多个网址,只需一个route_app_bar。

除非我完全误解了这个问题。