NodeType Removal

There may be many reasons to remove a NodeType. It might no longer be needed by the editors. Or you restructured your content or NodeTypes. To keep your Neos from accumulating unused NodeTypes it is recommended to remove those, that are no longer needed.

There are a few things to consider and also more than one way to remove a NodeType.

#Removing a NodeType without children

Removing a NodeType consists of two steps:

  1. remove the NodeType definition (.yaml configuration), its rendering/template (.fusion or fluid), styling (css), translations (.xlf), example:
    • Neos.Demo/NodeTypes/Content/Headline/Headline.yaml
    • Neos.Demo/NodeTypes/Content/Headline/Headline.fusion
    • Neos.Demo/Resources/Private/Fusion/Presentation/Headline.fusion
    • Neos.Demo/Resources/Private/Translations/en/NodeTypes/Content/Headline.xlf
  2. remove the actual content from the database

Optional: remove its usage in other NodeTypes (.yaml) - see the example screenshot below of the usage of the Youtube NodeType in the Carousal NodeType:

Screenshot of Neos.Demo Github Repository with search results for the term youtube

explicit usage of "youtube" in the Neos.Demo package

In the example above in addition to the files that are called Youtube... there may be further references to the NodeType in the code which you should clean up. For example:

  • Neos.Demo/NodeTypes/Content/Carousel/Carousel.yaml
  • Neos.Demo/NodeTypes/Content/Carousel/Carousel.fusion

#Remove the content - using a custom Node Migration

Node migrations are a powerful tool to update your NodeTypes including their removal. 

Create a blueprint Node Migration:

Create an empty blueprint node migration
./flow node:migrationcreate [packageKey, e.g. Neos.Demo]

Neos.Demo/Migrations/ContentRepository/Version20240312104355.yaml
Your node migration has been created successfully.

The resulting file is placed in the Migrations folder in your specified Package with the current timestamp, example: Neos.Demo/Migrations/ContentRepository/Version20240312104355.yaml

Generated empty Node Migration blueprint
#############################################################################################################################################################################
# For more information about node migrations in Neos, checkout the documentation: https://neos.readthedocs.io/en/stable/References/NodeMigrations.html?highlight=migrations #
#############################################################################################################################################################################
up:
  comments: 'Migration description'
  migration:
    -
      filters:
        -

down:
  comments: 'No down migration available'

Fill your Node Migration with the necessary information:

Node Migration to remove the YouTube NodeType
up:
  comments: 'Migration to remove the YouTube content NodeType'
  migration:
    -
      filters:
        -
          type: 'NodeType'
          settings:
            nodeType: 'Neos.Demo:Content.YouTube'
      transformations:
        -
          type: 'RemoveNode'

down:
  comments: 'No down migration available'

After you created the Node Migration, list the available migrations to get its version identifier...

list available node migrations
./flow node:migrationstatus

+----------------+---------------------+------------------------+--------------------------------------------------------------+
| Version        | Date                | Package                | Comments                                                     |
+----------------+---------------------+------------------------+--------------------------------------------------------------+
| 20120725073211 | 25-07-2012 07:32:11 | Neos.ContentRepository | This is the migration to adjust your content to the Phoenix  |
|                |                     |                        | content types definition committed in the July 2012 sprint   |
|                |                     |                        | release                                                      |
| 20120921140942 | 21-09-2012 14:09:42 | Neos.Neos              | This is the migration to adjust sites to the new             |
|                |                     |                        | TYPO3.Phoenix.ContentTypes namespace                         |
| 20121030105142 | 30-10-2012 10:51:42 | Neos.NodeTypes         | This is the migration to adjust sites from Phoenix to Neos   |
| 20121030110246 | 30-10-2012 11:02:46 | Neos.Demo              | Rename from Phoenix to Neos                                  |
| 20130326131600 | 26-03-2013 13:16:00 | Neos.NodeTypes         | This is the migration to adjust from "Content Types" to      |
|                |                     |                        | "Node Types"                                                 |
| 20130515214324 | 15-05-2013 21:43:24 | Neos.NodeTypes         | This is the migration to add new property hasCaption to      |
|                |                     |                        | already existing "Image" and "Text With Image" nodes         |
| 20130516212400 | 16-05-2013 21:24:00 | Neos.NodeTypes         | This is the migration to adjust the node types to the        |
|                |                     |                        | renaming as per #45317                                       |
| 20130911165510 | 11-09-2013 16:55:10 | Neos.NodeTypes         | This is the migration to move the "page" NodeType from       |
|                |                     |                        | TYPO3.Neos to TYPO3.Neos.NodeTypes as per #52020             |
| 20140326143834 | 26-03-2014 14:38:34 | Neos.ContentRepository | Migrate from no node dimensions to default dimension values. |
| 20140516221523 | 16-05-2014 22:15:23 | Neos.ContentRepository | Migrate from "locales" dimension to "languages" dimension.   |
| 20140708120530 | 08-07-2014 12:05:30 | Neos.ContentRepository | Delete removed nodes that were published to "live" workspace |
| 20140723115900 | 23-07-2014 11:59:00 | Neos.Neos              | Migrate from "languages" dimension to "language" dimension.  |
| 20140930125621 | 30-09-2014 12:56:21 | Neos.Neos              | Migrate shortcut nodes: targetMode value adjustment and      |
|                |                     |                        | rename targetNode property                                   |
| 20141103100401 | 03-11-2014 10:04:01 | Neos.Neos              | Migrate serialized Media objects to relation format.         |
| 20141210114800 | 10-12-2014 11:48:00 | Neos.NodeTypes         | This is the migration to rename the "insert record" NodeType |
|                |                     |                        | from TYPO3.Neos.NodeTypes:Records to                         |
|                |                     |                        | TYPO3.Neos.NodeTypes:ContentReferences as per NEOS-847       |
| 20150716212459 | 16-07-2015 21:24:59 | Neos.ContentRepository | Migrate from some node dimensions to default dimension       |
|                |                     |                        | values, adding missing dimension default values.             |
| 20150907194505 | 07-09-2015 19:45:05 | Neos.Neos              | Migrate PluginViews references from node paths to            |
|                |                     |                        | identifiers.                                                 |
| 20160427182952 | 27-04-2016 18:29:52 | Neos.Demo              | Rename from Neos.NeosDemoTypo3Org to Neos.Demo               |
| 20190204182906 | 04-02-2019 18:29:06 | Neos.Demo              | Alter node-types to match best practices 1.0.0               |
| 20190218182044 | 18-02-2019 18:20:44 | Neos.Demo              | Migrate nodetypes from Neos.NodeTypes to Neos.Demo namespace |
| 20190304111200 | 04-03-2019 11:12:00 | Neos.NodeTypes         | Alter NodeTypes of subpackages that are extracted from       |
|                |                     |                        | Neos.NodeTypes to their respective namespaces                |
| 20190308100514 | 08-03-2019 10:05:14 | Neos.Demo              | Migrate content collection types to Neos.Demo namespace      |
| 20240312104355 | 12-03-2024 10:43:55 | Neos.Demo              | Migration to remove the YouTube content NodeType                                        |
|                |                     |                        | Applied:                                                     |
|                |                     |                        |    UP applied on 2024-03-12 10:55:37                         |
+----------------+---------------------+------------------------+--------------------------------------------------------------+

