Adding a field to a part in a migration

Topics: Writing modules
Apr 5, 2011 at 7:55 AM

Hi guys,

Sorry if I'm being dumb: how do I add a field (e.g. Contrib.ImageField) to a part in a migration? I'm assuming it's not using WithPart() - but I can't see WithField().

I tried the following anyway but it didn't work:



ContentDefinitionManager.AlterTypeDefinition("Profile", cfg => cfg



Thanks for your help :)

Apr 5, 2011 at 10:21 AM
Edited Apr 5, 2011 at 10:28 AM

If you need to alter ContentPart, you'll have to use 'AlterPartDefinition':

ContentDefinitionManager.AlterPartDefinition("mypart", part => part.WithField("MyField", field => field.OfType("ImageField")); 

[edit: there was a mistake in the code, I forgot to set up a field type, gave only FieldName. Default fieldType is TextField]

Your code tries to add a part (not field) named 'ImageField' to contentType 'Profile'. That does not work because there is no ContentPart with such name.

The tricky thing is if you want to add a field directly to a ContentType. The web-interface allows it, but 'behind the scene' a fake contentPart is created with the same name as ContentType and the field is actually added to this part. The migration interface does not seem to support 'fields directly in ContentTypes', so you'll have to create a part and add field to this part.

[Actually I did not try 'fields in types' myself, so I can be wrong about it]

Apr 5, 2011 at 10:23 AM

I guess you would have to do the same if you wanted multiple instances of a field on a content item then? Or could you add multiple fields to the part and do it that way?

Apr 5, 2011 at 10:32 AM
Edited Apr 5, 2011 at 10:38 AM

You can not add any fields to ContentType during migration (as far as I know), but you can add any number of fields (even multiple fields of the same type) to ContentParts. So the solution would be something like:

                part => part
                    .WithField("MyField1", field => field.OfType("ImageField"))
                    .WithField("MyField2", field => field.OfType("ImageField"))

                type => type.WithPart("MyContentPart"));
We create a part, add our fields to this part, and add the part to our ContentType.
Apr 5, 2011 at 12:33 PM

When you create a Content Type, a dummy Content Part by the same name is also created.

So you should be able to do:

ContentDefinitionManager.AlterTypeDefinition("MyContentType", ...)

ContentDefinitionManager.AlterPartDefinition("MyContentType", part=>part.WithField...)

Note: I haven't tested this, it's just my understand of how fields and types work elsewhere...

Apr 5, 2011 at 7:40 PM

Awesome thanks guys, that worked.

How could I then set one of the attributes of the ImageField (specifically ImageFieldSettings.MediaFolder)?

Apr 5, 2011 at 7:43 PM
   .WithField("MyField1", field => field.OfType("ImageField").WithSetting(...))

Don't know offhand whether you need to use "MediaFolder" or the full "ImageFieldSettings.MediaFolder". You might have to experiment :)

Apr 5, 2011 at 7:50 PM

You, sir, are a hero.

Aug 21, 2012 at 6:37 PM

In case anyone else stumbles upon this thread...

A ContentPart with the same name as the ContentType is created when adding Fields within the Orchard admin.  This ContentPart is not shown in the Content Parts tab since it's named the same as a ContentType.  It is used to relate the Fields to the ContentType (via this hidden ContentPart).  In order to do this in Migrations.cs you must do what randompete wrote above, but also add the ContentPart to the ContentType as follows:


ContentDefinitionManager.AlterPartDefinition("MyContentType", part=>part.WithField...)

ContentDefinitionManager.AlterTypeDefinition("MyContentType", cfg => cfg.WithPart("MyContentType")...)


Aug 15, 2013 at 4:31 PM
I wrote a blog post about how you add a field to a type. It doesn't add any more than is in this discussion, but it's a nice summary.