我通常使用Symfony2框架为移动应用程序开发API。但我目前的任务是为在线市场开发桌面应用程序,其中将有多个块,如前5个卖家块,前5个品牌块,流行产品(10个产品),最新10个产品,类似10个产品(这将显示在产品页面)等等。将会有大约25个块..我正在寻找创建这些块而不使用contrib bundle的最佳方法。我知道有SonataBlockBundle提供了这个功能,但我不想出于某种原因使用它。目前,我计划为每个块创建Twig函数(扩展),并将它们包含在我想要的位置。但是我对如何通过微观,渲染控制器或嵌入模板创建它们感兴趣?
更新
我不想发布我的解决方案作为答案,这就是为什么我要更新问题。所以,我最终创建了宏和Twig扩展(功能和服务)渲染我的块'内容)..我不想在模板中渲染控制器,因为它违反了设计模式原则,例如控制器必须处理业务逻辑,而视图必须只返回视图,没有别的。混合它们不是我想的好方法..
答案 0 :(得分:4)
在我看来,如果您必须在网站上的任何时间使用该块,您可以将其设置为服务。
例如;如果您想在您网站的右侧显示最新的10个产品;
<?php
namespace YOUR\UniqueBundle\ServiceFolder;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ProductService
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function getLatestProducts($count) // may be another variables like category etc.
{
// Get entity manager and set the products and return result.
}
}
在services.yml或xml上定义此服务。
<service id="product.service" class="YOUR\UniqueBundle\ServiceFolder\ProductService">
<argument type="service" id="service_container" />
</service>
将此功能定义为您的枝条延伸。
public function getLatestProducts($count)
{
return $this->container->get('product.service')->getLatestProducts($count);
}
随时随地调用该功能。
{% block latest_products %}
{% set products = getLatestProducts(10) %}
{# Do templating here #}
{% endblock %}
注意:Twig扩展需要加载容器来调用服务。
答案 1 :(得分:3)
您可以在树枝模板中渲染任何控制器的输出,如下所示:
<div id="sidebar">
{{ render(controller('MyStoreShopBundle:MyController:topSellers')) }}
{{ render(controller('MyStoreShopBundle:MyController:topBrands')) }}
(...)
</div>
然后定义MyStore\ShopBundle\Controller\MyController
行动:
/**
* @Template
*/
public function topSellersAction()
{
$topSellers = $this->someMethodToGetTopSellers();
return array('topSellers' => $topSellers);
}
/**
* @Template
*/
public function topBrandsAction()
{
$topBrands = $this->someMethodToGetTopBrands();
return array('topBrands' => $topBrands);
}
为此新操作创建模板。
这会将MyStore\ShopBundle\Controller\MyController
topSeller
和topBrands
操作的整个输出注入#sidebar div
。请记住,MyStore\ShopBundle\Controller\MyController
阻止操作模板无法扩展其他树枝模板,应该很简单。这些操作也无法处理重定向。
您可以阅读有关嵌入控制器的更多信息[此处]。(http://symfony.com/doc/current/book/templating.html#embedding-controllers)
您可以随时注入{{ render(controller('...')) }}
。
答案 2 :(得分:2)
您可以create macro(s)定义“块”,然后用内容填充它。要获取内容块,我建议每个块creating services,然后使用宏
渲染数据某些控制器和动作的伪代码:
/**
* SomeController
* @Route("/some-route")
*/
class SomeController extends Controller
{
/**
* @Route("/", name="some_index")
* @Template
*/
public function indexAction()
{
$block1 = $this->get('some.block1');
$block2 = $this->get('some.block2');
// and so on
return [
'block1' => $block1->someMethod(),
'block2' => $block2->someOtherMethodMaybe(),
// and so on
];
}
}