logo

Extra Block Types (EBT) - Nieuwe Layout Builder ervaringâť—

Extra Block Types (EBT) - gestileerde, aanpasbare bloktypes: Slideshows, Tabs, Cards, Accordions en vele andere. Ingebouwde instellingen voor achtergrond, DOM Box, javascript-plugins. Ervaar vandaag al de toekomst van layout building.

Demo EBT-modules Download EBT-modules

âť—Extra Paragraph Types (EPT) - Nieuwe Paragraphs ervaring

Extra Paragraph Types (EPT) - analoge op paragrafen gebaseerde set modules.

Demo EPT-modules Download EPT-modules

Scroll

9.10.3. Werken met velden in Drupal. Maak je eigen veldtype, widget en formatter voor het invoegen van video's van YouTube.

17/10/2025, by Ivan

Menu

In eerdere artikelen hebben we gezien hoe het veldtype Link werkt: Storage, Widget, Formatter. In dit artikel gaan we ons eigen veldtype maken voor het weergeven van een YouTube-video op een pagina, met twee verschillende weergaveformaten en instellingen.

Dit artikel richt zich op de Fields API, en als je gewoon een YouTube-videoveld aan je site wilt toevoegen, kun je beter de kant-en-klare module gebruiken:

https://www.drupal.org/project/video_embed_field

Ik heb alle code op GitHub toegevoegd in de module drupalbook_youtube; je kunt de module downloaden en aan je site toevoegen:

https://github.com/levmyshkin/drupalbook8

Laten we de bestanden van deze module bekijken, en ik zal proberen uit te leggen hoe dit type veld werkt:

modules/custom/drupalbook_youtube/drupalbook_youtube.info.yml

name: DrupalBook Youtube
type: module
description: Youtube embed field
core: 8.x
package: Custom

We bepalen hiermee de metadata van de module.

modules/custom/drupalbook_youtube/src/Plugin/Field/FieldType/DrupalbookYoutubeItem.php

<?php
 
namespace Drupal\drupalbook_youtube\Plugin\Field\FieldType;
 
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;
 
/**
 * Plugin implementation of the 'drupalbook_youtube' field type.
 *
 * @FieldType(
 *   id = "drupalbook_youtube",
 *   label = @Translation("Embed Youtube video"),
 *   module = "drupalbook_youtube",
 *   description = @Translation("Output video from Youtube."),
 *   default_widget = "drupalbook_youtube",
 *   default_formatter = "drupalbook_youtube_thumbnail"
 * )
 */
class DrupalbookYoutubeItem extends FieldItemBase {
  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition) {
    return array(
      'columns' => array(
        'value' => array(
          'type' => 'text',
          'size' => 'tiny',
          'not null' => FALSE,
        ),
      ),
    );
  }
 
  /**
   * {@inheritdoc}
   */
  public function isEmpty() {
    $value = $this->get('value')->getValue();
    return $value === NULL || $value === '';
  }
 
  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties['value'] = DataDefinition::create('string')
      ->setLabel(t('Youtube video URL'));
 
    return $properties;
  }
 
}

We maken een veldtype aan zodat Drupal weet wat er in de tabel voor dit veld zal worden opgeslagen.

<?php
 
namespace Drupal\drupalbook_youtube\Plugin\Field\FieldType;
 
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;
Definieer namespaces voor ons veldtype.

/**
 * Plugin implementation of the 'drupalbook_youtube' field type.
 *
 * @FieldType(
 *   id = "drupalbook_youtube",
 *   label = @Translation("Embed Youtube video"),
 *   module = "drupalbook_youtube",
 *   description = @Translation("Output video from Youtube."),
 *   default_widget = "drupalbook_youtube",
 *   default_formatter = "drupalbook_youtube_thumbnail"
 * )
 */

We schrijven een abstract voor onze klasse; vanuit deze abstractie zal Drupal de naam en machine-naam van ons veldtype afleiden.

class DrupalbookYoutubeItem extends FieldItemBase {

De naam van de klasse eindigt bij voorkeur op Item.

/**
 * {@inheritdoc}
 */
public static function schema(FieldStorageDefinitionInterface $field_definition) {
  return array(
    'columns' => array(
      'value' => array(
        'type' => 'text',
        'size' => 'tiny',
        'not null' => FALSE,
      ),
    ),
  );
}

We definiëren dat we de waarde van het veld als tekst zullen opslaan.

/**
 * {@inheritdoc}
 */
public function isEmpty() {
  $value = $this->get('value')->getValue();
  return $value === NULL || $value === '';
}

Als er een aanroep van dit veld plaatsvindt vanuit externe code, geven we een lege waarde terug voor het geval het veld leeg is.

/**
 * {@inheritdoc}
 */
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
  $properties['value'] = DataDefinition::create('string')
    ->setLabel(t('Youtube video URL'));
 
  return $properties;
}

We beschrijven onze kolommen voor de MySQL-tabel en het entiteitsobject. Als resultaat slaan we de volledige link op:

select

Nu we het veldtype hebben toegevoegd, maken we een Widget om gegevens in te voeren:

modules/custom/drupalbook_youtube/src/Plugin/Field/FieldWidget/DrupalbookYoutubeWidget.php

<?php
 
namespace Drupal\drupalbook_youtube\Plugin\Field\FieldWidget;
 
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
 
/**
 * Plugin implementation of the 'drupalbook_youtube' widget.
 *
 * @FieldWidget(
 *   id = "drupalbook_youtube",
 *   module = "drupalbook_youtube",
 *   label = @Translation("Youtube video URL"),
 *   field_types = {
 *     "drupalbook_youtube"
 *   }
 * )
 */
class DrupalbookYoutubeWidget extends WidgetBase {
 
  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $value = isset($items[$delta]->value) ? $items[$delta]->value : '';
    $element += array(
      '#type' => 'textfield',
      '#default_value' => $value,
      '#size' => 32,
      '#maxlength' => 256,
      '#element_validate' => array(
        array($this, 'validate'),
      ),
    );
    return array('value' => $element);
  }
 
  /**
   * Validate the color text field.
   */
  public function validate($element, FormStateInterface $form_state) {
    $value = $element['#value'];
    if (strlen($value) == 0) {
      $form_state->setValueForElement($element, '');
      return;
    }
    if(!preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=v\/)[^&\n]+(?=\?)|(?<=v=)[^&\n]+|(?<=youtu.be/)[^&\n]+#", $value, $matches)) {
      $form_state->setError($element, t("Youtube video URL is not correct."));
    }
  }
 
}

De widget maakt het mogelijk om gegevens in te voeren op het bewerkingsformulier van de entiteit.

/**
 * Plugin implementation of the 'drupalbook_youtube' widget.
 *
 * @FieldWidget(
 *   id = "drupalbook_youtube",
 *   module = "drupalbook_youtube",
 *   label = @Translation("Youtube video URL"),
 *   field_types = {
 *     "drupalbook_youtube"
 *   }
 * )
 */

In de annotatie bij de klasse moeten we het field_type vermelden dat we eerder hebben aangemaakt, namelijk drupalbook_youtube.

class DrupalbookYoutubeWidget extends WidgetBase {

Aan het einde van de klassenaam voegen we Widget toe, zodat duidelijk is dat deze klasse bedoeld is als Field Widget.