Add a command-line utility to export content in YAML format

Created on 26 June 2025, about 10 hours ago

Problem/Motivation

Recipes -- and especially site templates -- can include content. Core can import the format generated by the venerable Default Content contrib module.

However, exporting content is a gap. You need the Default Content module to do that. Default Content has some problems, namely that it is not extensible for export -- new types of fields and data structures can't be handled by it without patching the module.

Besides, it's not really feasible to require recipe authors, and especially site template creators, to use Default Content to put content into their recipes. It needs to work, and it needs to be able to handle all core field types, and it needs to be able to handle exotic contrib field types (Entity Reference Revisions, Smart Date, Experience Builder's stuff, and so on).

Proposed resolution

I propose we add a new content:export command to the core/scripts/drupal script.

Initially, to keep things simple, it should support exporting entities one at time, with no handling of dependencies, and only in YAML format. For example:

$ php core/scripts/drupal content:export node 42
... YAML DUMP HERE ...

To generate the export, it should use the Serialization module's normalization API to normalize the entity and all of its fields. This means the command will have to exit with an error if Serialization is not installed -- but that's probably okay for the time being. This is a developer-facing command anyway, and we can lift that restriction when and if Serialization is turned into a core subsystem (which is being discussed in #2296029: Move Serialization module back into a core/lib component β†’ ).

The exported content should be, pretty much, exactly what you'd get out of the Default Content module. We don't need to handle normalization for all core field types right away; that can happen in follow-ups, as long as the normalization is pluggable.

In a follow-up issue, we should add support for exporting an entity and its dependencies into a folder structure.

User interface changes

None.

Introduced terminology

TBD.

API changes

TBD; the default content subsystem might get a few changes.

Data model changes

None.

Release notes snippet

TBD

✨ Feature request
Status

Active

Version

11.0 πŸ”₯

Component

recipe system

Created by

πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @phenaproxima
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    +1 for this, it will likely require a dependency on the serialization module but I think that is fine

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    Just to give a little context, @larowlan linked me to https://www.previousnext.com.au/blog/we-could-add-default-content-drupal..., which is from almost a decade ago. It outlines four tricky problems that prevent the addition of default content capabilities to core. I want to quickly shoot these down.

    Adding default content to standard profile would mean that none of the profile's configuration would have been imported yet.

    Core's default content import is done by recipes, and works well. The concern about shipping content with modules is moot. Recipes' job is to put all necessary configuration in place before any content is created, and the recipe system's strong, straightfoward configuration handling means that default content can come in easily. This concern is definitely no longer applicable.

    The second issue here is that the default content module relies on the Rest, HAL and serialization modules in core.

    This was true for v1 of the Default Content module. We would still need to have Serialization enabled for export, that's true...but there are no special modules required for import, which is the end user-facing case.

    There are shortcomings in core's normalizers. The main ones are around fields that resemble entity references but really aren't and fields with calculated values. And then there's normalizing files and images.

    This is probably legitimate, although the picture probably significantly better now than it was at the time the blog post was written, thanks to the advent of JSON:API and the core improvements that it brought us. But yes, normalization is the meat and potatoes of doing default content export correctly.

    Just because we could add default content to the standard profile - does that mean we should?

    We already put default content in recipes, which puts profile support on the back burner (where it belongs). This is not a problem anymore.

    So there you go. If you ask me, the time to do this is now!

  • πŸ‡ΊπŸ‡ΈUnited States thejimbirch Cape Cod, Massachusetts

    Moving to the Default content system.

  • Merge request !12512Resolve #3532694 "Add a command line" β†’ (Open) created by phenaproxima
  • πŸ‡ΊπŸ‡ΈUnited States nicxvan

    Slightly different use case, but tome can export content to json for keeping it in git.

  • Pipeline finished with Failed
    about 7 hours ago
    Total: 661s
    #532704
  • Pipeline finished with Failed
    about 7 hours ago
    Total: 181s
    #532719
  • Pipeline finished with Failed
    about 7 hours ago
    Total: 179s
    #532721
  • Pipeline finished with Failed
    about 6 hours ago
    Total: 179s
    #532726
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • Pipeline finished with Failed
    about 5 hours ago
    Total: 185s
    #532741
  • Pipeline finished with Success
    about 5 hours ago
    Total: 1744s
    #532742
Production build 0.71.5 2024