logo

एक्स्ट्रा ब्लॉक टाइप्स (EBT) - नया लेआउट बिल्डर अनुभव❗

एक्स्ट्रा ब्लॉक टाइप्स (EBT) - स्टाइलिश, कस्टमाइज़ेबल ब्लॉक टाइप्स: स्लाइडशो, टैब्स, कार्ड्स, एकॉर्डियन्स और कई अन्य। बैकग्राउंड, DOM बॉक्स, जावास्क्रिप्ट प्लगइन्स के लिए बिल्ट-इन सेटिंग्स। आज ही लेआउट बिल्डिंग का भविष्य अनुभव करें।

डेमो EBT मॉड्यूल्स EBT मॉड्यूल्स डाउनलोड करें

❗एक्स्ट्रा पैराग्राफ टाइप्स (EPT) - नया पैराग्राफ्स अनुभव

एक्स्ट्रा पैराग्राफ टाइप्स (EPT) - एनालॉजिकल पैराग्राफ आधारित मॉड्यूल्स का सेट।

डेमो EPT मॉड्यूल्स EPT मॉड्यूल्स डाउनलोड करें

स्क्रॉल

9.10.3. Drupal में फील्ड्स के साथ काम करना। यूट्यूब से वीडियो जोड़ने के लिए अपना खुद का फील्ड टाइप, विजेट और फॉर्मैटर बनाना।

17/10/2025, by Ivan

Menu

पिछले लेखों में हमने देखा कि लिंक फील्ड टाइप कैसे काम करता है: स्टोरेज, विजेट, फॉर्मेटर। इस लेख में हम एक नया फील्ड टाइप बनाएंगे जो पेज पर यूट्यूब से वीडियो दिखाने के लिए होगा, जिसमें दो अलग-अलग फॉर्मेट और सेटिंग्स होंगी।

यह लेख Fields API पर केंद्रित है, और यदि आपको अपनी साइट पर यूट्यूब वीडियो फील्ड जोड़ने की आवश्यकता है, तो बेहतर होगा कि आप तैयार मॉड्यूल का उपयोग करें:

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

मैंने सारा कोड GitHub पर drupalbook_youtube मॉड्यूल में जोड़ा है, आप मॉड्यूल डाउनलोड करके अपनी साइट में जोड़ सकते हैं:

https://github.com/levmyshkin/drupalbook8

आइए इस मॉड्यूल की संरचना देखें और मैं समझाने की कोशिश करूंगा कि यह फील्ड टाइप कैसे काम करता है:

modules/custom/drupalbook_youtube/drupalbook_youtube.info.yml

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

यह मॉड्यूल की मेटाडाटा को निर्धारित करता है।

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;
  }
 
}

यह फील्ड टाइप Drupal को बताता है कि इस फील्ड के लिए टेबल में क्या संग्रहित किया जाएगा।

<?php
 
namespace Drupal\drupalbook_youtube\Plugin\Field\FieldType;
 
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;
Define namespaces for our type of field.

यहाँ हमारे क्लास के लिए एक एब्स्ट्रैक्ट लिखा गया है, जिससे Drupal हमारे फील्ड टाइप का नाम और मशीन नाम प्राप्त करेगा।

class DrupalbookYoutubeItem extends FieldItemBase {

क्लास के नाम के अंत में "Item" लिखना सर्वोत्तम प्रथा है।

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

हम परिभाषित करते हैं कि हम टेक्स्ट टाइप का value फील्ड संग्रहित करेंगे।

/**
 * {@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;
}

हम MySQL टेबल और एंटिटी ऑब्जेक्ट के लिए कॉलम का वर्णन करते हैं। परिणामस्वरूप, पूरा लिंक संग्रहित किया जाएगा:

select

अब जब हमने फील्ड टाइप जोड़ लिया है, तो डेटा दर्ज करने के लिए एक विजेट बनाएँ:

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."));
    }
  }
 
}

यह विजेट हमें एंटिटी एडिटिंग फॉर्म में डेटा दर्ज करने की अनुमति देगा।

क्लास एनोटेशन में हमें field_type निर्दिष्ट करना होता है, जिसे हमने ऊपर बनाया था, यानी drupalbook_youtube

क्लास के नाम के अंत में "Widget" जोड़ें ताकि यह स्पष्ट हो कि यह क्लास फील्ड विजेट के लिए है।

हम एक साधारण टेक्स्टफील्ड बनाते हैं जहाँ उपयोगकर्ता यूट्यूब वीडियो का लिंक दर्ज करेगा।

validate() फ़ंक्शन उपयोगकर्ता द्वारा दर्ज लिंक की जाँच करता है कि वह सही यूट्यूब URL है या नहीं। यदि गलत है, तो यह त्रुटि दिखाता है।

अब जब हम फील्ड में डेटा दर्ज कर सकते हैं, तो हमें एक Field Formatter जोड़ना होगा ताकि डेटा प्रदर्शित हो सके।

modules/custom/drupalbook_youtube/src/Plugin/FieldFieldFormatter/DrupalbookYoutubeThumbnailFormatter.php

हमारे पास दो फॉर्मैटर होंगे। पहला एक साधारण होगा, जो केवल वीडियो की थंबनेल और यूट्यूब लिंक दिखाएगा:

<?php

namespace Drupal\drupalbook_youtube\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldItemListInterface;

/**
 * Plugin implementation of the 'drupalbook_youtube_thumbnail' formatter.
 *
 * @FieldFormatter(
 *   id = "drupalbook_youtube_thumbnail",
 *   module = "drupalbook_youtube",
 *   label = @Translation("Displays video thumbnail"),
 *   field_types = {
 *     "drupalbook_youtube"
 *   }
 * )
 */
class DrupalbookYoutubeThumbnailFormatter extends FormatterBase {

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    $elements = array();

