# Extending thumbnails

The thumbnails API enable you to choose an image for a specific content. If you don't want to use custom thumbnails, `ContentType` is used instead.

## Thumbnail mechanism

The thumbnail mechanism has two layers, and each layer can have many implementations. The mechanism checks if any of the implementations returns a field, for example, `ibexa_image`, that has function "Can be a thumbnail" turned on.

If found, the image is used as a content type thumbnail.

### First layer

First layer of the mechanism contains strategy pattern that focuses on finding a thumbnail source. The thumbnail can be found inside or outside the content type. For example for users thumbnails can be downloaded from an avatar-generating service.

For this layer there are following default implementations:

- The mechanism looks for fields that can be thumbnail, if found, the mechanism moves to the second layer.
- If there are no fields that can be a thumbnail, the content type icon is used as a thumbnail.

### Second layer

Second layer of mechanism enables selection of thumbnail from a field that the first layer has found. It searches the content type for all the fields, for example, images, with function "Can be a thumbnail" turned on.

If there is more than one field in the content type that can be used as a thumbnail, this layer returns the first nonempty field as a thumbnail.

This mechanism can be modified to fit your site needs, so you can decide from where and how the thumbnails is downloaded.

### Create a thumbnail mechanism

First, create base strategy for returning custom thumbnails from a static file. Create `StaticStrategy.php` in `src/Strategy`.

```
<?php

declare(strict_types=1);

namespace App\Strategy;

use Ibexa\Contracts\Core\Repository\Strategy\ContentThumbnail\ThumbnailStrategy;
use Ibexa\Contracts\Core\Repository\Values\Content\Thumbnail;
use Ibexa\Contracts\Core\Repository\Values\Content\VersionInfo;
use Ibexa\Contracts\Core\Repository\Values\ContentType\ContentType;

final readonly class StaticThumbnailStrategy implements ThumbnailStrategy
{
    public function __construct(private string $staticThumbnail)
    {
    }

    public function getThumbnail(ContentType $contentType, array $fields, ?VersionInfo $versionInfo = null): Thumbnail
    {
        return new Thumbnail([
            'resource' => $this->staticThumbnail,
        ]);
    }
}
```

Next, add the strategy with the `ibexa.repository.thumbnail.strategy.content` tag and `priority: 100` to `config/services.yaml`:

```
services:
    App\Thumbnails\FieldValueUrl:
        tags:
            - { name: ibexa.repository.thumbnail.strategy.field, priority: 100 }
```

Priority `100` allows this strategy to be used first on a clean installation or before any other strategy with lower priority.

At this point you can go to the back office and check the results.

Thumbnail mechanism

This strategy overrides all generated thumbnails. You can specify a specific content type. See the example [here](https://github.com/ibexa/user/blob/main/src/lib/Strategy/DefaultThumbnailStrategy.php)

## Other fields as thumbnails

Any field type can generate a thumbnail, for example:

- DateAndTime (`ibexa_datetime`) - you can add a mini calendar thumbnail for Appointment content type and on the day of the appointment a clock thumbnail with a specific time when it takes place
- TextBlock (`ibexa_text`) - you can add a first letter of the text block that is inside

### Add ibexa_text field as thumbnail

First, create a strategy that adds support for `ibexa_text` as the thumbnail. It enables you to add a thumbnail URL in the text field.

Add `FieldValueUrl.php` in `src/Thumbnails`.

```
<?php

declare(strict_types=1);

namespace App\Thumbnails;

use Ibexa\Contracts\Core\Repository\Values\Content\Field;
use Ibexa\Contracts\Core\Repository\Values\Content\Thumbnail;
use Ibexa\Contracts\Core\Repository\Strategy\ContentThumbnail\Field\FieldTypeBasedThumbnailStrategy;
use Ibexa\Contracts\Core\Repository\Values\Content\VersionInfo;

class FieldValueUrl implements FieldTypeBasedThumbnailStrategy
{
    public function getFieldTypeIdentifier(): string
    {
        return 'ibexa_text';
    }

    public function getThumbnail(Field $field, ?VersionInfo $versionInfo = null): ?Thumbnail
    {
        return new Thumbnail([
            'resource' => $field->value,
        ]);
    }
}
```

Next, add the strategy with the `ibexa.repository.thumbnail.strategy.field` tag to `config/services.yaml`:

```
    App\Thumbnails\FieldValueUrl:
        tags:
            - { name: ibexa.repository.thumbnail.strategy.field, priority: 100 }
```

At this point you can go to the back office and check the results.
