Adding a field to a content type in an Orchard data migration

In Orchard you can create your own content type by welding together several content parts. Here is an example of how you'd do that in your data migration:

ContentDefinitionManager.AlterTypeDefinition("MyNewType",
    cfg => cfg
        .WithPart("TitlePart")
        .WithPart("BodyPart")
        .WithPart("CommonPart")
);

You can also add fields to a content type, but it's not obvious at first how to do this. You can't add a field to a type directly, you can only add fields to parts. To get round this you can add a secret part to a type with the same name as the type. This part is not shown in content admin, but it acts as a container for any fields you'd like to add.

Here is how you'd change the above data migration to add a field to your type.

ContentDefinitionManager.AlterTypeDefinition("MyNewType",
    cfg => cfg
        .WithPart("MyNewType")
        .WithPart("TitlePart")
       .WithPart("BodyPart")
        .WithPart("CommonPart")
);

ContentDefinitionManager.AlterPartDefinition("MyNewType",
    cfg => cfg
        .Attachable()
        .WithField("Picture", f => f.OfType("MediaLibraryPickerField").WithDisplayName("Type picture"))
);