Creating a custom Content Part (shapes do not display)

Topics: Writing modules
Jun 22, 2011 at 8:27 PM
Edited Jun 22, 2011 at 9:36 PM

As a learning exercise, I wanted to create a custom content part, so I started to write one that had a simple string field called TagName that would basically just get its value spit back out...I named this "RelatedContent" because eventually I'll morph it into something practical, so ignore the unintuitive name for now :).  

So, I created a new content type called "Related Content" and added my "Related Content Part" to that type.  The problem is, when I go to edit my new content type, the shape for my content part isn't displaying. Here's the code:

RelatedContentDriver.cs

 

public class RelatedContentDriver : ContentPartDriver<RelatedContentPart>
    {
        protected override DriverResult Display(
            RelatedContentPart part, string displayType, dynamic shapeHelper)
        {

            return ContentShape("Parts_RelatedContent", () => shapeHelper.Parts_RelatedContent(
                TagName: part.TagName));
        }

        //GET
        protected override DriverResult Editor(
            RelatedContentPart part, dynamic shapeHelper)
        {

            return ContentShape("Parts_RelatedContent_Edit",
                () => shapeHelper.EditorTemplate(
                    TemplateName: "Parts/RelatedContent",
                    Model: part,
                    Prefix: Prefix));
        }
        //POST
        protected override DriverResult Editor(
            RelatedContentPart part, IUpdateModel updater, dynamic shapeHelper)
        {

            updater.TryUpdateModel(part, Prefix, null, null);
            return Editor(part, shapeHelper);
        }
    }

 

RelatedContentHandler.cs

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

RelatedContent.cs (model)
public class RelatedContentRecord : ContentPartRecord
    {
        public virtual string TagName { getset; }
    }

    public class RelatedContentPart : ContentPart<RelatedContentRecord>
    {
        [Required]
        public string TagName
        {
            get { return Record.TagName; }
            set { Record.TagName = value; }
        }
    }
Views/EditorTemplates/Parts/RelatedContent.cshtml
<fieldset>
              
  <div class="editor-label">
    @Html.LabelFor(model => model.TagName)
  </div>
  <div class="editor-field">
    @Html.TextBoxFor(model => model.TagName)
    @Html.ValidationMessageFor(model => model.TagName)
  </div>
          
</fieldset>

Views/Parts/RelatedContent.cshtml

Tag Name: @Model.TagName

Migrations.cs
public int Create()
        {
            // Creating table MapRecord
            SchemaBuilder.CreateTable("RelatedContentRecord", table => table
                .ContentPartRecord()
                .Column("TagName"DbType.String)
            );

            ContentDefinitionManager.AlterPartDefinition(
                typeof(RelatedContentPart).Name, cfg => cfg.Attachable());

            return 1;
        }

I'm sure it's just some small detail that I"m missing, but I can't figure out for the life of me why it won't show up.
Jun 22, 2011 at 9:01 PM

I took a very brief look at what you posted and it seems ok.
Did you edit your theme's placement.info file? 

Something along the lines of:

  <Place Parts_RelatedContent ="Content:10"/>

Jun 22, 2011 at 9:01 PM

I took a very brief look at what you posted and it seems ok.
Did you edit your theme's placement.info file? 

Something along the lines of:

  <Place Parts_RelatedContent ="Content:10"/>

Jun 22, 2011 at 9:03 PM

My placement.info file is the following:

<Placement>
    <Place Parts_RelatedContent="Content:10"/>
    <Place Parts_RelatedContent_Edit="Content:7.5"/>
</Placement>
Jun 22, 2011 at 9:16 PM

Hmm it all looks good. When I've had that problem it's always been the placement.info file.

Are you sure you added the RelatedContentPart to a ContentType?
Is your module enabled?



 

Jun 22, 2011 at 9:20 PM

Yeah, I added it, I just checked.  Something else might be amiss though, as when I went to enable it, it was showing both the feature and the module itself as being able to be enabled/disabled. I've never seen that before. I verified by changing the manifest file to show different descriptions/names for the feature and the module itself.

Jun 22, 2011 at 9:20 PM

I've also had issues that didn't work before I left for lunch magically start working afterwards.  I wonder if some kind of caching is going on...

Jun 22, 2011 at 9:24 PM

restart your webserver

Jun 22, 2011 at 9:30 PM

Yep, that did it...I should probably make a habit of doing an IISReset after every new module :)

Coordinator
Jun 22, 2011 at 9:32 PM

Apologies for being late at the party but I can't find in this thread a statement of what exactly is not working.

Jun 22, 2011 at 9:35 PM

I put it in the subject line, but you're right, I wasn't explicit...when I edit my content type, the content part's shape wasn't displaying in the edit form.  A simple restart of the web server did the trick...

Coordinator
Jun 22, 2011 at 9:41 PM

Ah, yes, I missed that part in the subject.

Jun 22, 2011 at 9:42 PM

It's ok, I added a sentence to the top post to make it more clear as well. Thanks again for the prompt responses.

Jun 23, 2011 at 3:24 PM

When I actually created a new item with this part tied to it, it saves correctly, but when I go to the content page in the admin, it gives me the following error:

The model item passed into the dictionary is of type 'IShapeProxy4266dc98ea644ed5889b82ce4d5f9400', but this dictionary requires a model item of type RelatedContent.Models.RelatedContentPart'

Jun 23, 2011 at 3:30 PM

Interesting, after viewing this post, I removed this line from my display view:

@model RelatedContent.Models.RelatedContentPart

I guess the display view doesn't need that line?
Jun 23, 2011 at 6:09 PM

That's right, for display views you are usually passing in a dynamic object so you don't want to specify a model type.

On editor views you'll pass in a specific model type so you use the @model there.

Jun 23, 2011 at 6:11 PM

Yep, I saw that in the official orchard docs that the model wasn't specified on the display view, and I thought it was an error of omission. 

Jun 23, 2011 at 6:29 PM

Maybe those docs could explain it a bit more; it's something I remember happening and then figuring it out like you did, but it's not obvious at first.

Coordinator
Jun 23, 2011 at 6:30 PM

Sure, it's a wiki ;)