Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Rob 27 posts 129 karma points
    Feb 03, 2019 @ 22:36
    Rob
    0

    Blog Posts sorting oldest first.

    I tried to find the right answer first but had no luck.

    I am working on a website using the Starter Kit of Umbraco in V7 For some reason, it sorts the blog posts using oldest first, while I want to get the newest posts first in the list view using Partial View Macro 'GetLatestBlogPosts'

    Here is the code I'm currently using for the Partial View Macro:

    @using ContentModels = Umbraco.Web.PublishedContentModels;
    

    @using Umbraco.Web; @inherits Umbraco.Web.Macros.PartialViewMacroPage @{ var startNodeId = Model.MacroParameters["startNodeId"] != null ? Model.MacroParameters["startNodeId"] : Model.Content.Id; var numberOfPosts = 3; if (Model.MacroParameters["numberOfPosts"] != null) { int.TryParse((string)Model.MacroParameters["numberOfPosts"], out numberOfPosts); }

    } @if (startNodeId != null) { @* Get the starting page *@ var startNode = Umbraco.TypedContent(startNodeId); //Gets all blogposts to calculate pages var blogposts = startNode.Children.OrderByDescending(x => x.GetPropertyValue("PublicationDate")).ToList(); var pageCount = (int)Math.Ceiling((double)blogposts.Count / (double)numberOfPosts); //gets the page from the querystring and sets it to one if it is out of range var page = 1; if (!string.IsNullOrEmpty(Request.QueryString["page"])) { int.TryParse(Request.QueryString["page"], out page); if (page <= 0 || page > pageCount) { page = 1; } } //Gets the blogposts for the current page var pagedBlogposts = blogposts.Skip((page - 1) * numberOfPosts).Take(numberOfPosts).ToList();

    if (pagedBlogposts.Count > 0)
    {
        <div class="blogposts">
    
            @foreach (ContentModels.Blogpost post in pagedBlogposts)
            {
                <a href="@post.Url" class="blogpost">
                    <div class="blogpost-meta">
                        <small class="blogpost-date">@post.CreateDate.ToLongDateString()</small>
                        <small class="blogpost-cat">
                            @Html.Partial("~/Views/Partials/CategoryLinks.cshtml", post.Categories)
                        </small>
                    </div>
    
                    @if(post.FeaturedImage != null){
                    <div class="blogpost-image">
                        <img class="img-responsive" src="@post.FeaturedImage.Url?width=200" alt="@post.PageTitle" style="width: 100%; height: 100%;"/>
                    </div>
                    }
                    <h3 class="blogpost-title">@post.PageTitle</h3>
                    <div class="blogpost-excerpt">@post.Excerpt</div>
                </a>
            }
        </div>
    }
    
    if (blogposts.Count > numberOfPosts)
    {
        <div class="pagination">
            <nav class="nav-bar nav-bar--center">
                @if (page <= 1)
                {
                    <span class="nav-link nav-link--black nav-link--disabled">Prev</span>
                }
                else
                {
                    <a class="nav-link nav-link--black" href="@(Model.Content.Url + "?page=" + (page - 1))">Prev</a>
                }
    
                @for (int i = 1; i <= pageCount; i++)
                {
                    <a class="nav-link nav-link--black @(page == i ? "nav-link--active" : null)" href="@(Model.Content.Url + "?page=" + i)">@i</a>
                }
                @if (page == pageCount)
                {
                    <span class="nav-link nav-link--black nav-link--disabled">Next</span>
                }
                else
                {
                    <a class="nav-link nav-link--black" href="@(Model.Content.Url + "?page=" + (page + 1))">Next</a>
                }
    
            </nav>
        </div>
    }
    

    }

    I am completely stuck. Tried some things but all I try is going to break the site. Would really appreciate some help here to get this sorted in the desired way.

    Thanks a lot for some guidance and assistance

  • Nik 1614 posts 7260 karma points MVP 7x c-trib
    Feb 04, 2019 @ 09:15
    Nik
    0

    Hi Robert,

    Looking at the code you've posted I'm noticing two things....

    The first is that you are sorting by the "PublicationDate" property, and then the second is that you are outputting the "CreateDate" property to screen.

    Because you are outputting a different date to the date you are sorting by, how have you verified that the ordering is incorrect?

    Have you confirmed that there is a "PublicationDate" property on the blog post document type?

    Thanks

    Nik

  • Rob 27 posts 129 karma points
    Feb 04, 2019 @ 12:33
    Rob
    0

    Hi Nik,

    First of all thanks for having a look.

    What I've posted is the default code from the Umbraco Starter Kit's 'LatestBlogPosts' Partial View Macro.

    I haven't changed anything o the code. I can confirm that there is no "PublicationDate" property on the doc type.

    I already tried to change that to 'CreateDate' or tried if it would work to change the sorting to ascending.

    None of the above would solve it. It appears that the posts are sorted by the sort order number they are assigned when creating the blog post in the Content section in the back end.

    But how could I use that? Any suggestions?

  • Nik 1614 posts 7260 karma points MVP 7x c-trib
    Feb 04, 2019 @ 12:57
    Nik
    1

    Hi Robert,

    I've just spun up a completely clean Umbraco 7.13.1 install and added the starter kit.

    First thing I've noticed is that the LatestBlogPosts Macro Partial View doesn't make any reference to "PublicationDate", it has the following line var blogposts = startNode.Children.OrderByDescending(x => x.CreateDate).ToList();

    Also, when the starter kit is installed, at least in my situation, the blogs all have the same CreateDate (I suspect milliseconds might be different but from what I can see they have the same date and same time) so sorting could vary slightly. However, it does appear to be showing them in the correct order.

    To test this, I waited a couple of minutes and then added my own blog post. When I visited the "Blog" page of the test site my blog that I added appeared at the top as expected.

    I'm curious, are you sure no one has modified the partial view macro code?

    For reference, this is the entire contents of the partial view file after a clean install:

    @using ContentModels = Umbraco.Web.PublishedContentModels;
    @using Umbraco.Web;
    @inherits Umbraco.Web.Macros.PartialViewMacroPage
    @{
        var startNodeId = Model.MacroParameters["startNodeId"] != null ? Model.MacroParameters["startNodeId"] : Model.Content.Id;
        var numberOfPosts = 3;
        if (Model.MacroParameters["numberOfPosts"] != null)
        {
            int.TryParse((string)Model.MacroParameters["numberOfPosts"], out numberOfPosts);
        }
    }
    @if (startNodeId != null)
    {
        @* Get the starting page *@
        var startNode = Umbraco.TypedContent(startNodeId);
        //Gets all blogposts to calculate pages
        var blogposts = startNode.Children.OrderByDescending(x => x.CreateDate).ToList();
        var pageCount = (int)Math.Ceiling((double)blogposts.Count / (double)numberOfPosts);
        //gets the page from the querystring and sets it to one if it is out of range
        var page = 1;
        if (!string.IsNullOrEmpty(Request.QueryString["page"]))
        {
            int.TryParse(Request.QueryString["page"], out page);
            if (page <= 0 || page > pageCount)
            {
                page = 1;
            }
        }
        //Gets the blogposts for the current page
        var pagedBlogposts = blogposts.Skip((page - 1) * numberOfPosts).Take(numberOfPosts).ToList();
    
        if (pagedBlogposts.Count > 0)
        {
            <div class="blogposts">
    
                @foreach (ContentModels.Blogpost post in pagedBlogposts)
                {
                    <a href="@post.Url" class="blogpost">
                        <div class="blogpost-meta">
                            <small class="blogpost-date">@post.CreateDate.ToShortDateString()</small>
                            <small class="blogpost-cat">
                                @Html.Partial("~/Views/Partials/CategoryLinks.cshtml", post.Categories)
                            </small>
                        </div>
                        <h3 class="blogpost-title">@post.PageTitle</h3>
                        <div class="blogpost-excerpt">@post.Excerpt</div>
                    </a>
                }
            </div>
        }
    
        if (blogposts.Count > numberOfPosts)
        {
            <div class="pagination">
                <nav class="nav-bar nav-bar--center">
                    @if (page <= 1)
                    {
                        <span class="nav-link nav-link--black nav-link--disabled">Prev</span>
                    }
                    else
                    {
                        <a class="nav-link nav-link--black" href="@(Model.Content.Url + "?page=" + (page - 1))">Prev</a>
                    }
    
                    @for (int i = 1; i <= pageCount; i++)
                    {
                        <a class="nav-link nav-link--black @(page == i ? "nav-link--active" : null)" href="@(Model.Content.Url + "?page=" + i)">@i</a>
                    }
                    @if (page == pageCount)
                    {
                        <span class="nav-link nav-link--black nav-link--disabled">Next</span>
                    }
                    else
                    {
                        <a class="nav-link nav-link--black" href="@(Model.Content.Url + "?page=" + (page + 1))">Next</a>
                    }
    
                </nav>
            </div>
        }
    }
    

    (This can also be seen on the GitHub repository for the starter kit: https://github.com/umbraco/The-Starter-Kit/blob/master/src/Umbraco.SampleSite.Website/Views/MacroPartials/LatestBlogposts.cshtml )

    I'm curious as to if something else has interfered with your install/views resulting in you not seeing the expected behaviour?

    Thanks

    Nik

  • Rob 27 posts 129 karma points
    Feb 04, 2019 @ 21:07
    Rob
    0

    Hi Nik,

    Thanks a lot for sharing that. You are right, some differences in the code are there. That might be due to a friend helped me earlier to get the thumbnail images on the Latest Blog Posts using the Featured Image property I added to the doctype.

    I have just changed one partial line of code to the default code you shared from your clean installation.

    var blogposts = startNode.Children.OrderByDescending(x => x.CreateDate).ToList();
    

    Have added a test blog post to verify it is sorting by creation date in desc order.

    Only thing now is that I, of course, would like to get them sorted by date published instead.

  • Nik 1614 posts 7260 karma points MVP 7x c-trib
    Feb 04, 2019 @ 21:44
    Nik
    1

    Hi Robert,

    There is an UpdatedDate (I think) property that you could use which relates to the last time the document was published.

    However, what I would do is add a Date property onto the document type called "ArticleDate" or "PostDate" so you can assign a specific date to an article. The reason I would do this is because do you really want a 2 week old post suddenly appearing at the top when you've just had to fix a typo you've noticed?

    I never use the CreatedDate or the UpdatedDate for sorting for this reason :-)

    Just some food for thought.

    Nik

  • Rob 27 posts 129 karma points
    Feb 04, 2019 @ 21:51
    Rob
    0

    Hi Nik,

    That sounds like a proposal worth consideration.

    I would not use the updated date to sort the blog posts though.

    Implementing a date property could give what i am looking for.

    Will have a thought about that.

    Wishing you a good night for now ;)

  • Rob 27 posts 129 karma points
    Feb 04, 2019 @ 22:12
    Rob
    0

    Hi Nik,

    However, what I would do is add a Date property onto the document type called "ArticleDate" or "PostDate" so you can assign a specific date to an article.

    How would I then modify the code in the Partial View Macro?

    I tried var blogposts = startNode.Children.OrderByDescending(x => x.GetPropertyValue("ArticleDate")).ToList();

    Which doesn't work.

  • Nik 1614 posts 7260 karma points MVP 7x c-trib
    Feb 04, 2019 @ 22:39
    Nik
    1

    Hi Robert,

    Assuming you called the Property Article Date, it's alias would be articleDate.

    So to access it you'd do:

    var blogposts = startNode.Children.OrderByDescending(x=> x.GetPropertyValue<DateTime>("articleDate")).ToList();
    

    Thanks

    Nik

  • Rob 27 posts 129 karma points
    Feb 05, 2019 @ 08:43
    Rob
    0

    Hi Nik,

    I tried the following code as I'm using a date picker only:

    var blogposts = startNode.Children.OrderByDescending(x=> x.GetPropertyValue<Date>("articleDate")).ToList();
    

    That is causing a compiler error stating that the namespace name or Type "Date" is not found

    Sorry for all the hassle, as you surely can tell I am not a developer, just a newbie trying to build a website for my wife and her blog project

  • Nik 1614 posts 7260 karma points MVP 7x c-trib
    Feb 05, 2019 @ 08:59
    Nik
    100

    Hi Robert,

    In .Net there is no Date class, even the date picker stores data as a DateTime due to the classes that exist in .Net.

    I completely understand not being a developer and not being aware of this, give it a try specifying DateTime instead of Date and let me know how you get on :-)

    Thanks

    Nik

  • Rob 27 posts 129 karma points
    Feb 05, 2019 @ 11:18
    Rob
    0

    Hi Nik,

    Super. I changed the code that way and recognised one more thing that I wasn't aware of:

     @foreach (ContentModels.Blogpost post in pagedBlogposts)
            {
                <a href="@post.Url" class="blogpost">
                    <div class="blogpost-meta">
                        <small class="blogpost-date">@post.ArticleDate.ToLongDateString()</small>
    

    I still had

    @post.CreateDate.ToLongDateString()

    instead of @post.ArticleDate.ToLongDateString

    Now it's working perfectly.

    Thanks a lot for all your help and patience.

    Best Robert

  • Nik 1614 posts 7260 karma points MVP 7x c-trib
    Feb 05, 2019 @ 11:22
    Nik
    1

    Hi Robert,

    Absolutely no problem, pleased you've managed to get it all working :-)

    Thanks

    Nik

Please Sign in or register to post replies

Write your reply to:

Draft