简体   繁体   English

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

[英]calling PHP business logic from parent Twig templates

In my Symfony2 project I use Twig templates to render the HTML, and I need an "application-bar" to be included each one of the website's pages. 在我的Symfony2项目中,我使用Twig模板来呈现HTML,并且需要一个“应用程序栏”来包含网站的每个页面。 The contents of this bar depend on who the user is, what privileges she has, etc. (in other words, there's a bit of business logic that needs to be executed behind the scenes). 该栏的内容取决于用户的身份,用户拥有的特权等(换句话说,需要在后台执行一些业务逻辑)。 The obvious solution would seem to be to add the app-bar in the base template (since it needs to appear on each page). 显而易见的解决方案似乎是在基础模板中添加应用栏(因为它需要出现在每个页面上)。 The problem with this however, is that it's not clear how the business logic is to be executed from the base (parent) Twig template. 但是,这样做的问题在于,尚不清楚如何从基本(父)Twig模板执行业务逻辑。

@Flukey had a similar problem in this question , where his solution is to render a sub-controller from within a twig template, thereby forcing the execution of a secondary controller. @Flukey在此问题中有一个类似的问题,其中他的解决方案是从树枝模板中render子控制器,从而强制执行辅助控制器。 To be explicit, his solution looks as follows: 明确地说,他的解决方案如下所示:

{# ::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>

And the child: 和孩子:

{# AcmeDemoBundle:userpage.html.twig #}
{% extends '::base.html.twig' %}
{% block body %}user content here; Twig file rendered from "primary" PHP Controller.{% endblock %}

In order for the render to work, we also require the route to be defined: 为了使render工作,我们还需要定义路径:

# routing.yml
app_bar_route:
    pattern:  /sitestructure/appbar
    defaults: { _controller: SiteManagerBundle:AppBar:index }

But this solution lies very uneasily with me for the following reasons: 但是由于以下原因,这个解决方案对我来说很不舒服:

  • Firstly, this solution means that you have to manage separate new URL for each navigation-bar on your site 首先,此解决方案意味着您必须为网站上的每个导航栏管理单独的新URL
  • Secondly, there is a separate URL for every nav-bar on the site ( http://mysite/sitestructure/appbar in the example above), which just seems very messy 其次, 对于在网站上每一个导航栏单独的URL( http://mysite/sitestructure/appbar在上面的例子),这似乎只是很凌乱
  • Thirdly, there is also this concern about performance , which I find very sensible concern. 第三,我也非常关注性能 ,这是我对性能的关注。 I don't see why each individual user-request to an HTML page should result in two (or three or four) physical requests being sent to the server -- an extra render request for each nav-bar on the site (more nav-bars are likely to be added as the site gets more complex). 我不明白为什么每个用户对HTML页的请求都应该导致将两个(或三个或四个)物理请求发送到服务器-网站上每个导航栏都需要一个额外的render请求(更多nav-随着网站变得越来越复杂,可能会添加条形图)。

So is there a better way to do this? 那么,有没有更好的方法呢? Is it possible to use Twig's {% include %} functionality instead of {% render %} , and if so, how does the business logic for the base template get executed? 是否可以使用Twig的{% include %}功能代替{% render %} ,如果可以,基本模板的业务逻辑如何执行?

EDIT : To clarify, the type of 'business logic' that I refer to will require making database calls -- it's not the type of logic I want to code into the template, so I need somehow to get back into a PHP class/function. 编辑 :为澄清起见,我所指的“业务逻辑”类型将需要进行数据库调用-这不是我要编码到模板中的逻辑类型,因此我需要以某种方式返回到PHP类/函数。

EDIT2 : Should I really be worrying about making calls to sub-controllers? EDIT2 :我真的应该担心打电话给子控制器吗? Perhaps I misunderstood the way the render engine works. 也许我误解了render引擎的工作方式。 I assumed that this would generate a second HTTP request to the web-server (obviously not from the Web browser, but an internal one from the server itself). 我以为这将向Web服务器生成第二个HTTP请求(显然不是从Web浏览器,而是从服务器本身的内部HTTP请求)。 To me, this would seem to imply quite large overheads, not to mention increased chance of producing some kind of response error. 对我来说,这似乎意味着相当大的开销,更不用说增加产生某种响应错误的机会了。 But then maybe I have misunderstood the framework, in which case, please educate me! 但是,也许我误解了该框架,在这种情况下,请教育我!

I'm not sure I understand all of your points. 我不确定我是否理解您的所有观点。

You can certainly make a app_bar template and include it in your base template: 您当然可以制作一个app_bar模板并将其包含在基本模板中:

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

You can certainly show different items in app_bar based on the user 您当然可以根据用户在app_bar中显示不同的项目

{% if is_granted('ROLE_ADMINx') %}
    <li><a href="{{ path('zayso_natgames_admin') }}">Admin</a></li>
{% endif %}

It's not clear what other sort of "business logic" you need. 尚不清楚您需要什么其他类型的“业务逻辑”。 If it goes beyond simple conditionals then you could put the code in a twig extension. 如果超出简单的条件,则可以将代码放在树枝扩展中。

I sort of get the impression that you need more? 我有点觉得您需要更多吗? Multiple types of app_bar perhaps? 可能是多种类型的app_bar? I don't understand the stuff about "each navigation bar" needs something special. 我不了解有关“每个导航栏”的内容需要一些特殊的东西。

It's possible that you may have a misunderstanding about how sub controllers are implemented. 您可能对子控制器的实现方式有误解。 Sub-controller requests are done internally. 子控制器的请求在内部完成。 No round trip to the browser. 无需往返浏览器。 Performance impact is minor. 对性能的影响很小。 No need for multiple url's, Just one route_app_bar. 不需要多个网址,只需一个route_app_bar。

Unless of course I completely misunderstood the question. 当然,除非我完全误解了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM