Upgrade Your Drupal Skills
We trained 1,000+ Drupal Developers over the last decade.
See Advanced Courses NAH, I know EnoughWriting custom fields in Drupal 8 - Part 1
On a recent project we had to create a section that is basically a Twitter search for a hashtag. It needed to be usuable in different sections of the layout and work the same. Also, we were using the Paragraphs module and came up with a pretty nifty (we think) solution of creating a custom field that solved this particular problem for us. I will walk you through how to create a custom field/widget/formatter for Drupal 8. There are Drupal console commands for generating boilerplate code for this... which I will list before going through each of the methods for the components.
Field Type creation
The first thing to do is create a custom field. In a custom module (here as "my_module") either run drupal:generate:fieldtype
or create a file called HashTagSearchItem.php
in src/Plugin/Field/FieldType
. The basic structure for the class will be:
namespace Drupal\my_module\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\TypedData\DataDefinition;
class HashtagSearchItem extends FieldItemBase {
}
Next, implement a few methods that will tell Drupal how our field will be structured. Provide a default field settings for the field that will be the count for the amount of tweets to pull. This will return of default settings keyed by the setting's name.
public static function defaultFieldSettings() {
return [
'count' => 6
] + parent::defaultFieldSettings();
}
Then provide the field item's properties. In this case there will be an input for hashtag and a count. Each property will be keyed by the property name and be a DataDefinition
defining what the properties will hold.
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
$properties = [];
$properties['hashtag_search'] = DataDefinition::create('string')
->setLabel(t('The hashtag to search for.'));
$properties['count'] = DataDefinition::create('integer')
->setLabel(t('The count of twitter items to pull.'));
return $properties;
}
Then provide a schema for the field. This will be the properties that we have created above.
public static function schema(FieldStorageDefinitionInterface $field_definition) {
return [
'columns' => [
'hashtag_search' => [
'type' => 'varchar',
'length' => 32,
],
'count' => [
'type' => 'int',
'default' => 6
]
]
];
}
Field widget creation
Next create the widget for the field, which is the actual form element and it's settings. Either drupal:generate:fieldwidget
or create a file in src/Plugin/Field/FieldWidget/
called HashtagSearchWidget.php
. This is the class' skeleton:
namespace Drupal\my_module\Plugin\Field\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
class HashtagSearchWidget extends WidgetBase {
}
Then implement several methods. Provide a default count of tweets to pull for new fields and the settings form for the field item:
public static function defaultSettings() {
return [
'default_count' => 6,
] + parent::defaultSettings();
}
public function settingsForm(array $form, FormStateInterface $form_state) {
$elements = [];
$elements['default_count'] = [
'#type' => 'number',
'#title' => $this->t('Default count'),
'#default_value' => $this->getSetting('default_count'),
'#empty_value' => '',
'#min' => 1
];
return $elements;
}
public function settingsSummary() {
$summary = [];
$summary[] = t('Default count: !count', array('!count' => $this->getSetting('default_count')));
return $summary;
}
Then create the actual form element. Add the hashtag textfield and count number field and wrap it in a fieldset for a better experience:
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$item = $items[$delta];
$element['hashtag_search'] = [
'#type' => 'textfield',
'#title' => $this->t('Hashtag'),
'#required' => FALSE,
'#size' => 60,
'#default_value' => (!$item->isEmpty()) ? $item->hashtag_search : NULL,
];
$element['count'] = [
'#type' => 'number',
'#title' => $this->t('Pull count'),
'#default_value' => $this->getSetting('default_count'),
'#size' => 2
];
$element += [
'#type' => 'fieldset',
];
return $element;
}
In part 2, Bez will show you how to pull the tweets and create a field formatter for the display of the tweets. You can read that post here!
About Drupal Sun
Drupal Sun is an Evolving Web project. It allows you to:
- Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
- Facet based on tags, author, or feed
- Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
- View the entire article text inline, or in the context of the site where it was created
See the blog post at Evolving Web