Score:0

How do I migrate body content with [embed]*[/embed] tags?

fr flag

Currently I am working on migrating a Drupal 7 site to Drupal 9. The nodes in the site has nodes with content similar to the following one.

<h3><strong>WHAT WILL YOUR NEXT MEAL BE?</strong></h3>
<p>[embed]https://www.youtube.com/watch?v=Np28O3Y_P2o[/embed]</p>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry galley of type and Lorem Ipsum</p>

I tried to dump the value into the Body field with the Rich Text Filter, but the nodes are displayed with a link between [embed] and [/embed], instead of a render item.

Can anyone please suggest a migration plugin or a way to convert <p>[embed]https://www.youtube.com/watch?v=Np28O3Y_P2o[/embed]</p> to Drupal 9 Media entities?

Score:1
in flag

I am not aware about any plugins for this case.

But you can write your custom plugin.

In the custom plugin you will need to parse text by a regular expression and create youtube media entities from it manually.

Here are some code examples to point you to a right direction.

The migration process plugin will parse the text, and process embed parts:

<?php

namespace Drupal\my_migrate\Plugin\migrate\process;

use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;

/**
 * Provides a body text migrate process plugin.
 *
 * @MigrateProcessPlugin(
 *  id = "body_text"
 * )
 */
class BodyText extends ProcessPluginBase {

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    $body = '';

    if (preg_match_all('/[embed](.*)[/embed]/Usi', $text, $matches)) {
      // Text parts splitted by embeds.
      $text_parts = preg_split('/[embed](.*)[/embed]/Usi', $text);

      $body = $text_parts[0];
      unset($text_parts[0]);
      $text_parts = array_values($text_parts);

      // Loop text parts, create media embeds.
      foreach ($text_parts as $key => $text_part) {
        if (isset($matches[1][$key])) {
          $embed = $matches[1][$key];
          if (!$text) {
            $this->addTag(MigrationTags::TAG_MISSING_QUOTE);
          }
          $body .= $this->createYoutubeEmbed($embed);
        }

        $body .= $text_part;
      }
    }
    return $body;
  }

  protected function createYoutubeEmbed($embed) {
    // 1. Create youtube media entity using the URL.
    // 2. Generate media embed.
  }

}


In the createYoutubeEmbed method you will need to

  1. Create youtube media entity using the URL.
  2. Generate media embed. To figure out how the youtube media embed should look like, create some content in Drupal manually and see the source code in the CKEditor.

This is an example for media image embed that I implemented in my migration:

/**
   * Creates media image embed for text paragraphs.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media image.
   * @param string $align
   *   (optional) The image alignment, allowed values: left, right, center.
   * @param string $display
   *   (optional) The image display variant. Allowed values: large (default),
   *   medium, small.
   * @param string $link
   *   (optional) Link URL.
   *
   * @return string
   *   The embed code.
   */
  protected function createMediaImageEmbed(MediaInterface $media, $align = '', $display = 'large', $link = NULL) {
    $attributes = [
      'data-embed-button' => $media->bundle(),
      'data-entity-embed-display' => 'view_mode:media.' . $display,
      'data-align' => $align,
      'data-entity-type' => 'media',
      'data-entity-uuid' => $media->uuid(),
      'data-langcode' => 'de',
    ];
    if ($link) {
      $link = str_replace("/", "\/", $link);
      $attributes['data-entity-embed-display-settings'] = '{&quot;link_url&quot;:&quot;' . $link . '\/&quot;,&quot;link_url_target&quot;:0}';
    }
    $embed = '<drupal-entity';
    foreach ($attributes as $key => $value) {
      $embed .= " $key=\"$value\"";
    }
    $embed .= '></drupal-entity>';
    return $embed;
  }
miststudent2011 avatar
fr flag
Thank you for your answer, Markup part was the missing piece in my custom Migration Plugin, will try to integrate the markup in my plugin .
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.