... and execute the migration:

execute a specific node migration
./flow node:migrate 20240312104355

Comments
  Migration to remove the YouTube content NodeType

Successfully applied migration.

#Remove the content - using node:repair

An alternative method to delete the content from the database is to use a node:repair command. 

Use node:repair with --dry-run first!

Review the output from the node:repair command with the --dry-run argument before running it without it. As the command removeAbstractAndUndefinedNodes cannot be scoped to a specific NodeType it might remove more than you intend.

Remove a NodeType with node:repair
./flow node:repair --only removeAbstractAndUndefinedNodes --dry-run

#Removing a NodeType with possible children

A custom node migration does NOT remove the child nodes of a removed node.

If you remove a node that could have child nodes, these child nodes will become orphaned nodes without a parent.

After you removed the NodeType definition (see above) you can list the nodes that would be removed, using node:repair. In the below example, we removed the Carousel and the CarouselYoutTube NodeTypes.

node:repair to get a list of affected nodes
./flow node:repair --only removeAbstractAndUndefinedNodes --dry-run
Dry run, not committing any changes.
Run checks for basic node integrity in the content repository

Checking for nodes with abstract or undefined node types ...
Found node with undefined node type named "node5270f5b85777b" (Neos.Demo:Content.Carousel) in "/sites/neosdemo/features/custom-elements/main/node5270f5b85777b"
Found node with undefined node type named "node-bj9mshvwdeq6h" (Neos.Demo:Content.CarouselYouTube) in "/sites/neosdemo/features/custom-elements/main/node5270f5b85777b/node-bj9mshvwdeq6h"
 ❱ Remove 2 nodes with abstract or undefined node types
    skipped (dry run)

Run integrity checks related to Neos features


Node repair dry run finished.

Run node:repair removeOrphanNodes before 

To have a baseline to compare your orphaned nodes to after your removed your desired NodeType, execute ./flow node:repair --only removeOrphanNodes --dry-run before you run the removal node migration. 

Execute your removal node:migration (see steps above) to actually remove the node and review the resulting orphaned nodes afterwards with

node:repair command to remove orphaned nodes
./flow node:repair --only removeOrphanNodes --dry-run
Dry run, not committing any changes.
Run checks for basic node integrity in the content repository

Checking for orphan nodes ...
Found orphan node named "node-bj9mshvwdeq6h" (Neos.Demo:Content.CarouselYouTube) in "/sites/neosdemo/features/custom-elements/main/node5270f5b85777b/node-bj9mshvwdeq6h"
Found orphan node named "node-lucdhi6k3disi" (Neos.Demo:Content.Headline) in "/sites/neosdemo/features/custom-elements/main/node5270f5b85777b/node-lucdhi6k3disi"
Found orphan node named "node5270f60a66dfb" (Neos.Demo:Content.Image) in "/sites/neosdemo/features/custom-elements/main/node5270f5b85777b/node5270f60a66dfb"
Found orphan node named "node-s00zs4l1b6cdo" (Neos.Demo:Content.Headline) in "/sites/neosdemo/features/custom-elements/main/node5270f5b85777b/node-s00zs4l1b6cdo"
Found orphan node named "node5270f5d9e1496" (Neos.Demo:Content.Image) in "/sites/neosdemo/features/custom-elements/main/node5270f5b85777b/node5270f5d9e1496"
 ❱ Remove 5 orphan nodes
    skipped (dry run)

Run integrity checks related to Neos features


Node repair dry run finished.