Add example on how to migrate data into Custom Field

Created on 25 February 2025, about 2 months ago

Problem/Motivation

It would be nice if there was a very basic example of migrating data into Custom Field.

A link to an example could also work.

Steps to reproduce

  1. Have multivalue fields that need to be migrated into Drupal 10
  2. Preferring to not migrate into Paragraphs, since it can get complicated, but not sure how difficult it is with Custom Field ...

Proposed resolution

Add a simple example on a doc page, for example how to import two fields "Link text" and "Link URL".

Remaining tasks

User interface changes

API changes

Data model changes

πŸ“Œ Task
Status

Active

Version

3.1

Component

Documentation

Created by

πŸ‡©πŸ‡°Denmark ressa Copenhagen

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @ressa
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Are you asking for an example for instance with migration yml via migrate_plus module? Its been a bit since I've done migrations and it certainly depends on what the source data looks like but I believe would be handled through a sub_process plugin just like if you were importing into a multi-value drupal core link field. Something like this example? This makes some broad assumptions about the data of course... other migrate plugins may be needed depending on the source.

      field_links:
        plugin: sub_process
        source: links
        process:
          url:
            plugin: get
            source: link/url
          title:
            plugin: get
            source: link/title
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Same idea as if you had a multi-valued address field using the address module. Custom fields are structured just like address fields or link fields. The properties are just dynamic. Migrations should be handled exactly the same way as if you were importing into one of these field types.

  • πŸ‡©πŸ‡°Denmark ressa Copenhagen

    Thanks for a fast reply @apmsooner, stellar support!

    And sorry if my request was a bit vague. But yes, I am looking for an example of a classic migration with Migrate and Migrate Plus, and your example was exactly what I was looking for. I'll give it a spin, and maybe create a documentation page later. Thanks!

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Okay great! I think that example works but like i said its been a bit. That example would be pertinent if you were migrating from e.g. xml with structure like:

    <links>
        <link>
            <url>https://www.example.com</url>
            <title>Example Website</title>
        </link>
        <link>
            <url>https://www.wikipedia.org</url>
            <title>Wikipedia</title>
        </link>
        <link>
            <url>https://www.github.com</url>
            <title>GitHub</title>
        </link>
    </links>

    Migrating from csv is a little more challenging for multi-valued fields so I try to avoid it. Feeds module is also supported in custom_field but its a little tricky with multi-valued, you'd basically need to have a source thats providing json that you can import into a temporary target and have a feeds event subscriber in custom module that would convert the data on presave. Here's an example of that:

    /**
     * Subscribe to events from the `feeds` module.
     */
    class FeedsEventSubscriber implements EventSubscriberInterface {
    
      /**
       * {@inheritDoc}
       */
      public static function getSubscribedEvents(): array {
        $events = [];
        $events[FeedsEvents::PROCESS_ENTITY_PRESAVE][] = 'presave';
        return $events;
      }
    
      /**
       * Acts on presaving an entity.
       *
       * @param \Drupal\feeds\Event\EntityEvent $event
       *   The feed event.
       */
      public function presave(EntityEvent $event) {
        $json = $event->getItem()->get('portions_json');
        $values = json_decode($json, TRUE);
        $event->getEntity()->get('field_weights')->setValue($values);
      }
    
    }
  • πŸ‡©πŸ‡°Denmark ressa Copenhagen

    Thanks very much for sharing those examples, they will surely help users who like to use Feed for import.

    It seems that the Migrate ecosystem has the best support for a JSON-source (I also personally prefer JSON-format, as well as Migrate over Feeds).

    And for this use case of nested values, it's probably a good choice?

    With your help, suggesting using the sub_process plugin, and a bit of internet searching, I got it working, and created a documentation page. Perhaps you can review it and add it to the menu? Migrate multivalue fields into unlimited Custom Fields field β†’

  • πŸ‡©πŸ‡°Denmark ressa Copenhagen
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Looks pretty good to me. I think you might just want to reference the dependency modules. You're using migrate_plus correct?

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Oh, i guess this is just core stuff. I realize migrate_plus just extends core functionality. So yeah... looks good to me. I'll publish it. Thanks for the contribution and glad it works for you!

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner
  • πŸ‡©πŸ‡°Denmark ressa Copenhagen

    You're welcome! It's so great that you created this module, since it makes migrating nested, multivalue data so much easier than Paragraphs, see for example πŸ“Œ Paragraphs migration example? Active

    You do have a point about Migrate Plus, and I have updated the documentation, since it is required for the url migrate source plugin and JSON-support to work.

    Without Migrate Plus (just Migrate):

    $ drush ev "print_r(array_keys(\Drupal::service('plugin.manager.migrate.source')->getDefinitions()));"
    Array
    (
        [0] => empty
        [1] => embedded_data
    )
    

    With Migrate Plus:

    Array
    (
        [0] => empty
        [1] => embedded_data
        [2] => url
        [3] => table
    )
    

    From Overview of migrate source plugins > Which migrate source plugins can you use? β†’

    Also, Migrate Plus is required for JSON-support:

    The contributed Migrate Plus β†’ module provides capabilities for migrating data to Drupal 8 from XML, JSON or SOAP source.

    From Migrating data from XML, JSON or SOAP source β†’ .

    Feel free to verify if it works for you, these are the basic commands:

    composer require drupal/migrate_plus
    drush install migrate migrate_plus
    drush migrate:status
    drush migrate:import custom_field_hyperlink
    
  • πŸ‡©πŸ‡°Denmark ressa Copenhagen

    I added a link to the new documentation page in the Paragraphs migration issue, #2990527-34: Paragraphs migration example? β†’

  • πŸ‡©πŸ‡°Denmark ressa Copenhagen

    I suggested that Paragraphs module mentions this module as an alternative, since migrating is easy.

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Awesome. Thanks so much and glad you're getting use out of the module. Just an FYI, enable the custom_field_viewfield sub-module and you might get some interesting ideas for sitebuilding ;)

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner
  • πŸ‡©πŸ‡°Denmark ressa Copenhagen

    Sounds very interesting with custom_field_viewfield sub-module, thanks for sharing :)

    I found "Viewfield select (requires custom_field_viewfield sub-module)" on https://www.drupal.org/docs/extending-drupal/contributed-modules/contrib... β†’ ... but maybe it deserves some documentation?

    Actually, if it doesn't exist yet, maybe the sub-modules could get a "Custom Field sub-modules" doc page, shortly describing what each one does? It would be an awesome help for the users.

    • Custom Field - Linkit integration
    • Custom Field - Media
    • Custom Field - Viewfield
    • GraphQL Compose: Custom Field
    • Search API: Custom Field
Production build 0.71.5 2024