在Twig模板中包含控制器,而不是其他模板

时间:2013-02-28 12:17:59

标签: php templates twig

据我所知,像Twig这样的模板引擎的主要设计思想是从视图中删除所有PHP代码,并让呈现视图的控制器设置该视图中所需的所有参数。

但是,假设视图包含不同的“块”:标题,页脚,购物车和产品列表。您可以让order_controller.php检查客户是否已登录(因为如果没有,则标题不包含“注销”链接),以及获取所有可用产品的列表(以显示它们)产品块),以及在$ _SESSION中获取购物车的内容(在购物车块中显示)。

然而,让order_controller只获取一件东西可能更有趣:产品列表。然后,控制器将呈现的视图将包含其他块(页眉,页脚和购物车)的不同包含,但它们不包括其视图。它们将包括其他控制器(showheader_controller,showfooter_controller和showcart_controller),而这些控制器又会呈现它们自己的单个块(showheader_controller只会呈现标题视图等...)。简而言之:您将包含在主视图中呈现视图的控制器。检查客户是否登录的逻辑将是showheader_controller,原因很简单,标题视图是唯一需要知道此视图的视图。从$ _SESSION加载购物车内容的逻辑将是showcart_controller,因为cart-view是唯一需要访问此数据的视图等...

这样,你可能有大量的控制器都显示标题,但是不是让每个控制器重复逻辑来检查客户是否登录,你只能在一个地方(控制器)渲染标题视图)。 如果有一个Twig函数在视图中的那个位置包含任何外部源,问题将得到修复(因为我可以只包括其他控制器),但因为它只允许包含其他模板(不能他们有PHP逻辑,否则就有点失败了。)

我现在修复此问题的方法是让order_controller具有以下逻辑:

  • 获取产品列表
  • 开始缓冲输出流(ob_start())
  • 包括呈现标题的控制器(showheader_controller)
  • 将缓冲区的内容存储在变量$ headerView。
  • 清理缓冲区
  • 开始缓冲输出流(ob_start())
  • 包括呈现购物车的控制器(showcart_controller)
  • 将缓冲区的内容存储在变量$ cartView。
  • 清理缓冲区
  • 冲洗并重复......

在视图中,我打印设置变量的内容:

{{ headerView | raw }}

必须添加原始过滤器,因为headerView变量包含html-tags。

它完美无缺,但它并不完全“整洁”。

我的问题:是否有更好的方法来实现这一策略?

1 个答案:

答案 0 :(得分:3)

首先,通过更好地实施MVC分离可以简化这一过程。控制器的工作几乎完全是为了对事件作出反应,并将模型用于响应此事件做适当的事情。握住视线并不是控制器的工作,视图也完全不依赖于控制器。

该模型是您的核心应用程序,建模应用程序应该执行的所有操作。视图的工作是可视化应用程序中发生的事情,为用户提供与之交互的内容。控制器只是用户和应用程序之间的一点点胶水,可以让用户控制应用程序。

因此,控制器对诸如“用户访问的主页”之类的事件作出反应,触发模型中的必要事件,这导致视图更新以表示应用程序的新状态。视图可以做任何需要做的事情。视图不仅仅是Twig模板。视图可以与模型对话以获取更多信息。最后,控制器不需要向Twig模板发送必要的数据,而是需要在呈现模板之前为模板设置必要数据的视图。控制器中的代码更少,视图中的代码更多。

如果您想使其更加模块化,您可以定义自定义Twig标签或功能,这些标签或功能可以从需要提取的任何位置获取必要的数据。例如:

<div class="head">{{ user_login_status() }}</div>

user_login_status是一个Twig扩展函数,它可以与模型对话以获取显示状态所需的数据。

希望你明白这一点。

相关问题