How do I render the various parts (like tags) of a blog post?

Topics: Customizing Orchard, Writing themes
May 12, 2011 at 7:44 PM

I'm trying to render the list of blog posts in this layout:

[first post - special summary]
[second post][third post][fourth post]
[pager]

I'm trying to render the first post myself and then loop over the remaining items to render them using the blog post summary template.

A number of questions here:

  1. Is this a good way to pull off the layout I'm trying to achieve or should I start looking into creating a module?
  2. Should I create a summary template for my special first post rendering and how would I go about that?
  3. If I continue down the same path how do I render parts like tags and the postdate?

I have this so far in my theme: Parts.Blogs.BlogPost.List-url-blog.cshtml

@using Orchard.Blogs.Extensions;
@using Orchard.Blogs.Models;
@using Orchard.ContentManagement;
@using Orchard.Utility.Extensions;
@{
    IEnumerable<dynamic> blogPosts = Model.ContentItems;
    Model.ContentItems.Classes.Add("content-items");
    Model.ContentItems.Classes.Add("blog-posts");

    var firstPost = blogPosts.FirstOrDefault();
    //BlogPart blog = (BlogPart)firstPost.Get(typeof(BlogPart));

}
<h1>@firstPost.Title</h1>
by <span>@firstPost.ContentItem.CommonPart.Owner.NormalizedUserName</span>

@* How do i render tags using the tags part template? *@

@Display(firstPost.Tags) 
@Display(firstPost.Parts_Tags_ShowTags)
@Display(firstPost.TagsPart) 
@Display(firstPost.ContentItem.TagsPart)
@Display(firstPost.ContentItem.TagsPart.ContentItem)

@* none of the above work *@

<hr />
<ul class="content-items">
    @foreach (var post in blogPosts.Skip(1))
    {
        <li class="content-item-summary">
            @Display(post)
        </li>
    }
</ul>

Bonus points - Why can't I do something like this:

@Display(blogPosts.Skip(1))

but I can do

@Display(blogPosts)
Coordinator
May 12, 2011 at 8:29 PM

For the bonus points, did you try .ToList() after the Skip?

I think you are on the right track overriding the list template, but I think what you want to do is change the display type for the first item to replace the default one (Summary). You should then be able to create specialized placement for it.

May 12, 2011 at 8:32 PM

I did (if memory serves). I tried a number of things. .ToList() was one of them. My workaround is just to render the list myself. No biggie there. 

Any idea on the tags question? 

Coordinator
May 12, 2011 at 8:43 PM

What happens when you try? Nothing? Error message?

On the tags thing, I haven't looked into the details but I think you should try the placement approach I described first: statically rendering parts in the template is not recommended as it kills extensibility scenarios down the line.

May 12, 2011 at 8:59 PM
@Display(firstPost.Tags) - nothing
@Display(firstPost.Parts_Tags_ShowTags) - nothing
@Display(firstPost.TagsPart)  - nothing 
@Display(firstPost.ContentItem.TagsPart) - the text "Orchard.Tags.Models.TagsPart"
@Display(firstPost.ContentItem.TagsPart.ContentItem) - the text "Orchard.ContentManagement.ContentItem"
Coordinator
May 12, 2011 at 9:09 PM

I meant what happens when you try the skip thing.

May 12, 2011 at 9:18 PM

w/o .ToList()

Unable to cast object of type '<SkipIterator>d__4d`1[System.Object]' to type 'Orchard.DisplayManagement.Shapes.Shape'.

w/ .ToList()

the text 'System.Collections.Generic.List`1[System.Object]'

Coordinator
May 12, 2011 at 10:17 PM

Right, you'd need to make that into a list shape, with a ContentItems property that is that list. Similarly, you don't get to Display the parts directly, you'd need to ask the corresponding drivers to give you shapes. This is why you should probably consider some easier, more canonical approaches like I said above.

Dec 2, 2011 at 5:57 PM

Did u found solution for this? If so pls provide code sample

Coordinator
Dec 2, 2011 at 8:26 PM

http://weblogs.asp.net/bleroy/archive/2011/05/23/orchard-list-customization-first-item-template.aspx