Series Overview & ToC | Previous Article | Next Article


Article Content:

Today, we're building on our previous work with field widget settings. We will cover migrating view modes, a prerequisite for migrating field groups and field formatter settings. We’ll then walk through migrating field groups. Field formatter settings will be addressed in our next article.

Before we begin

Familiarity with site building concepts is assumed. Namely, view modes and form modes. They are collectively known as display modes in Drupal 10 and you can learn more about them in this article on Drupal.org.

For today's discussions, it is worth noting that:

  • View modes determine how content is viewed. Form modes determine how content is edited. In both cases, visibility can be controlled on a per field basis.
  • View modes use field formatters to determine how individual fields are presented. Form modes use field widgets to determine how to collect data for each field.
  • Each entity type can have a different set of display modes. Additionally, each bundle for each entity type can have a particular display mode enabled or disabled.
  • The concept of view modes existed in Drupal 7, but form modes were introduced in Drupal 8. That is why we have a view modes migration but not a form modes migration.
  • Field groups in Drupal 7 provided a way to group fields for viewing and editing purposes. That is why the field group migration can affect view mode and form mode configuration in Drupal 10.

Migrating view modes

Our example Drupal 7 project does not use any custom view mode other than what comes available out of the box in a standard installation or provided by enabled modules. Three view modes in total: default and teaser for the node entity and default for the field_collection_item entity. Equivalent view modes are available in Drupal 10.

We are still going to run the migration for two reasons:

  1. To learn how to do it for projects with custom view modes.
  2. Other migrations specify a dependency on this one. They rely on a migration_lookup against upgrade_d7_view_modes which would yield no results if this migration is not executed.

Let’s get started. Copy the upgrade_d7_view_modes migration from the reference folder into our custom module and rebuild caches for it to be detected.

cd drupal10
cp ref_migrations/migrate_plus.migration.upgrade_d7_view_modes.yml web/modules/custom/tag1_migration/tag1_migration_config/migrations/upgrade_d7_view_modes.yml
ddev drush cache:rebuild

Note that while copying the file, we also changed its name and placed it in a migrations folder inside our custom module. After copying the file, make the following changes:

  • Remove the following keys: uuid, langcode, status, dependencies, cck_plugin_method, field_plugin_method, and migration_group.
  • Add two migration tags: entity_view_mode and tag1_configuration.
  • Add key: migrate under the source section.
  • Update the required migration_dependencies to include the migrations that create entities.

After the modifications, the upgrade_d7_view_modes.yml file should look like this:

id: upgrade_d7_view_modes
class: Drupal\migrate\Plugin\Migration
migration_tags:
 - 'Drupal 7'
 - Configuration
 - entity_view_mode
 - tag1_configuration
label: 'View modes'
source:
 key: migrate
 plugin: d7_view_mode
process:
 mode:
   -
     plugin: static_map
     source: view_mode
     bypass: true
     map:
       default: full
 label:
   -
     plugin: static_map
     source: view_mode
     bypass: true
     map:
       search_index: 'Search index'
       search_result: 'Search result'
       rss: RSS
       print: Print
       teaser: Teaser
       full: Full
       default: Full
 targetEntityType:
   -
     plugin: get
     source: entity_type
   -
     plugin: static_map
     map:
       field_collection_item: paragraph
       paragraphs_item: paragraph
     bypass: true
destination:
 plugin: 'entity:entity_view_mode'
migration_dependencies:
 required:
   - upgrade_d7_field_collection_type
   - upgrade_d7_node_type
   - upgrade_d7_taxonomy_vocabulary
 optional: {  }

Now, rebuild caches for our changes to be detected and execute the migration. Run migrate:status to make sure we can connect to Drupal 7. Then, run migrate:import to perform the import operations.

ddev drush cache:rebuild
ddev drush migrate:status upgrade_d7_view_modes
ddev drush migrate:import upgrade_d7_view_modes

View modes are configuration entities in Drupal 10. After running this migration, review the site's configuration. Even in cases like ours (without custom view modes), you might get configuration changes.

One such change is related to the labels of the view modes. This migration imports the default view mode from Drupal 7 as the full view mode in Drupal 10. In all cases, the label is set to Full no matter the entity type associated with the view mode. By default the node entity in Drupal 10 uses Full content as the label for the full view mode. After running this migration, its label will be changed to Full. You are free to keep or discard the label change as long as the migrated view modes remain in the system. If you are certain that a migrated view mode will not be used in the new site, you can update the migration to prevent it from being migrated or manually delete it after executing the migration.

