Having completed the migration of academic program nodes as mentioned in Drupal 8 Migration: Migrating Basic Data (Part 1) and the migration of taxonomy terms as mentioned in Drupal 8 Migration: Migrating Taxonomy Term References (Part 2), this article would focus on the third requirement. We have images for each academic program. The base name of the images are mentioned in the CSV data-source for academic programs. To make things easy, we have only one image per program. This article assumes:
- You have read the first part of this article series on migrating basic data.
- You are able to write basic entity migrations.
- You understand how to write multiple process plugins in migrations.
Though the problem might sound complex, the solution is as simple as following two steps.
Step 1: Importing images as "file" entities
First we need to create file entities for each file. This is because Drupal treats files as file entities which have their own ID. Then Drupal treats node-file associations as entity references, referring to the file entities with their IDs.
We create the file entities in the migrate_plus.migration.program_image.yml file, but this time, using some other process plugins. We re-use the program.data.csv file to import the files, so the
source definition again uses the CSV plugin. We specify the key parameter in source as the column containing file names, ie, Image file. This way, we would be refer to these files in other migrations using their names, eg,
keys: - Image file
Apart from that, we use some constants to refer to source and destination paths for the images.
constants: file_source_uri: public://import/program file_dest_uri: 'public://program/image'
file_source_uri is used to refer to the path from which files are to be read during the import, and
file_dest_uri is used to refer to the destination path where files should be copied to. The newly created file entities would refer to files stored in this directory. The
public:// URI refers to the files directory inside the site in question. This is where all public files related to the site are stored.
file_source: - plugin: concat delimiter: / source: - constants/file_source_uri - Image file - plugin: urlencode file_dest: - plugin: concat delimiter: / source: - constants/file_dest_uri - Image file - plugin: urlencode
Where do we use these constants? In the process element, we prepare two paths - the file source path (
file_source) and the file destination path (
- file_source is obtained by concatenating the file_source_uri with the Image file column which stores the file's basename. Using
delimiter: /we tell the migrate module to join the two strings with a
/ (slash)in between to ensure we have a valid file name. In short, we do
file_source_uri . '/' . basenameusing the
- file_dest, in a similar way, is
file_dest_uri . '/' . basename. This is where we utilize the constants we defined in the source element.
Now, we use the file_source and file_dest paths generated above with
plugin: file_copy. The file_copy plugin simply copies the files from the
file_source path to the
file_dest path. All the steps we did above were just for being able to refer to complete file source and destination paths during the process of copying files. The file gets copied and the uri property gets populated with the destination file path.
uri: plugin: file_copy source: - '@file_source' - '@file_dest'
We also use the existing file names as names of the newly created files. We do this using a direct assignment of the Image file column to the filename property as follows:
filename: Image file
Finally, since the destination of the migration is
entity:file, the migrate module would use the
uri properties to generate a file entity, thereby generating a unique file ID.
Step 2: Associating files to academic programs
Once the heavy-lifting is done and we have our file entities, we need to put the files to use by associating them to academic programs. To do this, we add processing instructions for
file_image in migration_plus.migration.program_data.yml. Just like we did for taxonomy terms, we tell the migrate module that the Image file column contains a unique file name, which refers to a file entity created during the program_image migration. We assign these file references to the
field_image/target_id property as in Drupal 8, file associations are also treated as entity references.
'field_image/target_id': plugin: migration migration: program_image source: Image file
However, in the data-source for academic program data, we see a column named Image alt as well. Can we migrate these as well? We can! With an additional line of YAML.
'field_image/alt': Image alt
And we are done! If you update the configuration introduced by the c11n_migrate module and run the migration with the command
drush config-import --partial --source=sites/sandbox.com/modules/c11n_migrate/config/install -y && drush migrate-import --group=c11n --update -y, you should see the following output::
$ drush mi --group=c11n --update -y Processed 8 items (0 created, 8 updated, 0 failed, 0 ignored) - done with 'program_tags' Processed 4 items (4 created, 0 updated, 0 failed, 0 ignored) - done with 'program_image' Processed 4 items (0 created, 4 updated, 0 failed, 0 ignored) - done with 'program_data'
To make sure that tag data is imported and available during the academic program migration, we specify the
program_image migration in the
migration_dependencies for the
program_data migration. Now, when you run these migrations, the image files get associated to the academic program nodes.
- Check out the source files for the c11n_migrate module.
- Read about various migration process plugins and how they work.
- Check out the migration_plus module for some more migration examples.
This is part three in a series of three articles on migrating data in Drupal 8. If you missed it, go back and read part one: Migration basics or part two: Migrating taxonomy terms and term references.