如何在模板中嵌入控制器
在某些情况下,你需要做的不止包含一个简单的模板。假设你有一个菜单栏sidebar在你的布局文件中来显示最新的文章。获取三篇最新文章可能需要查询数据库或者执行其他包含很多逻辑的操作,这样就不能在一个模板中完成了。
这种情况的解决方案是简单的嵌入一个完整的控制器结果到你的模板。首先,创建一个控制器来渲染特定数量的最近文章:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// src/AppBundle/Controller/ArticleController.PHP
namespace AppBundle\Controller;
// ...
class ArticleController extends Controller
{
public function recentArticlesAction($max = 3)
{
// make a database call or other logic
// to get the "$max" most recent articles
$articles = ...;
return $this->render(
'article/recent_list.HTML.twig',
array('articles' => $articles)
);
}
} |
这个recent_list
模板很简单:
1 2 3 4 5 6 |
{# app/Resources/views/article/recent_list.html.twig #}
{% for article in articles %}
<a href="/article/{{ article.slug }}">
{{ article.title }}
</a>
{% endfor %} |
1 2 3 4 5 6 |
<!-- app/Resources/views/article/recent_list.html.php -->
<?php foreach ($articles as $article): ?>
<a href="/article/<?php echo $article->getSlug() ?>">
<?php echo $article->getTitle() ?>
</a>
<?php endforeach ?> |
请注意,这篇文章的URL被硬编码在案例中(例如 /article/*slug*
)。这是不好的做法。在下一节中,你将学习如何正确做。
为了能包含控制器,你需要使用一个标准的字符语法来表示控制器,格式类似bundle:controller:action
1 2 3 4 5 6 7 8 9 |
{# app/Resources/views/base.html.twig #}
{# ... #}
<div id="sidebar">
{{ render(controller(
'AppBundle:Article:recentArticles',
{ 'max': 3 }
)) }}
</div> |
1 2 3 4 5 6 7 8 9 10 11 |
<!-- app/Resources/views/base.html.php -->
<!-- ... -->
<div id="sidebar">
<?php echo $view['actions']->render(
new \Symfony\Component\HttpKernel\Controller\ControllerReference(
'AppBundle:Article:recentArticles',
array('max' => 3)
)
) ?>
</div> |
你需要一个变量或者一些列信息时,你不必在模板中访问,而是考虑渲染一个控制器。因为控制器能够更快的执行并且很好的提高了代码的组织和复用。当然,像所有的控制器,它们都应该“瘦身”,这意味着尽可能多的代码应该被做成可复用的服务。