Content Type with container part not displaying other parts

Topics: Customizing Orchard, General
Feb 17, 2011 at 11:57 AM

Hi,

I seem to be having a problem with trying to display a list below some content on my page:
I'm currently using a content type which contains body parts, fields and now a container part.

The problem is that when I added the contain part to my type it makes all other parts on the content type disappear.

I have had a search through the forums for this problem and have found two solutions:
- edit the placement.info file

- edit the item controller, Views/Item/display.cshtml in Orchard.Core.

The first "solution" did not seem to work at all. The second solution I predict should work but I am simply missing something in the Item Controller:

 var startIndex = container.As<ContainerPart>().Record.Paginated ? pager.GetStartIndex() : 0;
            var pageOfItems = query.Slice(startIndex, pager.PageSize).ToList();

            //// Code to display the container body and title if they have a Body or Route part
            string body = null;
            string title = null;
            if (container.As<BodyPart>() != null)
                body = container.As<BodyPart>().Record.Text;
            if (container.As<RoutePart>() != null)
                title = container.As<RoutePart>().Record.Title;
            var containerShape = Shape.Container(Title: title, Text: body);
            //// End new container code


            var list = Shape.List();
            list.AddRange(pageOfItems.Select(item => _contentManager.BuildDisplay(item, "Summary")));

            dynamic viewModel = Shape.ViewModel() 
                .ContentItems(list)
                .Pager(pagerShape)
                .ShowPager(container.As<ContainerPart>().Record.Paginated);

            // Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
            return View((object)viewModel);

I think the reason my "containerShape" isnt showing up is because I havn't put it in the viewModel object which is then parsed through to the Display.cshtml
Is there any way of doing this?

If there are any other solutions to this problem then please do tell :)

 

Feb 17, 2011 at 1:53 PM

I finally found the solution to this problem now:

In the Orchard.Core/Containers/Controllers/ItemController.cs :
I made the addition to my viewmodel:

           
 var startIndex = container.As<ContainerPart>().Record.Paginated ? pager.GetStartIndex() : 0;
            var pageOfItems = query.Slice(startIndex, pager.PageSize).ToList();

            //// Code to display the container body and title if they have a Body or Route part
            string body = null;
            string title = null;
            if (container.As<BodyPart>() != null)
                body = container.As<BodyPart>().Record.Text;

            if (container.As<RoutePart>() != null)
                title = container.As<RoutePart>().Record.Title;
            var containerShape = Shape.Container(Title: title, Text: body);
            //// End new container code


            var list = Shape.List();
            list.AddRange(pageOfItems.Select(item => _contentManager.BuildDisplay(item, "Summary")));

            // Here I made the change to the view model to include the 
            //dynamic viewModel = Shape.ViewModel(Title: title, Text: body) 
                 .ContentItems(list)
                .Pager(pagerShape)
                .ShowPager(container.As<ContainerPart>().Record.Paginated);

I simply changed the view model to store the values I got from the database (title and body). I then changed my
Containers/Views/Items/Display.cshtml to:
@{
    var bodyText = new HtmlString(@Model.Text);
}
<h1>@Model.Title</h1>
@bodyText

@Display(Model.ContentItems)
@if (Model.ShowPager)
{
    @Display(Model.Pager)
}


Which made my list display the content at the top and hey there you go!!!

Now to just get the content item's fields to be displayed and I'll have a wonderful content type ready to use.

Coordinator
Feb 17, 2011 at 7:32 PM

I don't understand why you would have to do that in Core. Why can't this code live in a handler for example?