In Drupal 7, field formatters settings, field groups, and views are some examples of places where view modes can be used.

Migrating field groups

Our source site includes only one field group and it contains two fields. One of those is a YouTube field that we skipped because it will be replaced by a media reference field in a future article. It is a rather contrived example, but we can use it to learn how to migrate field groups.

Field groups migrations are provided by the field_group_migrate submodule inside the main field_group project. The submodule needs to be enabled before generating the migrations using the Migrate Upgrade module. When that is the case, the field_group_migrate submodule uses a deriver to create one migration for each entity type and bundle combination that uses field groups in the source site.

For our example, copy the upgrade_d7_field_group_node_session migration from the reference folder into our custom module and rebuild caches for it to be detected.

cd drupal10
cp ref_migrations/migrate_plus.migration.upgrade_d7_field_group_node_session.yml web/modules/custom/tag1_migration/tag1_migration_config/migrations/upgrade_d7_field_group_node_session.yml
ddev drush cache:rebuild

Note that while copying the file, we also changed its name and placed it in a migrations folder inside our custom module. After copying the file, make the following changes:

  • Remove the following keys: uuid, langcode, status, dependencies, cck_plugin_method, field_plugin_method, and migration_group.
  • Add two migration tags: d7_field_group and tag1_configuration.
  • Add key: migrate under the source section.
  • Update the required migration_dependencies to include the migration responsible for migrating the entity type for the current field group migration. In this case, that would be upgrade_d7_node_type.

After the modifications, the upgrade_d7_field_group_node_session.yml file should look like this:

id: upgrade_d7_field_group_node_session
class: Drupal\migrate\Plugin\Migration
migration_tags:
 - 'Drupal 7'
 - Configuration
 - d7_field_group
 - tag1_configuration
label: 'Field groups of node (bundle: session)'
source:
 key: migrate
 plugin: d7_field_group
 entity_type: node
 bundle: session
process:
 entity_type:
   -
     plugin: get
     source: entity_type
   -
     plugin: static_map
     map:
       field_collection_item: paragraph
       paragraphs_item: paragraph
     bypass: true
 bundle:
   -
     plugin: get
     source: bundle
 mode:
   -
     plugin: static_map
     source: mode
     bypass: true
     map:
       form: default
 type:
   -
     plugin: static_map
     source: mode
     default_value: entity_view_display
     map:
       form: entity_form_display
 group_name:
   -
     plugin: get
     source: group_name
 settings:
   -
     plugin: get
     source: settings
destination:
 plugin: d7_field_group
migration_dependencies:
 required:
   - upgrade_d7_node_type
   - upgrade_d7_view_modes
 optional: {  }

Now, rebuild caches for our changes to be detected and execute the migration. Run migrate:status to make sure we can connect to Drupal 7. Then, run migrate:import to perform the import operations.

ddev drush cache:rebuild
ddev drush migrate:status upgrade_d7_field_group_node_session
ddev drush migrate:import upgrade_d7_field_group_node_session

The imported migration group can be seen in the Manage form display tab for the Session content type: https://migration-drupal10.ddev.site/admin/structure/types/manage/session/form-display

As usual, make sure to review and confirm the result of the migration is what you expect. At first sight, things look good. The Manage form display tab shows the Resources group of type Fieldset containing the Slides field. But if you try to add a node of type Session, you will notice that the group does not behave like it does in the source site. In Drupal 7, the field group is collapsible. In Drupal 10, it is not.

Manage Form Display page

In many cases even when an automated migration exists, implementation details could have changed between Drupal 7 and Drupal 10. As documented in this issue, the option to make fieldsets collapsible was removed in Drupal 10. If you want to get similar functionality, you need to change the group type to Details. Other changes include merging the Vertical tab and Horizontal tab group types from Drupal 7 into a single Tab group in Drupal 10. Look at the project page of the Field Group module for a list of available groups and notes about their usage.

Because field group migrations are generated for each entity type and bundle combination, you have the flexibility to choose which ones to execute and which to discard. These migrations are particularly helpful when the groups contain a large number of fields. As demonstrated in our example, you might have to tweak the settings for the group itself but getting the fields inside the groups saves time.

Consider whether to recreate some group configurations manually or drop them entirely. Remember to always strike a balance between what to automate and what to redo manually.

In the next article, we will explore migrating field formatter settings, building on what we’ve learned so far.


Image by Matthias Böckel from Pixabay