I have a question thats got me stuck for 2 hours now.
Now all this works great and I get the information displaying on my homepage in the featured section of the layout. At the point I want to start editing the raw data into a nice slider, first things 1st is to iterate through this model and get each slide so i can extract the properties and do something with them.
However as its a dynamic object (orchard shape) there is no intellisense which is to be expected of course. However I have tried every way I can think of to get the property's.
Ive tried http://docs.orchardproject.net/Documentation/Creating-lists
Ive also tried http://www.ideliverable.com/blog/ways-to-render-lists-of-things
Both are good reads but my methodology is to do with widgets and I'm not sure if its because of this that that i cant seem to easily find the property's I need. I've tried stepping through and inspected the dynamic model but the meta data contains nothing that resembles property's.
Code I currently have
@Display(Model.Content)
@{
var MySliderList = Model.List;
}
<div>
@foreach (var slide in MySliderList)
{
<div>@slide.Title</div>
<div>@slide.SliderText</div>
<div>@slide.UrlLink</div>
}
</div>
As you can tell this code doesnt display anything other than @display(model.content).
Can someone tell me the correct way to get the data of each "slide" from the model on this .cshtml?
Many thanks.
UPDATE: also please note the code I have there is the latest attempt, ive also tried Model.ContentItem, ContentItems, ContentItems.Content, Content etc etc.
tl;dr; use projections, skip to the bottom for example links.
The great (and perhaps worst) thing about Orchard is there are a million ways to achieve what you want haha.
The widget view you are trying to override (as Bertrand explained) is basically a mini layout file that will render parts that have been chucked into the "Content" zone. These parts include things like the WidgetPart (which displays the widgets title) and the WidgetContainerPart, which displays the list of Slider Slides in your case.
However, the Widget view can access all its child parts as you are trying to do, instead of letting the individual parts render them. This can be useful in situations where you need a very specific layout calling for bits from multiple parts and fields. But what the view can access is basically the properties of the part as they are given to it from the model/handler. The ContainableWidgetPart builds its list of content items to display within the driver so you cant actually access that list from anywhere outside the view that the driver renders (i.e. Parts.ContainerWidget.cshtml). But fear not, we can just create that list ourselves, if you so wished.
@using Orchard.ContentManagement
@using Orchard.Core.Common.Models
@using Orchard.Core.Containers.Extensions;
@{
var item = Model.ContentItem;
var part = (Orchard.Core.Containers.Models.ContainerWidgetPart)Model.ContentItem.ContainerWidgetPart;
var _contentManager = WorkContext.Resolve<IContentManager>();
var container = _contentManager.Get(part.Record.ContainerId);
IContentQuery<ContentItem> query = _contentManager
.Query(VersionOptions.Published)
.Join<CommonPartRecord>().Where(cr => cr.Container.Id == container.Id);
if (part.Record.ApplyFilter) {
query = query.Where(part.Record.FilterByProperty, part.Record.FilterByOperator, part.Record.FilterByValue);
}
var items = query.Slice(0, part.Record.PageSize).ToList();
}
@foreach (var i in items) {
// do stuff with the item here
}
But having this crap in the view isn't particularly nice. So let's look at the ContainerWidgetPart. What happens in the driver is that it creates a list shape, which is a core shape Orchard provides to render a list of content items. Pretty neat and easy. And if you look closely at the ContainerWidgetPart driver you will see that it is building a view with the display type of "Summary" to be displayed in the list. So we could look at just overriding the display of Slider Slide display using placements to only display the image (that I assume you have on them). However, if you are using a slide it may require certain classes or custom attributes be added to the ul and li elements. This is easily achieved by overriding the Parts.ContainerWidget.cshtml shape in our theme and adding the following lines:
// adds the class slider to the ul
Model.ContentItems.Classes.Add("slider");
// adds a class slider-item to each li
Model.ContentItems.ItemClasses.Add("slider-item");
// adds a custom attribute to each li
Model.ContentItems.ItemAttributes.Add("style", "display:none");
However, if you want to be displaying your content without the ul tags, this isn't particularly useful. You can access the individual items from the list shape using .Items but this seems a little bit silly when you have already built a bunch of shapes to be displayed and then you just go ahead and bypass all that.
So after all this, I'd recommend you using a projection to build your slider. Projections are a lot more flexible, way cooler and you can create badass templates for them. Check out these examples of how to build a slider using Projections:
Or better yet, don't even use a slider because no one really likes them anyway ^_^ Hope I confused you sufficiently, I now have no idea what is going on!