Skip to content

Instantly share code, notes, and snippets.

@WengerK
Last active March 10, 2023 17:01
Show Gist options
  • Save WengerK/f30f1efc9ca6da766b3cce5854d9a6ea to your computer and use it in GitHub Desktop.
Save WengerK/f30f1efc9ca6da766b3cce5854d9a6ea to your computer and use it in GitHub Desktop.
How to Migrate content into Drupal Paragraphs

Article Ressources - How to Migrate content into Drupal Paragraphs

This is the Gist repository for my article Behat on Drupal - clearing Data Between Scenarios.

Be aware that this article has been wrote for the Blog of Antistatique — Web Agency in Lausanne, Switzerland. A place where I work as Full Stack Web Developer.

Feel free to read it the full article on Medium or check it out on Antistatique.

id: articles
label: Articles
description: Migration of embed Articles to Drupal
source_type: 'custom embedded data'
source:
plugin: embedded_data
data_rows:
- id: 'A10'
title: 'Factory Lollipop, speeding up Kernel Tests on Drupal'
- id: 'B20'
title: 'Bamboo Twig, Beyond Twig in Drupal 8'
- id: 'C30'
title: 'Template Whisperer — Content-first templating in Drupal 8'
- id: 'Z99'
title: 'Trends on video games industry are toxic'
ids:
id:
type: string
dependencies:
enforced:
module:
- my_module_migrate
destination:
plugin: entity:node
default_bundle: article
process:
uid:
plugin: default_value
default_value: 1
status:
plugin: default_value
default_value: true
title: title
# Paragraphs.
paragraph_text:
-
plugin: migration_lookup
migration: articles_paragraphs_text
source: id
-
plugin: null_as_array
paragraph_gallery:
-
plugin: migration_lookup
migration: articles_paragraphs_gallery
source: id
-
plugin: null_as_array
field_content:
plugin: sub_process
source:
- '@paragraph_text'
- '@paragraph_gallery'
process:
target_id:
-
plugin: skip_on_empty
method: process
message: 'Cannot import empty paragraph'
source: '0'
target_revision_id:
-
plugin: skip_on_empty
method: process
message: 'Cannot import empty paragraph'
source: '1'
migration_dependencies:
required:
- articles_paragraphs_text
- articles_paragraphs_gallery
id: articles_images_files
label: Articles Images Files
description: Migrate images of articles from an URL to Drupal Files
source_type: 'custom embedded data'
source:
plugin: embedded_data
data_rows:
- id: 'KR2mdHJ5qMg'
article_id: 'A10'
image_url: 'https://loremflickr.com/cache/resized/65535_51821270379_dc9b1cd908_320_240_nofilter.jpg'
- id: 'p0j-mE6mGo4'
article_id: 'A10'
image_url: 'https://loremflickr.com/cache/resized/65535_51785024973_95943bca54_320_240_g.jpg'
- id: 'COb6HbexUxw'
article_id: 'B20'
image_url: 'https://loremflickr.com/cache/resized/65535_50735941456_c1d432b10c_320_240_nofilter.jpg'
- id: 'yCJo8zzqmtU'
article_id: 'Z99'
image_url: 'https://loremflickr.com/cache/resized/4116_4764722526_f62e8481c6_n_320_240_nofilter.jpg'
ids:
id:
type: string
article_id:
type: string
constants:
drupal_file_dest: 'public://articles/'
destination:
plugin: 'entity:file'
dependencies:
enforced:
module:
- my_module_migrate
process:
destination_filename:
-
plugin: callback
callable: basename
source: image_url
-
plugin: skip_on_empty
method: row
message: 'Cannot import empty filename.'
destination_full_path:
-
plugin: concat
source:
- 'constants/drupal_file_dest'
- '@destination_filename'
-
plugin: urlencode
uri:
-
plugin: file_copy
source:
- 'image_url'
- '@destination_full_path'
uid:
plugin: default_value
default_value: 1
migration_dependencies: {}
id: articles_images_media
label: Articles Images Media
description: Migrate previously downloaded articles images files to Drupal Media
source_type: 'custom embedded data'
source:
plugin: embedded_data
data_rows:
- id: 'KR2mdHJ5qMg'
article_id: 'A10'
image_url: 'https://loremflickr.com/cache/resized/65535_51821270379_dc9b1cd908_320_240_nofilter.jpg'
- id: 'p0j-mE6mGo4'
article_id: 'A10'
image_url: 'https://loremflickr.com/cache/resized/65535_51785024973_95943bca54_320_240_g.jpg'
- id: 'COb6HbexUxw'
article_id: 'B20'
image_url: 'https://loremflickr.com/cache/resized/65535_50735941456_c1d432b10c_320_240_nofilter.jpg'
- id: 'yCJo8zzqmtU'
article_id: 'Z99'
image_url: 'https://loremflickr.com/cache/resized/4116_4764722526_f62e8481c6_n_320_240_nofilter.jpg'
ids:
id:
type: string
article_id:
type: string
destination:
plugin: 'entity:media'
default_bundle: image
dependencies:
enforced:
module:
- my_module_migrate
process:
pseudo_destination_filename:
-
plugin: callback
callable: basename
source: image_url
-
plugin: skip_on_empty
method: row
message: 'Cannot import empty filename.'
name: '@pseudo_destination_filename'
field_media_image/target_id:
plugin: migration_lookup
migration: articles_images_files
source:
- id
- article_id
thumbnail/target_id:
plugin: migration_lookup
migration: articles_images_files
source:
- id
- article_id
uid:
plugin: default_value
default_value: 1
migration_dependencies:
required:
- articles_images_files
id: articles_paragraphs_text
label: Articles
description: Migration of Articles text to Drupal Paragraph Text
source_type: 'custom embedded data'
source:
plugin: embedded_data
data_rows:
- id: 'A10'
title: 'Factory Lollipop, speeding up Kernel Tests on Drupal'
body: 'Like many open-source projects, Drupal comes with automated tests that help prevent breaking changes while promoting code quality. But there is still some massive lack inside Drupal automated testing capabilities. but there is still some massive lack inside Drupal automated testing capabilities.'
- id: 'B20'
title: 'Bamboo Twig, Beyond Twig in Drupal 8'
body: 'The idea behind Bamboo Twig comes from a need to enhance layout management through code in Drupal 8. These best practices and codes are often needed and allow easy template fragmentation while.'
- id: 'C30'
title: 'Template Whisperer — Content-first templating in Drupal 8'
body: 'We recently released update 2.0 of Template Whisperer, so it is more than time to talk about it. This module radically changed our development process in our Drupal 8 projects.'
- id: 'Z99'
title: 'Trends on video games industry are toxic'
body: 'Here an opinion and thoughts about our modern video industry'
ids:
id:
type: string
destination:
plugin: entity_reference_revisions:paragraph
default_bundle: rich_text
process:
field_body/value: body
field_body/format:
plugin: default_value
default_value: "basic_html"
migration_dependencies: {}
name: My Custom Module Migration
type: module
description: Module used to handle migrations
core_version_requirement: ^9.1
package: Migration
dependencies:
- drupal:migrate_plus
- drupal:migrate_tools
- drupal:migrate
- drupal:node
- drupal:media
<?php
namespace Drupal\my_module_migrate\Plugin\migrate\process;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
/**
* Transforms a null value as an empty array usable on sub_process.
*
* When using migration_lookup, the return values may be NULL, meaning the
* lookup as not found any match.
* Then, SubProcess fails if input is array([0] => NULL).
* This process intend to transform null value into an empty array to prevent
* sub_process fail when mixing multiple nullable sources.
*
*
* Example:
*
* @code
* process:
* field_string:
* plugin: null_as_array
* source: my_nullable_value
* @endcode
*
* @code
* standard_migration:
* -
* plugin: migration_lookup
* migration: migration_that_is_required
*
* nullable_migration:
* -
* plugin: migration_lookup
* migration: migration_that_may_found_nothing
* -
* plugin: null_as_array
*
* field_content:
* plugin: sub_process
* source:
* - '@nullable_migration'
* - '@standard_migration'
* process:
* target_id:
* plugin: skip_on_empty
* method: process
* message: 'Cannot import empty paragraph'
* source: '0'
* @endcode
*
* @MigrateProcessPlugin(
* id="null_as_array"
* )
*/
class NullAsArray extends ProcessPluginBase {
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
if ($value === NULL) {
return [];
}
return $value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment