Document Default Content

Created on 18 January 2025, 5 months ago

Problem/Motivation

We have a stub for it in the README, and touch on it in https://git.drupalcode.org/project/distributions_recipes/-/blob/1.0.x/do...

But we should provide more in depth documentation, and a roadmap.

We can use https://kanopi.com/blog/default-content-in-drupal/ as an example.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

📌 Task
Status

Active

Version

1.0

Component

Documentation

Created by

🇺🇸United States thejimbirch Cape Cod, Massachusetts

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

Merge Requests

Comments & Activities

  • Issue created by @thejimbirch
  • 🇺🇸United States peaton

    I'm going to work on this at DrupalCon Atlanta 2025.

  • Assigned to peaton
  • 🇺🇸United States peaton
  • Issue was unassigned.
  • 🇺🇸United States thejimbirch Cape Cod, Massachusetts
  • Merge request !197Edit recipe_author_guide.md → (Open) created by nkarhoff
  • I've added more detail about using the Default Content module. Ready for review: https://git.drupalcode.org/project/distributions_recipes/-/merge_request...

  • 🇺🇸United States thejimbirch Cape Cod, Massachusetts

    Thanks for working on this.

    This is a good start, but I would like to have the content from the blog post to be put at the top level page here:

    https://project.pages.drupalcode.org/distributions_recipes/default_conte...

    And then in the author guide where you worked, add a link to the top level default content page.

    # Default Content in Recipes
    
    In Drupal 10.3, the DefaultContent API was added to Drupal core as part of the experimental Recipes APIs. These APIs allow Drupal to create content from files that are part of a recipe.
    
    This content that we programmatically create isn’t intended for deploying or migrating content, we have the Workspaces and other modules for that.
    
    Instead, it can be a great tool in our toolkit for creating demos and test content, while freeing developers and testers from the drudgery of repetitive content creation.
    
    ## The Default Content contrib module
    
    While we added a way in core to consume content config files from recipes, we are still at the start of what core can do, and mid-journey of what the contrib module aims to do.
    
    Until the recent interest from the Recipes Initiative team, the Default Content module has always been used for creating default content configuration files for custom modules and install profiles. You could create content on a local site, export it to your module or a module in an install profile, and when that module was enabled (or a site was started from the install profile), and you installed the default content module as a dependency, you would get your content imported. This all still works exactly as it always has, and now it can also be used with recipes. 
    
    
    
    ## Using the Default Content module
    
    The export process is the same for modules and recipes. Let’s review that now.
    
    ## Getting set up
    
    Install the module as you normally would. Since I am using the module for creating content for recipes, I install it in the dev section of my composer requirements as I do not need it in production.
    
    ```bash
    composer require --dev drupal/default_content
    ```
    
    And enable the module:
    
    ```bash
    drush en -y default_content
    ```
    
    The module doesn’t have a user interface. Instead, it provides Drush commands that can be run to export content.
    
    ## What can we export?
    
    Out of the box, we can export the following entity types:
    
    - **Content type nodes**: `node <node id>`
    - **Taxonomy Terms**: `taxonomy_term <taxonomy term id>`
    - **Files**: `file <file id>`
    - **Media**: `media <media id>`
    - **Menu Links**: `menu_link_content <menu link id>`
    - **Content blocks**: `block_content <block id>`
    - **Shortcuts**: `shortcut <shortcut id>`
    
    At this time, there isn’t a way to export by bundle type (e.g., all nodes of type Article, or all menu links from the main menu), but there is a patch for it.
    
    Let’s take a look at the three commands that the module provides to export content.
    
    ## Default content Drush commands
    
    ### `default-content-export-references`
    
    Exports an entity and all its referenced entities. This is my go-to command as it helps you export referenced media, files, taxonomy terms, and users from the parent node.
    
    **Alias**:  
    `dcer`
    
    **Arguments**:
    
    - `entity_type` – The entity type to export.
    - `entity_id` – The ID of the entity to export.
    
    *One of these arguments is required.*
    
    **Options**:
    
    - `folder` – The module or recipe’s content folder to export to. Entities are automatically grouped by entity type into directories.
    
    **Examples**:
    
    ```bash
    # Exports node 123 and all its dependencies.
    # To a module:
    drush dcer node 123 module_name 
    
    # To a recipe:
    drush dcer node 123 --folder=recipes/recipe_name/content
    
    # Export all nodes and all their dependencies.
    drush dcer node --folder=modules/custom/my_custom_module/content
    ```
    
    ---
    
    ### `default-content-export`
    
    Exports a single entity. Use this if you want to manage your own dependencies.
    
    **Alias**:  
    `dce`
    
    **Arguments**:
    
    - `entity_type` – The entity type to export.  
    - `entity_id` – The ID of the entity to export.  
    
    *Both arguments are required.*
    
    **Options**:
    
    - `file` – Write out the exported content to a file instead of stdout.
    
    **Example**:
    
    ```bash
    # Exports node 123 only. You are responsible to export dependencies.
    drush dce node 123 module_name
    ```
    
    ---
    
    ### `default-content-export-module`
    
    Exports all the content defined in a module info file. This is most helpful for distribution and install profile maintainers who want to maintain and update default content from a canonical source.
    
    **Alias**:  
    `dcem`
    
    **Arguments**:
    
    - `module` – The machine name of the module (required).
    
    **Options**:  
    None
    
    **Example**:
    
    ```bash
    # Exports all the content defined in a module info file.
    drush dcem module_name
    ```
    
    The module's info file would need to have a section like this:
    
    ```yaml
    default_content:
      node:
        - c9a89616-7057-4971-8337-555e425ed782
        - b6d6d9fd-4f28-4918-b100-ffcfb15c9374
      file:
        - 59674274-f1f5-4d6a-be00-fecedfde6534
        - 0fab901d-36ba-4bfd-9b00-d6617ffc2f1f
      media:
        - ee63912a-6276-4081-93af-63ca66285594
        - bcb3c719-e266-45c1-8b90-8f630f86dcc7
      menu_link_content:
        - 9fbb684c-156d-49d6-b24b-755501b434e6
        - 19f38567-4051-4682-bf00-a4f19de48a01
      block_content:
        - af171e09-fcb2-4d93-a94d-77dc61aab213
        - a608987c-1b74-442b-b900-a54f40cda661
    ```
    
    ---
    
    # Creating a Drupal recipe with Default content
    
    So let’s create a recipe that can store default content we can send to a test server so our QA engineer can test. We’ve created a node that has our new feature on our local environment. Rather than having to rebuild that page manually, we will export the content and apply the recipe after it has been deployed.
    
    ## Create the recipe structure
    
    We keep our recipes in the recommended folder above the webroot.
    
    You can manually create a recipe folder, the content folder, and a `recipe.yml` file or use the command line:
    
    ```bash
    mkdir recipes/recipe-name
    mkdir recipes/recipe-name/content
    touch recipes/recipe-name/recipe.yml
    ```
    
    In our `recipe.yml` file, we only need a name, description, and type:
    
    ```yaml
    name: 'Recipe name'
    description: 'Demo content for ticket xyz'
    type: 'Content'
    ```
    
    ## Export your content
    
    Use the Drush commands above, usually `dcer`, to export the content you need. Verify in your `/content` folder that you now have the entities you expect. It should look something like this:
    
    (Directory structure omitted for brevity)
    
    ## Uninstall the module
    
    We can now uninstall the Default Content module from our local environment.
    
    Normally, we just use recipes in our local development environments and deploy the resulting config. But when leveraging the Default Content module in your recipes, you will deploy them to your server.
    
    Once deployed and applied on your site, you’ll probably want to remove your recipe in a subsequent pull request as you don’t need it in production.
    
    Commit and deploy your new recipe along with your code changes as you normally would.
    
    
Production build 0.71.5 2024