    foreach ($items as $delta => $item) {
      preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=v\/)[^&\n]+(?=\?)|(?<=v=)[^&\n]+|(?<=youtu.be/)[^&\n]+#", $item->value, $matches);

      if (!empty($matches)) {
        $content = '<a href="' . $item->value . '" target="_blank"><img src="http://img.youtube.com/vi/' . $matches[0] . '/0.jpg"></a>';
        $elements[$delta] = array(
          '#type' => 'html_tag',
          '#tag' => 'p',
          '#value' => $content,
        );
      }

    }

    return $elements;
  }

}

यहाँ #type को html_tag के रूप में उपयोग किया गया है, ताकि HTML सीधे पेज पर प्रदर्शित हो सके। $delta का उपयोग कई वीडियो फील्ड को सपोर्ट करने के लिए किया जाता है।

अब हम एक जटिल फॉर्मैटर बनाएँगे जो टेम्पलेट और सेटिंग्स का उपयोग करेगा:

modules/custom/drupalbook_youtube/src/Plugin/FieldFieldFormatter/DrupalbookYoutubeVideoFormatter.php

<?php
 
namespace Drupal\drupalbook_youtube\Plugin\Field\FieldFormatter;
 
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
 
/**
 * Plugin implementation of the 'drupalbook_youtube_video' formatter.
 *
 * @FieldFormatter(
 *   id = "drupalbook_youtube_video",
 *   module = "drupalbook_youtube",
 *   label = @Translation("Displays Youtube video"),
 *   field_types = {
 *     "drupalbook_youtube"
 *   }
 * )
 */
class DrupalbookYoutubeVideoFormatter extends FormatterBase {
 
  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return array(
      'width' => '600',
      'height' => '450',
    ) + parent::defaultSettings();
  }
 
  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $elements['width'] = array(
      '#type' => 'textfield',
      '#title' => t('Youtube video width'),
      '#default_value' => $this->getSetting('width'),
    );
    $elements['height'] = array(
      '#type' => 'textfield',
      '#title' => t('Youtube video height'),
      '#default_value' => $this->getSetting('height'),
    );
 
    return $elements;
  }
 
  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    $elements = array();
    $width = $this->getSetting('width');
    $height = $this->getSetting('height');
 
    foreach ($items as $delta => $item) {
      preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=v\/)[^&\n]+(?=\?)|(?<=v=)[^&\n]+|(?<=youtu.be/)[^&\n]+#", $item->value, $matches);
 
      if (!empty($matches)) {
        $elements[$delta] = array(
          '#theme' => 'drupalbook_youtube_video_formatter',
          '#width' => $width,
          '#height' => $height,
          '#video_id' => $matches[0],
        );
      }
    }
 
    return $elements;
  }
 
  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {
    $summary = [];
    $settings = $this->getSettings();
 
    if (!empty($settings['width']) && !empty($settings['height'])) {
      $summary[] = t('Video size: @width x @height', ['@width' => $settings['width'], '@height' => $settings['height']]);
    } else {
      $summary[] = t('Define video size');
    }
    return $summary;
  }
 
}

यहाँ settingsForm() के माध्यम से हम फील्ड फॉर्मैटर के लिए वीडियो की चौड़ाई और ऊँचाई को बदल सकते हैं।

इसके बाद हमें टेम्पलेट परिभाषित करना होगा:

modules/custom/drupalbook_youtube/templates/drupalbook-youtube-video-formatter.html.twig

{#
/**
 * @file
 * Default theme implementation of a simple Youtube video.
 *
 * Available variables:
 * - width: Youtube video width.
 * - height: Youtube video height.
 * - video_id: Youtube video ID.
 */
#}
{% spaceless %}
  <iframe width="{{ width }}" height="{{ height }}" src="https://www.youtube.com/embed/{{ video_id }}" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen>iframe>
{% endspaceless %}

अब आप यूट्यूब वीडियो फील्ड बना सकते हैं और उसका आउटपुट Drupal के फॉर्मैटर के माध्यम से देख सकते हैं।

link

यहीं पर हम कस्टम फील्ड निर्माण समाप्त करेंगे और अब Entity API की ओर बढ़ेंगे, जहाँ हम कस्टम एंटिटी प्रकार बनाएंगे।