JuniperStudio

Drupal 8 image migration with images from xml or csv file

Full module on github: Drupal 8 XML image migration

Import content into Drupal 8 with associated image files using a csv or xml file. Importing will require 2 configuration files. One for the images and one for the nodes. Image files are references and need to be migrated and referenced using the id that uniquely identifies the imported item. This id is stored in the migrate system.

First configure the source of your images data, in this case I’m useing the XML parser.
Define your id: I’m using the name of the image which I have labled with the machine name name_image.
Next define field names and then source location and destination.

Import Images

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
    # Migration configuration for copying and tagging a file for import

    id: import_image #migrate_machine_name
    label: Childrens Book Reading List.
    migration_group: book_data #migrate_machine_name
    migration_tags:
      - file
      - image
    source:
      # We use the XML data parser plugin.
      plugin: url
      data_fetcher_plugin: http
      data_parser_plugin: xml
      # Normally, this is one or more fully-qualified URLs or file paths. Because
      # we can't hardcode your local URL, we provide a relative path here which
      # hook_install() will rewrite to a full URL for the current site.
      urls: modules/drupal_8_xml_image_migration/book.xml
      # Visit the URL above (relative to your site root) and look at it. You can see
      # that <response> is the outer element, and each item we want to import is a
      # <position> element. The item_xpath value is the xpath to use to query the
      # desired elements.
      item_selector: /root/row
      # Under 'fields', we list the data items to be imported. The first level keys
      # are the source field names we want to populate (the names to be used as
      # sources in the process configuration below). For each field we're importing,
      # we provide a label (optional - this is for display in migration tools) and
      # an xpath for retrieving that value. It's important to note that this xpath
      # is relative to the elements retrieved by item_xpath.
      fields:
        -
          name: name_image
          label: 'Position name'
          selector: image
        -
          name: my_unique_id
          label: 'Unique position identifier'
          selector: num

      # Under 'ids', we identify source fields populated above which will uniquely
      # identify each imported item. Use the id as the source: value in your field.
      # The 'type' makes sure the migration map table
      # uses the proper schema type for stored the IDs.
      ids:
        name_image: # <----Important: unique id of item. In this case the name of the file.
          type: string
      constants:
        file_source_uri: 'public://book_covers_source'
        file_dest_uri: 'public://book_covers/image'
    destination:
      # We will be creating entities of type "file" this time.
      plugin: 'entity:file'
      # mikeryan says...
      # By default, the system-of-record for a migration is the source data -
      # that is, when content is imported and the destination entity already exists,
      # it is entirely replaced by the source data. For the import to partially overwrite
      # the destination node, you can set "overwrite_properties" on the destination plugin:
      # overwrite_properties:
          #  - title
          #  - body
          #  - field_to_be_overwritten
          ## - field_that_wont_be_overwritten
    process:
      file_source:
        -
          plugin: concat
          delimiter: /
          source:
            - constants/file_source_uri
            - name_image
        # Make sure we don't have any url-unfriendly characters.
        -
          plugin: urlencode
      file_dest:
        -
          plugin: concat
          delimiter: /
          source:
            - constants/file_dest_uri
            - name_image
        # Make sure we don't have any url-unfriendly characters.
        -
          plugin: urlencode
      # Optionally you can set the fid: manually using my_unique_id
      # NOTE: Existing fids will be overwritten by migration.
      # fid: my_unique_id #
      uid:
        plugin: default_value
        default_value: '1'
      filemime:
        plugin: default_value
        default_value: 'image/jpeg'
      status:
        plugin: default_value
        default_value: '1'
      filename: name_image
      uri:
        plugin: file_copy
        source:
          - '@file_source'
          - '@file_dest'
    migration_dependencies:
      optional:
        - childbook_index

Import Nodes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
    # Migration configuration for drupal_8_xml_image_migration
    id: childbook_index #migrate_machine_name
    label: Child Books Import
    migration_group: book_data #migrate_machine_name
    source:
      # We use the XML data parser plugin.
      plugin: url
      data_fetcher_plugin: http
      data_parser_plugin: xml
      # Normally, this is one or more fully-qualified URLs or file paths. Because
      # we can't hardcode your local URL, we provide a relative path here which
      # hook_install() will rewrite to a full URL for the current site.
      urls: modules/drupal_8_xml_image_migration/book.xml
      # Visit the URL above (relative to your site root) and look at it. You can see
      # that <response> is the outer element, and each item we want to import is a
      # <position> element. The item_xpath value is the xpath to use to query the
      # desired elements.
      item_selector: /root/row
      # Under 'fields', we list the data items to be imported. The first level keys
      # are the source field names we want to populate (the names to be used as
      # sources in the process configuration below). For each field we're importing,
      # we provide a label (optional - this is for display in migration tools) and
      # an xpath for retrieving that value. It's important to note that this xpath
      # is relative to the elements retrieved by item_xpath.
      fields:
        -
          name: my_unique_id
          label: 'Unique position identifier'
          selector: num
        -
          name: name_image
          label: 'Position name'
          selector: image
        -
          name: name_body
          label: 'Position name'
          selector: body
        -
          name: name_title
          label: 'Position name'
          selector: caption_title

      # Under 'ids', we identify source fields populated above which will uniquely
      # identify each imported item. The 'type' makes sure the migration map table
      # uses the proper schema type for stored the IDs.
      ids:
        my_unique_id:
          type: string
    destination:
      plugin: entity:node
      default_bundle: children_book # Destination bundle machine name.
    process:
      type:
        plugin: default_value
        default_value: children_book # my_destination_node_machine_name
      title: name_title # destination_machine_name: source_value_referenced_above
      sticky:
        plugin: default_value
        default_value: 0
      body: name_body
      field_title: name_title

    # field_image:
    #    plugin: migration
    #    migration: import_image #migrate_machine_name
    #    # no_stub: true
    #    # The name of the file is the id used to
    #    # uniquely identify each imported item.
    #    source: name_image # <----Important: unique id of item. In this case the name of the file.
    #    # Alternatively set and use the fid.
    #    # source: my_unique_id

       #################
       # if you have alt and title fields you need to enclose the field name in
       # quotes and add target_id.
       #################

      'field_image/target_id':
         plugin: migration
         migration: import_image #migrate_machine_name
         source: name_image # <----Important: unique id of item. In this case the name of the file.
      'field_image/alt':
         plugin: default_value
         default_value: 'What a great selection timmy'
      'field_image/title':
        plugin: default_value
        default_value: 'hooray for reading'