Dynamic content in a content type

Topics: Customizing Orchard
Aug 20, 2014 at 1:01 AM
I looking to find a way to display dynamic item in a content type. Is there any content part that can do this?
Developer
Aug 20, 2014 at 1:54 AM
Can you clarify what you mean by dynamic item? What do you mean by displaying a dynamic item in a content type specifically?
Aug 20, 2014 at 2:11 AM
I'm working on a real estate website made with orchard.

My content type is a house with different static field value (work perfectly!). I would like when the broker is completing the content fields he will be able to add a list of the different rooms of the house. That list need to contains each room witch is dynamic for each house. Can I create a part containing that dynamic list ?
Developer
Aug 20, 2014 at 2:36 AM
Edited Aug 20, 2014 at 2:36 AM
I see. There seem to be various ways you could do this. If Room is also a content type, you might attach a Content Picker Field to your House content type. The user will have to create Rooms first, and then he can associate each Room with the House.

Alternatively, you could add the ContainerPart to the House content type and the ContainablePart to the Room content type, and add Rooms to a House as you create a House.
Aug 20, 2014 at 12:58 PM
Can you tell me, from the second option you mentionned, if I create a containerPart in my house content type, can I get values of those rooms in my House model ?

I'm trying to display values of each room in my house template view.

Ex: I can display this field value from house @Model.House.Adress I would like to display values for each room but in my house template something like

foreach var room in @Model.House.Rooms {
@Display(room.Name)
@Display(room.Size)
}

Can I acces my rooms values from the house model ?
Developer
Aug 29, 2014 at 4:54 AM
Yes you could, although not directly: the House type would have the ContainerPart attached, but the ContainerPart does not provide a direct way to the items that point to this container. The ContainerPartDriver however performs a query on items that reference the ContainerPart and then creates a List shape, which is set as a property on another shape it creates called Parts_Container_Contained. Through this shape you can access its List property, which in turn contains a list of Content shapes, where each Content shape has a ContentItem property that points to your Room content item.

One way to handle all this is by simply rendering some local zone in your House shape, e.g.
@Display(Model.Rooms)
Update Placement.info of your module (or Theme) to place the Parts_Container_Contained shape for the House type inside of the Rooms local zone, e.g.
<Match ContentType="House">
   <Place Parts_Container_Contained=Rooms:0 />
</Match>
In your Content-House.cshtml view, you can render your list of Rooms like this:
@{
   var roomContentShapes = Model.List;
}

<ul>
   @foreach(var roomContentShape in roomContentShapes){
      <li>@Html.ItemDisplayText((ContentItem)roomContentShape.ContentItem)</li>
   }
</ul>
Once you have access to each Room content item, you can access all of its parts and fields.
You could also choose to just render the Room content shape, and create a view file that renders an individual Room. That could look something like this:

Updated Content-House.cshtml view:
@{
   var roomContentShapes = Model.List;
}

<ul>
   @foreach(var roomContentShape on roomContentShapes){
      <li>@Display(roomContentShape)</li>
   }
</ul>
Content-Room.Summary.cshtml:
var room = (ContentItem)Model.ContentItem;

@Html.ItemDisplayText(room)