xurshid29 xurshid29 - 2 months ago 15
Twig Question

Best way to create blocks in Symfony2

I usually use Symfony2 framework to develope API for mobile applications. But my current task is to develope desktop application for online marketplace where there will be multiple blocks, like top 5 sellers block, top 5 brands block, popular products (10 products), latest 10 products, similar 10 products (this will be shown on product page) and so on.. There will be about 25 blocks.. I am searching for the best way to create these blocks without contrib bundle. I know there is SonataBlockBundle which gives this functionality, but I don't want to use it for some reason. Currently I'm planning to create Twig Functions (extension) for every block, and include them where I want. but I'm interested in how do you create them, by micros, or by rendering controllers, or embedding templates?..

UPDATE:

I don't want to post my solution as an answer, that's why I'm updating the question.. So, I ended up with creating macros and Twig extension (functions, and service which renders my blocks' content).. I didn't like to render controllers in templates, as it breaks design pattern principles, such as controller must deal with business logic, and view must return just view, nothing else. Mixing them is not a good way I think..

Answer

In my opinion, if you will have to use that block anywhere at anytime on your site, you can set as a service.

For example; if you want to show latest 10 products on the right side of your site;

<?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.
    }
}

Define this service on your services.yml or xml.

<service id="product.service" class="YOUR\UniqueBundle\ServiceFolder\ProductService">
    <argument type="service" id="service_container" />
</service>

Define this function to your twig extension.

public function getLatestProducts($count)
{
    return $this->container->get('product.service')->getLatestProducts($count);
}

And call that function anytime and anywhere you want.

{% block latest_products %}
    {% set products = getLatestProducts(10) %}
    {# Do templating here #}
{% endblock %}

Note: Twig extension will need to load container to call services.