Question

I want to programmatically create a content type which includes, among other things, an image. The obvious way to do this seems to be to use a MediaLibraryPickerField.

My question is very similar to this one, but unfortunately it doesn't give an answer

My problem is I can't get the field to show up. I've been digging through the docs and other online recourses, but no luck so far. I'm going to post all my code here in the hopes that someone can see what I'm missing. I'm learning, so if I'm doing anything weird, please don't hesitate to point it out.

My content type should consist of:

  • Title
  • Body
  • Description
  • Image

Migration.cs:

SchemaBuilder.CreateTable("MyTypePartRecord",
    table => table
        .ContentPartRecord()
        .Column<string>("Description", c => c.Unlimited())
    );

ContentDefinitionManager.AlterPartDefinition(
    "MyTypePart", builder => builder
        .WithDescription("Turns content types into a MyType.")
        .WithField("Image", f => f.OfType(typeof(MediaLibraryPickerField).ToString()))
        .Attachable()
        );

ContentDefinitionManager.AlterTypeDefinition(
    "MyType",cfg => cfg
        .WithPart("CommonPart")
        .WithPart("MyTypePart")
        .WithPart("TitlePart")
        .WithPart("BodyPart")
        .Creatable()
    );

Models/MyTypePart.cs:

public class MyTypePart : ContentPart<MyTypePartRecord>
{
    public string Description
    {
        get { return Record.Description; }
        set { Record.Description = value; }
    }
}

Models/MyTypePartRecord.cs:

public class MyTypePartRecord : ContentPartRecord
{
    [StringLengthMax]
    public virtual string Description { get; set; }
}

Models/MyTypePartRecordHandler.cs:

public class MyTypePartRecordHandler : ContentHandler
{
    public MyTypePartRecordHandler(IRepository<MyTypePartRecord> repository) {
        Filters.Add(StorageFilter.For(repository));
    }
}

Drivers/MyTypeDriver.cs

public class MyTypeDriver : ContentPartDriver<MyTypePart> {

    public MyTypeDriver() {

    }

    // GET
    protected override DriverResult Display(MyTypePart part, string displayType, dynamic shapeHelper) {
        return ContentShape("Parts_MyType",
            ()=> shapeHelper.Parts_MyType(
                Description: part.Description
                ));
    }

    // GET
    protected override DriverResult Editor(MyTypePart part, dynamic shapeHelper)
    {
        return ContentShape("Parts_MyType_Edit",
            () => shapeHelper.EditorTemplate(
                TemplateName: "Parts/MyType",
                Model: part,
                Prefix: Prefix));
    }

    // POST
    protected override DriverResult Editor(MyTypePart part, IUpdateModel updater, dynamic shapeHelper)
    {
        updater.TryUpdateModel(part, Prefix, null, null);
        return Editor(part, shapeHelper);
    }

}

Views/EditorTemplates/Parts/MyType.cshtml:

@model MySolution.Models.MyType

<fieldset>
    <div class="editor-label">@T("Description"):</div>
    <div class="editor-field">
        @Html.TextBoxFor(m => m.Description)
        @Html.ValidationMessageFor(m => m.Description)
    </div>
</fieldset>

Views/Parts/MyType.cshtml:

@using MySolution.Models

<div>Description: @Model.Description</div>

placement.info:

<Placement>
  <Place Parts_MyType="Content:1"/>
  <Place Parts_MyType_Edit="Content:7.5"/>
</Placement>

UPDATE

As suggested, I changed MyTypePart to MyType throughout the module. Now, in Content Definition, I see the Image Field directly in my content type, instead of it being a field of the MyTypePart part of the content type. I still don't see the field when creating a new item, though.

Was it helpful?

Solution

I finally found out what was wrong. Instead of this:

.WithField("Image", f => f.OfType(typeof(MediaLibraryPickerField).ToString()))

I should have done this:

.WithField("Image", f => f.OfType("MediaLibraryPickerField"))

The former would result in a field of type Orchard.MediaLibrary.Fields.MediaLibraryPickerField instead of just MediaLibraryPickerField and apparently Orchard didn't know how to handle it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top