Creating a custom entity type

by Gisle Hannemyr

This chapter describes how to create an example custom entity type named "projectdocumentaton", export it as a configuration object, and add that configuration to a custom module.

Table of contents

Drupal project discussed in this chapter: Config Split.

Introduction

Sources:

Drupal entities are bundles of related data. All the predefined data objects in Drupal (e.g. nodes, taxonomy terms, comments and users) are entities. It is possible for site designers to create new custom entities and include those in a site design. You may create a custom entity with fields using the GUI, or you may do by YAML files. Putting those YAML files into a custom extension module let the site builder add that entity type to the site by enabling that extension.

In Drupal 7 the default configuration for entities, field configuration, views, etc. either required custom PHP code to install and keep updated. Generating this could be semi-automated with the contributed Features extension, but it was an awkward process at the best of times.

In Drupal 8 and later, a Configuration Management system is part of core. It stores the site configuration in plain text YAML-files that can easily be exported and imported. There is no need for custom PHP to create an extension's default configuration.

See alsoThe change is well described in Mike Potter: Stop Using Features: A Guide To Drupal 8 Configuration Management. Mike Potter has also recorded a 51 minute video of a presentation he held at the 2017 "Drupal 4 Gov" conference: Advanced Configuration Management in Drupal 8.

In this case study, we shall create a custom content type for the custom module Project Documentation. See create a custom module to see how to create it.

Create a custom module

To create a module, create a directory to hold it in modules/custom/ below the webroot. Then create an .info.yml file that contains the metadata for the module.

In this tutorial, the module shall be called "projdoc" (machine name). Start out by creating the directory and in it: projdoc.info.yml. Then put the following content in this file:

name: 'Project Documentation'
description: 'Example of how to create a custom entity.'
package: 'Custom'
core_version_requirement: ^9.0
type: module

See alsoWhen starting out using YAML, you may want to read the YAML Specification and A YAML Primer.

When the folder and file has been created, you shall be able to go to Manage » Extend, locate the custom module and enable it. Of course, it will not do anything yet.

Create a custom entity type

Create a directory to hold the configuration:

$ mkdir -p config/install

Then add a YAML file to this directory to add the custom entity type:

# node.type.projdoc.yml
type: projdoc
name: Project documentation
description: Provides a content type to record metadata about projects.
help: ''
new_revision: false
display_submitted: true
preview_mode: 1
status: true
langcode: en
dependencies: { }

After enabling this, you have a bare bones content type consisting of a Title field It will appear when you navigate to Manage » Content » + Add content.

noteIf you installed the module before adding this content type, you'll need to uninstall and install it again for the configuration to take effect. The dependencies and enforced keys ensure that the configuration is removed when the module is uninstalled. If you've Devel installed you can use "Reinstall Modules".

Adding a body field

[TBA]

# field.field.node.projdoc.body.yml
langcode: en
status: true
dependencies:
    config:
        - field.storage.node.body
        - node.type.projdoc
    module:
        - text
id: node.projdoc.body
field_name: body
entity_type: node
bundle: projdoc
label: Body
description: 'A short description of the extension.'
required: false
translatable: true
default_value: {  }
default_value_callback: ''
settings:
    display_summary: true
field_type: text_with_summary

A real example of the node content type "Artcle" is here: node.type.article.yml.

Adding views and form display

Three additional configuration fields shall be needed for the body to show:

They're not reproduced here. See project repo to see their content.


The configuration management system takes care of creating and managing content types. You can ship a content type with your module by creating a properly named and structured configuration file.

In this case study, we will create a content type projdoc with the following fields:

Exporting a content type

Drupal let you create and populate a content type with fields using the GUI. How to do this is described in the chapter Using fields

If you've ceated a custom content type and want to export it to be installed when a custom module is installed, use drush to export the configuration of the site:

$ drush cex --destination=install

This will copy the entire configuration into the directory web/install/ below the siteroot. Dig into that directory a move the files for the content type you're interested in into the extension's config/install.

Edit and remove the "uuid" keys from all the files. You can do it with this command:

$ sed -i '/uuid/d' *
Source: https://stackoverflow.com/questions/5410757/how-to-delete-from-a-text-file-all-lines-that-contain-a-specific-string

Edit the node.type.…- and insert dependencies and enforced keys to ensure that the configuration also is removed when the module is uninstalled. Example:

Sources DSE: How do I export and import content types and SO: How to import / export content type in drupal 8?

Include default configuration in your Drupal module and Creating a custom content type in Drupal 8

Troubleshooting

If you get:

Unable to install … already exist in active configuration.

Use Easy Install to remove the unwanted configurations.

First, clear caches. Then navigate to Manage » Extend » Purge configurations. Locate the module you want to purge. Place a checkmark next to the name, and press "Purge configurations". Checkmark " Delete all the listed configurations", and press "Purge configurations" again.

Final word

[mumble]


Last update: 2021-03-23 [gh].