在我的Symfony2項目中,我使用Twig模板來呈現HTML,並且我需要一個「應用程序欄」來包含每個網站的頁面。這個欄的內容取決於用戶是誰,她擁有什麼特權等(換句話說,有一些業務邏輯需要在幕後執行)。顯而易見的解決方案似乎是在基本模板中添加應用程序欄(因爲它需要出現在每個頁面上)。然而,問題在於,如何從基本(父)Twig模板執行業務邏輯尚不清楚。從父樹枝模板調用PHP業務邏輯
@Flukey在this question中遇到了類似的問題,他的解決方案是從樹枝模板中的子控制器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
- 其次,是(在本例中
http://mysite/sitestructure/appbar
以上)的網站上的每個導航欄單獨的URL ,這似乎很雜亂 - 第三,也有this concern about performance,我覺得非常明智的關注。我不明白爲什麼每個用戶對HTML頁面的請求都會導致兩個(或三個或四個)物理請求被髮送到服務器 - 爲該網站上的每個導航欄添加一個額外的
render
請求(更多nav-當網站變得更加複雜時,酒吧可能會被添加)。
那麼有沒有更好的方法來做到這一點?是否可以使用Twig的{% include %}
功能而不是{% render %}
,如果是這樣,基模板的業務邏輯如何執行?
編輯: 爲了澄清,「商業邏輯」,我指的需要進行數據庫調用的類型 - 這不是邏輯我想代碼插入到模板的類型,所以我需要以某種方式獲得回到PHP類/函數。
EDIT2: 我真的很擔心打電話給子控制器嗎?也許我誤解了render
引擎的工作方式。我認爲這會對Web服務器產生第二個HTTP請求(顯然不是來自Web瀏覽器,而是來自服務器本身的內部請求)。對我而言,這似乎意味着相當大的開銷,更不用說增加產生某種響應錯誤的機會。但後來也許我誤解了框架,在這種情況下,請教育我!
我談論的「業務邏輯」可能會包括數據庫調用(但我並不是真的想讓這個問題陷入太多細節)。主要的一點是,我需要回到PHP類來做一些額外的邏輯。我知道如何在Smarty中做到這一點,但Twig的哲學看起來有點不同。 – cartbeforehorse
你可能是對的,我不明白子控制器是如何實現的。如果這一切都是在內部完成的,那麼它並沒有我想象的那麼糟糕。我只需要接受這是它的工作原理。 – cartbeforehorse
枝條與Smarty不同。既用我投了枝杈。你可以用樹枝擴展的方式進行數據庫調用,但幾乎可以肯定地使用子控制器。這:http://symfony.com/doc/current/components/http_kernel/introduction.html可能有點壓倒性,但如果你向下滾動到接近底部,子請求被解釋。 – Cerad