在Symfony2中创建块的最佳方法

时间:2014-05-21 05:51:10

标签: symfony twig

我通常使用Symfony2框架为移动应用程序开发API。但我目前的任务是为在线市场开发桌面应用程序,其中将有多个块,如前5个卖家块,前5个品牌块,流行产品(10个产品),最新10个产品,类似10个产品(这将显示在产品页面)等等。将会有大约25个块..我正在寻找创建这些块而不使用contrib bundle的最佳方法。我知道有SonataBlockBundle提供了这个功能,但我不想出于某种原因使用它。目前,我计划为每个块创建Twig函数(扩展),并将它们包含在我想要的位置。但是我对如何通过微观,渲染控制器或嵌入模板创建它们感兴趣?

更新

我不想发布我的解决方案作为答案,这就是为什么我要更新问题。所以,我最终创建了宏和Twig扩展(功能和服务)渲染我的块'内容)..我不想在模板中渲染控制器,因为它违反了设计模式原则,例如控制器必须处理业务逻辑,而视图必须只返回视图,没有别的。混合它们不是我想的好方法..

3 个答案:

答案 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 topSellertopBrands操作的整个输出注入#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
        ];
    }
}