Taking over list rendering in Orchard
A task that is likely to pop-up oftentimes when customizing an Orchard theme for a project is list rendering. Two types of shapes will typically be at work when rendering a list in Orchard: the summary shape and the list shape.
The list shape itself will rarely vary as the semantics of a list pretty much mandate the use of a simple UL/LI decorated with CSS classes. It's so simple in fact that it's not even rendered by a template but by a C# shape method in CoreShapes.cs.
The summary shapes can be rendered by templates that are specialized by content type and by display type. That covers most cases of list customization.
In a few rare cases though, you'll want to simply take over the rendering of a specific list completely.
In my LIDNUG demo last Monday, I had changed the item summary template so that my blog post summaries would show a little richer than the default template:
This caused the recent posts widget to also change appearance, and not in a good way, because it's using the same default summary template:
All we really want in there is a link to the post. At this point, I could have changed the code of the widget so that it would use a different display type, or I could just take over rendering. I opted for the latter. Let's look at the Parts.Blogs.RecentBlogPosts.cshtml template that I put into my theme's Views folder…
The template is extremely simple once you've got hold of the list of posts. The code for this is a little weird, admittedly:
IEnumerable<object> blogPosts = Model.ContentItems.ContentItems;
Model here is the widget's shape. It has a ContentItems property, which really is a List shape. The list shape itself has a ContentItems property and that last one is the actual list of blog posts. Once we have this, we just need to loop over the posts and display a simple link for each of them:
<ul class="content-items"> @foreach (dynamic post in blogPosts) { string title = post.Title; ContentItem item = post.ContentItem; <li class="content-item-summary">
@Html.ItemDisplayLink(title, item)
</li> } </ul>
Here's the full template code:
@using Orchard.ContentManagement; @{ IEnumerable<object> blogPosts =
Model.ContentItems.ContentItems; } @if (blogPosts == null || blogPosts.Count() < 1) { <p>@T("No posts.")</p> } else { <ul class="content-items"> @foreach (dynamic post in blogPosts) { string title = post.Title; ContentItem item = post.ContentItem; <li class="content-item-summary">
@Html.ItemDisplayLink(title, item)
</li> } </ul> }
And here's the result:
I hope this helps.