Attachable Part Not Showing In Create Menu...Help

Jan 19, 2011 at 4:39 AM

I have taken the tutorial on creating a many to many linking part for my module. The part is attached to the Page content type as a test.  When I debug the code the driver editor method is being called and a content shape is being returned but the cshtml in my template is not being displayed in the page create or edit forms. I think the template is not being found or my placement.info file is wrong would any of these things cause the part not to render in the attached content types create or edit views.  Any help would be helpful.  Also Thanks to the Orchard Team for an awesome CMS.

The driver code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using JetBrains.Annotations;
using SmudgeIT.TwitterFeed.Models;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement;
using SmudgeIT.TwitterFeed.ViewModels;
using SmudgeIT.TwitterFeed.Services;

namespace SmudgeIT.TwitterFeed.Drivers
{
    [UsedImplicitly]
    public class TwitterAccountsPartDriver : ContentPartDriver<TwitterAccountsPart>
    {
        private readonly ITwitterAccountsService _accountService;

        private const string TemplateName = "Parts/TwitterAccounts";

        public TwitterAccountsPartDriver(ITwitterAccountsService accountService)
        {
            _accountService = accountService;
        }

        protected override DriverResult Display(TwitterAccountsPart part, string displayType, dynamic shapeHelper)
        {

            return ContentShape("Parts_TwitterAccounts",
                            () => shapeHelper.Parts_TwitterAccounts(
                                ContentPart: part,
                                TwitterAccounts: part.Accounts));
        }

        protected override DriverResult Editor(TwitterAccountsPart part, dynamic shapeHelper)
        {
            return ContentShape("Parts_TwitterAccounts_Edit", () => shapeHelper.EditorTemplate(
                         TemplateName: TemplateName,
                         Model: BuildEditorViewModel(part),
                         Prefix: Prefix)
                         );
        }

        protected override DriverResult Editor(TwitterAccountsPart part, IUpdateModel updater, dynamic shapeHelper)
        {
            var model = new EditTwitterAccountsViewModel();
            updater.TryUpdateModel(model, Prefix, null, null);

            if (part.ContentItem.Id != 0)
            {
                _accountService.UpdateTwitterAccountsForContentItem(
                    part.ContentItem, model.TwitterAccounts);
            }

            return Editor(part, shapeHelper);
        }

        private EditTwitterAccountsViewModel BuildEditorViewModel(TwitterAccountsPart part)
        {
            var itemAccounts = part.Accounts.ToLookup(r => r.Id);
            return new EditTwitterAccountsViewModel
            {
                TwitterAccounts = (from s in _accountService.GetAccounts()
                                   select
                                       new TwitterAccountEntry
                                       {
                                           TwitterAccount = s,
                                           IsChecked = itemAccounts.Contains(s.Id)
                                       }
                    ).ToList()
            };
        }
    }
}

The Template (EditorTemplates/Parts/TwitterAccounts.cshtml)

@model SmudgeIT.TwitterFeed.ViewModels.EditTwitterAccountsViewModel
<fieldset>
    <legend>@T("Twitteer Accounts")</legend>
    <ul>
        @{
            var rewardIndex = 0;
        }
        @foreach (var account in Model.TwitterAccounts)
        {
            <li>
                <input type="hidden" value="@account.TwitterAccount.Id"
        name="@Html.FieldNameFor(m => m.Accounts[rewardIndex].TwitterAccount.Id)"/>
                <label for="@Html.FieldNameFor(m => m.Accounts[rewardIndex].IsChecked)">
                    <input type="checkbox" value="true"
                name="@Html.FieldNameFor(m => m.Accounts[rewardIndex].IsChecked)"
                id="@Html.FieldNameFor(m => m.Accounts[rewardIndex].IsChecked)"
                @if (reward.IsChecked)
                {<text>checked="checked"</text>}/>
                    @string.Format("{0} ({1:P1})", account.TwitterAccount.Username, account.TwitterAccount.UserId))
                </label>
                @{rewardIndex++;}
            </li>
        }
    </ul>
</fieldset>

The placement.info file
<Placement>
    <Place Parts_TwitterAccounts_Edit="Content:1"/>
</Placement>

    




Coordinator
Jan 19, 2011 at 4:57 AM

Try to assign a completely different position in the placement file, such as 1.1. It should support more than one at the same place but there might be a bug there.

Coordinator
Jan 19, 2011 at 7:03 AM

Also, check the "error" log file. I think that for Drivers, we ended up catching exceptions, logging errors and let the rest of the drivers run. So, if you have a "bug" in your driver or template, it will simply not render.

Jan 19, 2011 at 11:38 AM

Thanks for your replies I have tried both of those suggestions and no change I get a shape object at the end of the driver editor method and it is returned but the no mention of my part in the rendering of the create form any other options?

Coordinator
Jan 19, 2011 at 5:40 PM

Try replacing the template with something extremely simple, with no code and see if it gets displayed.