How to Create a Custom Field Formatter in Drupal 8 & 9
In Drupal, field values are displayed to the end user via a field formatter. Formatters that come with fields are often pretty basic. If you want to change what a field displays, then the best way to do this is to write a custom formatter.
In this tutorial, we’ll create a custom formatter for the link field that’ll allow an editor to display an embedded YouTube video.
The link field will be used to store a YouTube URL and the formatter will be used to display the embedded video.
we’ll need to create a module called YouTube Formatter (youtube_formatter) and place it in the /modules
directory.
Create .info.yml file
name: YouTube Formatter
type: module
description: 'YouTube formatter'
core: 8.x
package: Custom
dependencies:
- field
Create Formatter class
Now it’s time to implement the actual field formatter. We do this by defining a class called YouTubeLinkFormatter
that extends the FormatterBase
. Then in the class we’ll use the viewElements()
method to display the formatter.
1. Create a file called YouTubeLinkFormatter.php
and place it in <module>/lib/Drupal/youtube_formatter/Plugin/Field/FieldFormatter/YouTubeLinkFormatter.php
.
Open YouTubeLinkFormatter.php
and add the following:
<?php
namespace Drupal\youtube_formatter\Plugin\Field\FieldFormatter;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
/**
* Plugin implementation of the 'youtube_link' formatter.
*
* @FieldFormatter(
* id = "youtube_link",
* label = @Translation("YouTube Formatter"),
* field_types = {
* "link"
* }
* )
*/
class YouTubeLinkFormatter extends FormatterBase
{
/**
* Builds a renderable array for a field value.
*
* @param \Drupal\Core\Field\FieldItemListInterface $items
* The field values to be rendered.
* @param string $langcode
* The language that should be used to render the field.
*
* @return array
* A renderable array for $items, as an array of child elements keyed by
* consecutive numeric indexes starting from 0.
*/
public function viewElements(FieldItemListInterface $items, $langcode)
{
$elements = array();
foreach ($items as $delta => $item) {
$url =$item->getUrl();
$elements[$delta] = array(
'#theme' => 'youtube_link_formatter',
'#url' => $url,
);
}
return $elements;
}
}
The annotation attributes are pretty self-explanatory. All we’ve done is define an ID, label and which field type this formatter should be available on.
The field_types
attribute is the most important part, if you don’t add "link"
then this formatter will not appear on the manage display page.
Create template
Now that we’ve built the formatter, let’s finish off the module by creating a custom template for it.
Instead of adding HTML code inside of the viewElements()
method, we’ll use a custom template. The template will be called youtube_link_formatter
and it’ll accept the URL as the single parameter.
Open up youtube_formatter.module
and add the following function:
<?php
/**
* @file
* Defines simple YouTube formatter for the link field.
*/
/**
* Implements hook_theme().
*/
function youtube_formatter_theme() {
return array(
'youtube_link_formatter' => array(
'variables' => array('url' => NULL),
'template' => 'youtube-link-formatter',
),
);
}
then create a folder in the module called templates
and a file called youtube-link-formatter.html.twig
.
In the .twig
file, add the following:
<iframe width="100%" height="400"
src="{{ url }}"
frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
Now that we’ve finished everything it’s time to test the formatter. Go to your Drupal 8 site and install the Link and YouTube Formatter module.
Go and create a Link field on a content type, and in the manage display page you should be able to select “YouTube Formatter” as the formatter.
Once you’ve configured the formatter, create an article and enter a YouTube embed URL (not URL to the video page) into the link field.
Example embed url: https://www.youtube.com/embed/8uhNFoOnz_g
I hope you found this article useful. let me know if you have any questions and I’ll be happy to answer them.