Полезно ли добавлять Edge Side Include в мои шаблоны?

В нашем приложении Symfony2 мы визуализируем повторно используемые блоки с помощью render_esi. У нас есть такие шаблоны:

{% for products as product %}
<div class="product">
    <h4>{{ product.name }}</h4>
    <div class="ratings">
    {{ render_esi(controller('AcmeDemoCommunityBundle:Rating:ratingStars', {
        objectType: 'product',
        objectId: product.id,
        readOnly: true
    })) }}
    </div>
</div>
{% endfor %}

И, конечно, мы используем render_esi также на странице сведений о продукте.

1 ответ

Я хотел бы дифференцировать различные типы блоков:

  • Блокирует рендеринг других действий того же контроллера.
  • Блоки, которые можно использовать в других частях приложения.

В чем разница?

Блоки, которые визуализируют только другие действия того же контроллера, что и родительский шаблон, чаще всего используются для модульной обработки одной страницы и обеспечения кэширования частей. Эти блоки используются только один раз во всем приложении.

Блоки, которые отображают такие детали, как звездочки рейтинга или комментарии, являются своего рода независимыми виджетами, которые предоставляют определенные функции. Текущий контроллер дозы ничего не знает об этом виджете. Этот вид блоков в основном используется несколько раз в приложении.

Что это значит для разработки программного обеспечения?

Это означает, что в будущем мы можем захотеть изменить способ работы комментариев и оценок. Может, ESI больше не будет отображаться в будущем, потому что мы передали функциональность стороннему сервису, и нам нужно только включить какой-то JavaScript в этом месте? Или мы делаем их напрямую?

Это то, что должен решать виджет, а не та часть, которая включает виджет.

Так, что я мог сделать, чтобы улучшить мой дизайн?

Вы могли бы продолжать использовать ESI (потому что это имеет смысл для вашего сценария использования), но вы должны изменить способ включения модулей в файлы Twig. Вы должны переместить логику для этого из шаблона в отдельное расширение Twig в AcmeDemoCommunityBundle.

namespace Acme\DemoCommunityBundle\Twig;

use Symfony\Component\HttpKernel\Fragment\FragmentHandler;
use Symfony\Component\HttpKernel\Controller\ControllerReference;
use Acme\DemoCommunityBundle\Rating\RateableInterface;

class CommunityExtension extends \Twig_Extension
{
    /**
     * @var string
     */
    const RATING_ACTION = 'AcmeDemoCommunityBundle:Rating:ratingStars';

    /**
     * @var FragmentHandler
     */
    protected $handler;

    public function __construct(FragmentHandler $handler)
    {
        $this->handler = $handler;
    }

    public function getFunctions()
    {
        return array(
            'community_rating' => new \Twig_Function_Method($this, 'communityRating', array('is_safe' => array('html'))),
        );
    }

    public function communityRating(RateableInterface $object, $readOnly = false)
    {
        return $this->handler->render(new ControllerReference(self::RATING_ACTION, array(
            'objectType' => $object->getRatingType(),
            'objectId' => $object->getId(),
            'readOnly' => $readOnly
        )), 'esi', $options);
    }

    public function getName()
    {
        return 'community';
    }
}
services:
    acme_community.twig.community:
        class:     Acme\DemoCommunityBundle\Twig\CommunityExtension
        arguments: [ @fragment.handler ]
        tags:
            - { name: twig.extension }

Теперь ваш шаблон должен выглядеть так:

{% for products as product %}
<div class="product">
    <h4>{{ product.name }}</h4>
    <div class="ratings">
    {{ community_rating(product, true) }}
    </div>
</div>
{% endfor %}

Благодаря такому дизайну в нашем приложении легко использовать звездочки рейтинга, но мы также можем гибко изменять реализацию, как рейтинги работают в будущем, не затрагивая шаблоны, в которых используются рейтинги.

Другие вопросы по тегам