Using Content Migrations in Craft 3

Matt profile photo
Written by Matt on 23rd February 2018

When Craft 3 is released on April 4th 2018 it comes with a whole host of new features, one of them is something called content migrations. An article called Coming to Craft 3: Content Migrations has been written by Pixel & Tonic, the people behind Craft and it goes into a little bit of detail about how they can be used. This article is dated Sep 21, 2016 and is from an early beta version of Craft 3 so we’ve decided to take a deeper look into what these Content Migrations can achieve.

What is a Content Migration?

A content migration in its simplest form is a script that can be run on the site to modify something in the cms. This could be as simple as a database query to update some tables. As with everything Craft related though, the potential uses for this functionality are very large when you consider we have full access to the Craft::$app within these migrations.

Essentially what this means is that we can use a migration to make changes to fields on a dev site, and then instead of having to make those same changes manually on the live site, we just upload and run our migration and the same changes are applied. This makes it much easier to keep the dev and live databases in tandem with each other. However, migrations don’t just stop there, on numerous stack exchange posts we’ve seen people suggesting that the possibilities are endless for what these migration files can do, so we thought we’d give it a go.

Creating a migration

There are 2 ways to create a migration file, one is to do it via the command line, and the other is to create the file yourself locally. To create the file manually, all you need to do is create a migrations folder to sit at the same level as your config, modules, plugins, storage, templates and web folders. Once this is done you can add a new php file into this folder with a name of the following format m{Y}{m}{d}_{H}{i}{s}_{migration_name}, so this would be something along the lines of m180221_092706_adigital_text_fields as an example.

However all of this can be fully automated by simply opening the command line on the server, navigating to where your install is held at the level where the plugins, templates, etc are held, and then just running the following command:

./craft migrate/create adigital_text_fields

This will then create a migrations folder for you if one doesn’t already exist, and it will create the file inside for you with its date and time of creation added to the filename. It will also have a class set up with a safeUp() function ready for you to start coding.

We would recommend that creating your migration using the command line is the best way to get started, you can pull the migration down locally and update it in your favourite coding program.

Running and Reverting

Once you have updated your migration file to do what you need, make sure it is uploaded to your server and then you will have 2 options for running it. Option 1 is to run it in the cms under Utilities => Migrations, and option 2 is to once again use the command line. As long as your migration has been created correctly you should have no problem using option 1 to click a button in the cms and run these migrations. However if you encounter errors then the best way to run them is via the command line as you will be returned a stack trace which you can then use to find your errors and fix them. Once your migrations are created and working, they can confidently be run via the cms but we would recommend that when building and testing migrations, running them through the command line is the best option using:

./craft migrate/up

If you need to revert a migration and have coded up the safeDown() function, then there is currently no way of doing this via the cms whilst we are in Craft CMS 3.0.0-RC12 so the only option is to use the command line. Reverting migrations works a little differently to running them as reverting is done one at a time with a separate command for each one, whereas running them is all done with a single command. To revert a migration you will need to use the servers command line and run:

./craft migrate/down

How we have used them

Now that you know how to create a basic migration, run it, and revert it, we want to share what we have been able to achieve using these. Whilst migrating changes from the dev site to the live can be very handy, this is not the only usage we can get out of our migrations. We have developed a set of migrations that we can use at the start of a project on a fresh build of Craft. Starting with a blank install, we simply upload our migrations folder and run them via the cms and we instantly have the following created within the cms:

  • 2 Asset Volumes
  • 3 commonly used Plugins
  • 4 text fields
  • 2 redactor fields
  • 1 entries field
  • 2 assets fields
  • 3 matrix fields

This means that we have a very good basis for the start of our project and can edit and remove fields as we need. The migrations have done their job and can be left alone now. Taking this one step further we can upload a macro template that we use for our matrix blocks as the fields always start out the same. This means we have consistency between projects but can also retain our ability to deeply customise each site, using this as a very good starting point.

The plugins we use on most projects are also added and the settings populated by our migration files so we don’t even need to go through the process of adding and customising each one at the start of a project.

Possibilities for future usage

Initially we started off just creating our fields using a fairly basic migration. We then started to add more complex fields such as matrix blocks which required a more complex migration. This then grew to adding the necessary asset volumes that we need for our asset fields. The next logical step was to then add in plugins such as redactor for our rich text fields.

Going forwards we could use these migrations to actually create our sections with field layouts using these fields we have created. We could then populate these sections with some generic content which is ready to be customised, removed, or replaced by the client.

By having access to Craft::$app we truly can do essentially anything in a migration, as long as it is available in the class reference it is within our scope to create this functionality.

Currently the documentation around content migrations and the number of articles describing them are fairly vague but by using the class reference and the Craft->$app functions we have managed to create a lot of working code. These migrations can be viewed on our GitHub and you’re welcome to use them as a starting point for your own migrations. It turns out that the possibilities really are endless, happy coding!