Overview

This is a memo on how to add content types and fields using Drupal custom modules.

The following two articles were helpful.

https://www.drupal.org/docs/drupal-apis/entity-api/creating-a-custom-content-type-in-drupal-8

https://www.digitalnadeem.com/drupal/how-to-create-content-type-fields-and-view-while-installing-custom-module-in-drupal-9-using-configuration-manager/

Car Brand Example

Following the first article introduced above, I was able to add a content type “Car Brand” with a “body” field.

Note that the above article skips the part about creating the custom module. First, create the following folder and file.

name: foobar
description: Sample module
package: Custom
type: module
version: 1.0
core_version_requirement: ^8 || ^9

Adding Custom Fields

Using the above as reference, I was able to add a content type, but to add custom fields, I needed to add both a Field and a Field storage.

When I was unsure about how to write the YAML for Field storage, the second link introduced at the beginning was helpful.

https://www.digitalnadeem.com/drupal/how-to-create-content-type-fields-and-view-while-installing-custom-module-in-drupal-9-using-configuration-manager/

By using the “Configuration Manager” module, I was able to check the definitions of already registered Fields and Field storages.

Based on the above, let’s create a content type called “IIIF Media” and add a field for storing a string called iiif_image_url, and fields for storing numeric values called iiif_image_width and iiif_image_height. The following files are needed.

Content Type

modules/custom/foobar/config/install/node.type.iiif_media.yml

# node.type.iiif_media.yml
langcode: en
status: true
dependencies:
  enforced:
    module:
      - foobar # This is the name of the module we're using for this example
name: 'IIIF Media'
type: iiif_media
description: 'Content type for IIIF Media'
help: ''
new_revision: false
preview_mode: 1
display_submitted: true

Field: iiif_image_url (string)

Field storage

modules/custom/foobar/config/install/field.storage.node.field_iiif_image_url.yml

langcode: en
status: true
dependencies:
  enforced:
    module:
      - foobar
id: node.field_iiif_image_url
field_name: field_iiif_image_url
entity_type: node
type: string
settings:
  max_length: 255
  case_sensitive: false
  is_ascii: false
module: core
locked: false
cardinality: 1
translatable: true
indexes: {  }
persist_with_no_fields: false
custom_storage: false

Note that by setting dependencies > enforced > module > {module name}, the storage is also deleted when the module is uninstalled. Without this setting, only the storage information remained after uninstalling.

The following article was helpful.

https://www.drupal.org/project/drupal/issues/3231028

!

On the other hand, having related content types and fields deleted when uninstalling a module can be problematic in some cases, so care must be taken with these settings.

Field

modules/custom/foobar/config/install/field.field.node.iiif_media.field_iiif_image_url.yml

# field.field.node.iiif_media.field_iiif_image_url.yml
langcode: en
status: true
dependencies:
    config:
        - field.storage.node.field_iiif_image_url
        - node.type.iiif_media
id: node.iiif_media.field_iiif_image_url
field_name: field_iiif_image_url
entity_type: node
bundle: iiif_media
label: IIIF Image URL
description: ''
required: false
translatable: false
default_value: {  }
default_value_callback: ''
settings: {  }
field_type: string

Field: iiif_image_width (integer)

Field storage

modules/custom/foobar/config/install/field.storage.node.field_iiif_image_width.yml

langcode: en
status: true
dependencies:
  enforced:
    module:
      - foobar
id: node.field_iiif_image_width
field_name: field_iiif_image_width
entity_type: node
type: integer
settings:
  unsigned: false
  size: normal
module: core
locked: false
cardinality: 1
translatable: true
indexes: {  }
persist_with_no_fields: false
custom_storage: false

Field

modules/custom/foobar/config/install/field.field.node.iiif_media.field_iiif_image_width.yml

# field.field.node.iiif_media.field_iiif_image_width.yml
langcode: en
status: true
dependencies:
    config:
        - field.storage.node.field_iiif_image_width
        - node.type.iiif_media
id: node.iiif_media.field_iiif_image_width
field_name: field_iiif_image_width
entity_type: node
bundle: iiif_media
label: IIIF Image Width
description: ''
required: false
translatable: false
default_value: {  }
default_value_callback: ''
settings:
  min: null
  max: null
  prefix: ''
  suffix: ''
field_type: integer

Summary

As a result, by installing the custom module “foobar,” I was able to create a content type called “IIIF Media” and add fields with string and integer field types, as shown below.

I hope this serves as a useful reference for adding content types and fields using custom modules.