Recipe Migrations in Orchard Core CMS

Freelance Orchard Core Developer

Awhile back I developed an Orchard Core Module that creates a Bootstrap 4 Carousel Widget for Orchard Core CMS Websites. The module uses the traditional IContentDefinitionManager in Orchard CMS, because Recipe Migrations were not available. Recently Recipe Migrations were added to Orchard Core so I took it for a spin and developed a custom Orchard Core Module that creates a Bootstrap 4 Card Widget. In this tutorial I will show you how to configure Recipe Migrations for your custom Orchard Core Modules.

Recipe Migrations in Orchard Core CMS

If you want to use Recipe Migrations, you will need to create a class that inherits from the DataMigration Class (similar to using IContentDefinitionManager) and uses the new IRecipeMigrator interface to execute your recipe migration files. Here is the Migrations Class from my custom Orchard Core CMS Module that creates a Bootstrap 4 Card Widget. I called my recipe migration file, migration.recipe.json, but pick whatever name you want.

using System.Threading.Tasks;
using OrchardCore.Data.Migration;
using OrchardCore.Recipes.Services;

namespace BootstrapCard.OrchardCore {
    public class Migrations : DataMigration {
        private readonly IRecipeMigrator _recipeMigrator;

        public Migrations(IRecipeMigrator recipeMigrator) {
            _recipeMigrator = recipeMigrator;
        }

        public async Task<int> CreateAsync() {
            await _recipeMigrator.ExecuteAsync("migration.recipe.json", this);

            return 1;
        }
    }
}

Make sure you add the Migrations Class to your custom modules Startup Class as a dependency or your recipe migration file will never be executed.

using Microsoft.Extensions.DependencyInjection;
using OrchardCore.Data.Migration;
using OrchardCore.Modules;

namespace BootstrapCard.OrchardCore {
    public class Startup : StartupBase {
        public override void ConfigureServices(IServiceCollection services) {
            services.AddScoped<IDataMigration, Migrations>();
        }
    }
}

RecipeMigrator Expects Recipes In Migrations Folder

If you take a peek at the RecipeMigrator Class in OrchardCore.Recipes.Core, you will notice it looks for recipe migration files in a Migrations Folder. The migration.recipe.json file that I am using in my custom Orchard Core CMS Module to create a Bootstrap 4 Card Widget must be located in a Migrations Folder. Here is a screenshot of the custom module in Visual Studio Code.

Custom Orchard Core CMS Module Bootstrap 4 Card Widget

Migration Recipe Creates Custom Orchard Core Widget

I won't dive into the details here, but my recipe creates a custom Orchard Core Widget, called Card. I developed the widget only to demonstrate and test Recipe Migrations in Orchard Core. Adding the Card Widget to the FlowPart of a Page results in a Bootstrap 4 Card Component on the Page.

Add Widget to FlowPart in Orchard Core CMS

Custom Orchard Core CMS Module Creating Boostrap 4 Card Component

Having developed numerous setup recipes for custom Orchard Core CMS Themes as well as recipes that can be run from the Orchard Core Dashboard to add features on the fly, I much prefer using the new Recipe Migrations feature over IContentDefinitionManager. It's not clear at this time as to the limitations of what can be modified in recipe migration files, however, so complex migration needs may use a combination of both IRecipeMigrator and IContentDefinitionManager.