Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

External Content Migrate

A small, idiomatic Drupal 10/11 custom module that models and imports external publication content into nodes using the Migrate API. It ships a custom content type, fields and taxonomy as exported configuration, custom source and process plugins, a Drush runner, a normalizing service, and a Twig-themed admin report.

It is intentionally a demo: a self-contained, end-to-end example of how a real-world "import a legacy/external feed into a clean content model" job is done the Drupal way. The sample feed lives in assets/articles.json, so the migration runs against shipped data with no external service.

Requirements

Install

From a Composer-managed Drupal site:

# Add the module (adjust the VCS/path source as needed).
composer require levelbrook/external_content_migrate

# Enable it and its migrate dependencies.
drush en external_content_migrate -y

# Import the configured content model + migration group.
drush config:import --partial --source=modules/contrib/external_content_migrate/config/install -y

Enabling the module installs (via config/install/): the External Article content type, its fields (body, field_author, field_topic, field_source_url, field_reading_minutes), the Article Topics taxonomy vocabulary, default form/view displays, and the external_content migration group.

How to run

The module registers the external_articles migration plus convenience Drush commands:

# Status of the migration (source rows / imported / unprocessed / nodes).
drush ecm:status

# Import new/changed source rows into External Article nodes.
drush ecm:import

# Re-import everything, updating existing nodes in place (idempotent).
drush ecm:import --update

# Remove imported nodes and clear the map table.
drush ecm:rollback

The same migration is also runnable with stock tooling:

drush migrate:status --group=external_content
drush migrate:import external_articles --update
drush migrate:rollback external_articles

Then visit /admin/reports/external-content (permission: View the External Content migration report) for a status table and Twig-rendered previews of the most recent imports.

To point the migration at your own data, edit source.path in migrations/external_articles.yml (absolute path, stream wrapper, or path relative to the module) to a JSON file shaped like assets/articles.json.

What it demonstrates

Required skill Where it lives
Custom module external_content_migrate.info.yml, .module, composer.json
Migrate API — source plugin src/Plugin/migrate/source/ExternalArticleJson.php (file-backed, keyed on external_id for idempotent re-import)
Migrate API — process plugin src/Plugin/migrate/process/NormalizeText.php (DI'd plugin: clean / summary / word_count / reading_minutes / topic)
Migration config migrations/external_articles.yml, config/install/migrate_plus.migration_group.external_content.yml
Configuration management config/install/*node.type, field.storage.*, field.field.*, taxonomy.vocabulary, form/view displays
Entities / fields / taxonomy External Article node + 5 fields + Article Topics vocabulary; topics resolved with entity_generate
Twig theming templates/external-article-summary.html.twig + hook_theme() in the .module
Services / DI external_content_migrate.services.ymlContentNormalizer (+ interface) and MigrationReportService
Drush src/Commands/ExternalContentMigrateCommands.php + drush.services.yml
Controller / routing / permissions / menu src/Controller/MigrationReportController.php, *.routing.yml, *.permissions.yml, *.links.menu.yml
Tests tests/src/Unit/* (PHPUnit, @group external_content_migrate)

Tests

# From the Drupal site root:
./vendor/bin/phpunit -c web/modules/contrib/external_content_migrate \
  web/modules/contrib/external_content_migrate/tests/src/Unit

The unit tests cover the normalizer and the process plugin (pure logic, no database required).

License

MIT — see LICENSE. Copyright (c) 2026 Levelbrook LLC.

About

Drupal 10/11 custom module: Migrate API source + process plugins, content type/fields/taxonomy via configuration management, Twig theming, and Drush commands.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages