跳到主內容

YouTube Embed Formatter

在Drupal 10做的第一個模組,主要的功能是要把文字欄位 ( youtube_id ) 轉換成播放器

/web/modules/contrib/ 底下建立目錄 youtube_embed

接著在目錄底下建立 youtube_embed.info.yml

name: 'YouTube Embed Formatter'
type: module
description: 'Formats a field containing a YouTube ID as an embedded video.'
core_version_requirement: ^10|^11
package: Custom
dependencies:
  - field

mkdir -p src/Plugin/Field/FieldFormatter/

cd src/Plugin/Field/FieldFormatter/

在目錄底下建立 YouTubeEmbedFormatter.php

<?php

namespace Drupal\youtube_embed\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;

/**
 * Plugin implementation of the 'youtube_embed' formatter.
 *
 * @FieldFormatter(
 *   id = "youtube_embed_formatter",
 *   label = @Translation("YouTube Embed with RWD and Autoplay"),
 *   field_types = {
 *     "string",
 *     "string_long"
 *   }
 * )
 */
class YouTubeEmbedFormatter extends FormatterBase {

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

    foreach ($items as $delta => $item) {
      // 取得 YouTube ID
      $youtube_id = trim($item->value);

      // 建立包含 RWD 功能和靜音自動播放的 iframe 標籤
      $elements[$delta] = [
        '#type' => 'markup',
        '#markup' => '<div class="youtube-video-wrapper"><iframe src="https://www.youtube.com/embed/' . htmlspecialchars($youtube_id, ENT_QUOTES, 'UTF-8') . '?autoplay=1&mute=0" frameborder="0" allowfullscreen></iframe></div>',
        '#allowed_tags' => ['iframe', 'div'],
      ];
    }

    return $elements;
  }
}

然後要搭配CSS達成RWD顯示

<style>
  /* 讓 YouTube 影片支援響應式 */
  .youtube-video-wrapper {
    position: relative;
    padding-bottom: 56.25%; /* 16:9 比例 */
    height: 0;
    overflow: hidden;
    max-width: 100%;
    background: #000;
    margin-bottom: 20px; /* 可選 */
  }

  .youtube-video-wrapper iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
</style>