Copied to clipboard

Flag this post as spam?

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


  • k 256 posts 654 karma points
    May 28, 2019 @ 06:30
    k
    0

    Previous() /Next() + Umvbraco 8

    Hello,

    Is Previous() and Next() still valid on Umbraco 8 ?

  • Rhys Hamilton 140 posts 942 karma points
    May 30, 2019 @ 11:30
    Rhys Hamilton
    0

    As far as I can tell, these extension methods are no longer available in Umbraco V8 (at least not on IPublishedContent).

    I've noticed you've posted a few times about extension methods - so it might be worthwhile to look at the PublishedContentExtensions class on Umbraco's Github, to give you a better idea of what's changed since V7 - which you can find here.

  • k 256 posts 654 karma points
    Jun 24, 2019 @ 16:56
    k
    0

    Hello Rhys,

    Will they be available afterwards ?

  • Bjarne Fyrstenborg 1285 posts 4039 karma points MVP 8x c-trib
    Jun 24, 2019 @ 17:49
    Bjarne Fyrstenborg
    0

    Some of the extension methods in v7 has not been included in v8: https://github.com/umbraco/Umbraco-CMS/issues/4839

    But you should be able to get the same node as Previous() or Next() extension methods in v7 but using Siblings(), SiblingsOfType() or SiblingsAndSelf(): https://github.com/umbraco/Umbraco-CMS/issues/4839

    https://github.com/umbraco/Umbraco-CMS/blob/v8/dev/src/Umbraco.Web/PublishedContentExtensions.cs

    When looking at v7 source code, it used index of the specified node:

    Previous:

    https://github.com/umbraco/Umbraco-CMS/blob/v7/dev/src/Umbraco.Web/PublishedContentExtensions.cs#L1562-L1565

    Next:

    https://github.com/umbraco/Umbraco-CMS/blob/v7/dev/src/Umbraco.Web/PublishedContentExtensions.cs#L1493-L1496

    Looking at the v8 source code, this might be a workaround for the previous Previous() and Next() extension methods, e.g. in a TextPage view.

    string culture = Model.GetCulture()?.Name;
    var siblings = Model.Parent != null ? Model.Parent.Children(x => x.Id != Model.Id) : UmbracoContext.ContentCache.GetAtRoot().Where(x => !x.ContentType.VariesByCulture() || x.HasCulture(culture));
    var prev = siblings.LastOrDefault(x => x.SortOrder < Model.SortOrder);
    var next = siblings.FirstOrDefault(x => x.SortOrder > Model.SortOrder);
    

    In newer versions of Umbraco v8, it is possible to use the Siblings() extensions methods, so this can be simplified further:

    string culture = Model.GetCulture()?.Name;
    var siblings = Model.Siblings(culture);
    var prev = siblings.LastOrDefault(x => x.SortOrder < Model.SortOrder);
    var next = siblings.FirstOrDefault(x => x.SortOrder > Model.SortOrder);
    

    These might be alternative to PrecedingSibling() and FollowingSibling() extension methods as I think in v7 that Previous() extension method returned the parent node if the current node was the first child node.

    /Bjarne

  • Bjarne Fyrstenborg 1285 posts 4039 karma points MVP 8x c-trib
    Jun 25, 2019 @ 09:38
    Bjarne Fyrstenborg
    0

    An alternative which is similar to v7, where the Previous() and Next() extension method are using a GetIndex() method. https://github.com/umbraco/Umbraco-CMS/blob/v7/dev/src/Umbraco.Web/PublishedContentExtensions.cs#L634-L640

    var index = siblings.FindIndex(n => n.Id == Model.Id);
    var prev = siblings.ElementAtOrDefault(index - 1);
    var next = siblings.ElementAtOrDefault(index + 1);
    

    /Bjarne

  • Stephen 767 posts 2273 karma points c-trib
    Jun 25, 2019 @ 11:21
    Stephen
    0

    Navigating the tree is an expensive operation, and providing Previous/Next sibling navigation required some more expensive plumbing. That plumbing is gone in v8.

    Note that it was the same plumbing that provided IsOdd/IsEven and other funny helper methods.

    Depending on what you are trying to achieve... Model.Children().ToindexedArrayItem() will produce an array of items, which all have a Content property (the actual content item) and IsFirst(), IsOdd() etc helper methods. And, being an array, you can navigate with indexes.

    That's convenient and relatively cheap, when you're trying to do IsOdd/IsEven when styling a grid, or things like that.

    For anything more complex, using Siblings, as suggested, would be the way to go - but what would be the use case exactly?

  • Bjarne Fyrstenborg 1285 posts 4039 karma points MVP 8x c-trib
    Jun 25, 2019 @ 11:53
    Bjarne Fyrstenborg
    0

    Hi Stephen

    In Umbraco v7 you might have a checkout in a webshop with the following tree structure, where Previous() and Next() was useful.

    • HomePage
      • Products
      • About
      • Contact
      • Basket
        • Billing
        • Shipment
        • Payment
        • Confirmation

    Checkout could use a "Checkout" master templaten, and in this you might have a "Breadcrumb" partial and in v7 have something like this to navigate betweeen the steps (siblings).

    If current node was the first child node, it seems Previous() returned the parent node, so on "Billing" step it would return "Basket" node.

    var prevStep = Model.Content.Previous();
    var nextStep = Model.Content.Next();
    

    You can probably do something similar in v8 using .Parent.FirstChild(), .Parent.Children() or .Siblings() (added in v8.1.0: https://our.umbraco.com/download/releases/810)

    /Bjarne

  • k 256 posts 654 karma points
    Jun 25, 2019 @ 16:35
    k
    100

    The below is working on umbraco 8:

      @{
    
          var newsList = Model.Parent.Children("alias").ToList();
            var currentIndexInNewsList = newsList.FindIndex(x => x.Id.Equals(Model.Id));
           var  totalResults = newsList.Count();
    
            if (currentIndexInNewsList > -1)
                    {
    
                     if (currentIndexInNewsList > 0)
                        {
                            var previousItem = newsList[currentIndexInNewsList - 1]; 
                            <div class="col-xl-6 col-lg-6 col-sm-12 prevFooter">
                                    <a href="@previousItem.Url"><span><i class="fas fa-arrow-left"></i></span>Previous Project</a>
                                </div>
    
                        }   
                        if (totalResults-1 > currentIndexInNewsList)
                        {
                            var nextItem = newsList[currentIndexInNewsList + 1];
                             <div class="col-xl-6 col-lg-6 col-sm-12 nextFooter">
                                <a href="@nextItem.Url"><span></span>Next Project</a>
                            </div>
    
                        }
    
    
        }
    

    }

  • Bjarne Fyrstenborg 1285 posts 4039 karma points MVP 8x c-trib
    Jun 26, 2019 @ 06:54
    Bjarne Fyrstenborg
    1

    You don't need to use .ToList() on the IEnumerable<IPublishedContent>> collection.

    var newsList = Model.Parent.Children("alias");
    var currentIndexInNewsList = newsList.FindIndex(x => x.Id == Model.Id);
    var totalResults = newsList.Count();
    

    Then use the following to get previousItem and nextItem:

    var previousItem = newsList.ElementAtOrDefault(currentIndexInNewsList - 1);
    var nextItem = newsList.ElementAtOrDefault(currentIndexInNewsList + 1);
    

    /Bjarne

  • Richard Hamilton 36 posts 158 karma points
    May 29, 2020 @ 12:20
    Richard Hamilton
    0

    UMBRACO 8.x Before finding this thread, I knocked together this for BlogPosts:

    var prevPost = Model.SiblingsOfType(Blogpost.ModelTypeAlias).OrderBy(x => new Blogpost(x).PublishedDate).Where(x => new Blogpost(x).PublishedDate >= Model.PublishedDate).Take(1).FirstOrDefault();
    var nextPost = Model.SiblingsOfType(Blogpost.ModelTypeAlias).OrderByDescending(x => new Blogpost(x).PublishedDate).Where(x => new Blogpost(x).PublishedDate <= Model.PublishedDate).Take(1).FirstOrDefault();
    

    Does the job, not sure how the performance compares.

    Could be simplified if you were using CreatedDate instead of your own date.

Please Sign in or register to post replies

Write your reply to:

Draft