Node Migrations
Mass-Update Nodes programmatically
Neos <=8.x content
This is content for Neos <= 8.x releases.
This content is obsolete with Neos 9.0 and the event sourced Content Repository.
Node Migrations are a way to programmatically mass-update the Nodes you have in Neos. This is needed when you want to rename NodeTypes, adjust property names or update Content Dimensions.
#The core idea
Node migrations are defined in YAML files, residing in the Migrations/ContentRepository/ folder of a package.
A migration must have an up part (for migrating "upwards"), and it can have a down part for reverting the migration (if possible).
Each Node migration consists of two steps:
- a set of filters which determine when a node should be transformed. Only if a node matches all filters, it is transformed.
- a list of transformations to update the filtered nodes.
#Running a migration
You can list all migrations in all packages using the ./flow node:migrationstatus command:
$ ./flow node:migrationstatus
Available migrations
+----------------+---------------------+------------------------+--------------------------------------------------------------+
| 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 |
| | | | "NodeTypes" |
| 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 NodeTypes 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 |
+----------------+---------------------+------------------------+--------------------------------------------------------------+
To actually run a migration, use the ./flow node:migrate [version] command:
$ ./flow node:migrate 20160427182952
Comments
Rename from Neos.NeosDemoTypo3Org to Neos.Demo
Successfully applied migration.
#Adding a Content Dimension
One of the most common cases to run a node migration is when you have created your website without dimensions first, and lateron want to introduce e.g. a language dimension. In this case, the existing content (which has no dimension information attached) needs to be moved to the default of the dimension; otherwise it just disappears because it is not reachable anymore.
As an example, let's say we have started our website without dimensions, and then we add the following dimension configuration:
Neos:
ContentRepository:
contentDimensions:
language:
label: 'Language'
# the following line determines the default language
default: en_US
defaultPreset: en_US
presets:
en_US:
label: 'English (US)'
values:
- en_US
uriSegment: en
de:
label: German
values:
- de
uriSegment: de
With the above configuration, our complete website has no visible content anymore, as the content in the system is not yet moved to the language dimension.
This can be done with a node migration which is included in the Neos.ContentRepository package:
./flow node:migrate 20150716212459
Needs to be run whenever you add new dimensions
This migration has to be applied whenever a new dimension is configured to set the default value on all existing nodes.
Now, every content in the system is moved to language en_US, because this is the dimension's default in the configuration above.
This means your content is visible again in en_US, and you can start translating from en_US to de.
#Writing a custom migration
Pro tip:
Since Neos 8.3 it is possible to create node migrations also via the console. You can find more information in the documentation.
To create a node migration, since Neos 8.3 you can execute the command ./flow node:migrationcreate [package key]
. This creates a blueprint migration file.
Alternatively place a new YAML file inside the Migrations/ContentRepository folder of your package.
The name of the Migration YAML file must be Version[YYYYMMDDHHmmss].yaml, so the full timestamp (Year + Month + Day + Hour + Minute + Second) of the time when the migration is migrated is part of the filename, as in-order execution of migrations is sometimes important.
Here is an example of a migration that operates on nodes in the “live” workspace that are marked as removed and applies the RemoveNode transformation on them, i.e. deleting the nodes permanently.
up:
comments: 'Delete removed nodes that were published to "live" workspace'
warnings: 'There is no way of reverting this migration since the nodes will be deleted in the database.'
migration:
-
filters:
-
type: 'IsRemoved'
settings: []
-
type: 'Workspace'
settings:
workspaceName: 'live'
transformations:
-
type: 'RemoveNode'
settings: []
down:
comments: 'No down migration available'
Note:
Node migrations in Migrations/TYPO3CR directories are also supported for historic reasons
#Available Filters
The Content Repository comes with a number of filters:
- DimensionValues
- IsRemoved
- NodeName
- NodeType
- PropertyNotEmpty
- Workspace
They all implement the Neos\ContentRepository\Migration\Filters\FilterInterface. Custom filters can be developed against that interface as well, just use the fully qualified class name for those when specifying which filter to use.
#Available Transformations
The Content Repository comes with a number of common transformations:
- AddDimensions
- AddNewProperty
- ChangeNodeType
- ChangePropertyValue
- RemoveNode
- RemoveProperty
- RenameDimension
- RenameNode
- RenameProperty
- SetDimensions
- StripTagsOnProperty
They all implement the Neos\ContentRepository\Migration\Transformations\TransformationInterface. Custom transformations can be developed against that interface as well, just use the fully qualified class name for those when specifying which transformation to use.