# Rendering entity automatically

Some entity need to be rendered automatically for a couple of times: a person, a user, ...

One can use some twig filter to render those entities:

   {{ person|chill_entity_render_box }}

## Define a renderer

By default, the object passed through the renderer will be rendered using the `__toString()` method. To customize this behaviour, you have to define a service and tag it using `chill.render_entity`.

The rendered is implemented using :class:`Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface`. This interface has 3 methods:

* `public function supports($entity, array $options): bool`: return true if the `$entity` given in parameter, with custom options, is supported by this renderer;
* `public function renderString($entity, array $options): string`: render the entity as a single string, for instance in a select list;
* `public function renderBox($entity, array $options): string`: render the entity in a HTML box.

   The HTML returned by `renderBox` **MUST BE SAFE** of any XSS injection.

`Chill\MainBundle\Templating\Entity\AbstractChillEntityRender` provides some useful methods to get the opening and closing boxes that should be used.

Usage about rendering comment:

```php
   namespace Chill\MainBundle\Templating\Entity;

   use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
   use Chill\MainBundle\Repository\UserRepository;
   use Chill\MainBundle\Templating\Entity\AbstractChillEntityRender;
   use Symfony\Component\Templating\EngineInterface;

   class CommentRender extends AbstractChillEntityRender
   {
       /**
        * @var \Chill\MainBundle\Repository\UserRepository
        */
       private $userRepository;

       /**
        *
        * @var EngineInterface
        */
       private $engine;

       public function __construct(
           UserRepository $userRepository,
           EngineInterface $engine
       ) {
           $this->userRepository = $userRepository;
           $this->engine = $engine;
       }

       /**
        * @param CommentEmbeddable $entity
        * @param array $options
        *
        * @return string
        */
       public function renderBox($entity, array $options): string
       {
           // default options
           $options = \array_merge([
                   'user' => [],
                   'disable_markdown' => false,
                   'limit_lines' => null,
                   'metadata' => true
               ], $options);

           if ($entity->getUserId()) {
               $user = $this->userRepository->find($entity->getUserId());
           }

           return $this->engine
               ->render(
                   '@ChillMain/Entity/CommentEmbeddable.html.twig',
                   [
                       'opening_box' => $this->getDefaultOpeningBox('comment-embeddable'),
                       'closing_box' => $this->getDefaultClosingBox(),
                       'user' => $user ?? NULL,
                       'comment' => $entity,
                       'options' => $options
                   ]
               );
       }

       /**
        * @param CommentEmbeddable $entity
        * @param array $options
        *
        * @return string
        */
       public function renderString($entity, array $options): string
       {
           return $entity->getComment();
       }

       public function supports($entity, array $options): bool
       {
           return $entity instanceof CommentEmbeddable;
       }
   }
```

Logic inside the template:

```twig
   {# @var opening_box: string #}
   {# @var closing_box: string #}
   {{ opening_box|raw }}
   <div>
      {# logic for rendering #}
   </div>
   {{ closing_box|raw }}
```

## Usage in templates

For rendering an entity as a box:

   `{{ entity|chill_entity_render_box }}`

For rendering an entity as a string:

   `{{ entity|chill_entity_render_string }}`

## Available renderer and options

### `Person` (Person Bundle)

* no options

### `CommentEmbeddable` (Main Bundle)

Options :

* `user`: options, which will be passed to "user" renderer
* `disable_markdown`: disable markdown renderer, default to `FALSE`
* `limit_lines` (integer) limit the number of lines. Default to `NULL`. Can be an integer.
* `metadata` (boolean): show the last updating user and last updating date. Default to `TRUE`.
