Skip to content

Instantly share code, notes, and snippets.

@adamzimmermann
Created May 18, 2021 12:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamzimmermann/5213a22fd13b3deaffdadf964bdb9345 to your computer and use it in GitHub Desktop.
Save adamzimmermann/5213a22fd13b3deaffdadf964bdb9345 to your computer and use it in GitHub Desktop.
Converts custom media tokens into responsive images.
<?php
namespace Drupal\chromatic_image\Plugin\Filter;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
/**
* Provides a filter for rendering custom media tokens.
*
* @Filter(
* id = "filter_media_image_token",
* title = @Translation("Media Image Tokens"),
* description = @Translation("Renders media image tokens."),
* type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE,
* )
*/
class FilterImageToken extends FilterBase implements ContainerFactoryPluginInterface {
/**
* The default responsive image style.
*/
const DEFAULT_RESPONSIVE_STYLE = 'content_image';
/**
* The regex used to find the media tokens.
*/
const TOKEN_REGEX = '/\[media:(\d+):?([a-z|_]*)\S*?\]/';
/**
* The entity query service.
*
* @var \Drupal\Core\Entity\Query\QueryFactory
*/
protected $entityQuery;
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityManager;
/**
* The renderer service.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* Constructs a token filter plugin.
*
* {@inheritdoc}
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
EntityTypeManagerInterface $entityManager,
RendererInterface $renderer) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityManager = $entityManager;
$this->renderer = $renderer;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('entity_type.manager'),
$container->get('renderer')
);
}
/**
* {@inheritdoc}
*/
public function process($text, $langcode) {
$text = preg_replace_callback(
self::TOKEN_REGEX,
function ($matches) {
$mediaEntity = $this->entityManager->getStorage('media')->load($matches[1]);
if (!$mediaEntity) {
return NULL;
}
$caption = $mediaEntity->field_media_image_caption->getValue();
$image = [
'#theme' => 'chromatic_body_image',
'#image' => [
'#theme' => 'responsive_image',
'#responsive_image_style_id' => $this->determineResponsiveStyleId($matches[2]),
'#uri' => $mediaEntity->field_media_image->entity->getFileUri(),
'#attributes' => [
'alt' => $mediaEntity->field_media_image->alt,
],
],
'#caption' => !empty($caption[0]) ? check_markup($caption[0]['value'], $caption[0]['format']) : '',
'#full_width' => (strpos($matches[0], 'full') !== FALSE),
];
return $this->renderer->render($image);
},
$text
);
$result = new FilterProcessResult($text);
return $result;
}
/**
* {@inheritdoc}
*/
public function tips($long = FALSE) {
$build = [];
$build[] = [
'#markup' => $this->t('Create media image tokens using the format <code>[media:mid:responsive_style:full]</code>, the <code>content_image</code> style will be used by default. For full width images, include <code>full</code> as an optional last token segment.'),
];
return $this->renderer->render($build);
}
/**
* Determines the responsive image style that should be used.
*
* @param string $tokenImageStyle
* The style passed in through the token.
*
* @return string
* The verified responsive image style name.
*/
private function determineResponsiveStyleId($tokenImageStyle) {
$responseImageStyleStorage = $this->entityManager->getStorage('responsive_image_style');
if (!empty($tokenImageStyle) && $responseImageStyleStorage->load($tokenImageStyle)) {
return $tokenImageStyle;
}
return self::DEFAULT_RESPONSIVE_STYLE;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment