10

I have a Razor Template where I need to order a list of component links by a particular field in descending order (Fields.Date). Normally when I want to loop through a list I would just do something like the below:

@foreach(dynamic item in Fields.Articles)
{
    //do something here
}

However the problem I am faced with is I need to sort the data before going into the loop and then write out the fields. Looking at the Razor Mediator documentation I can use List ComponentModel but I'm not sure what properties I can use?

@using Tridion.Extensions.Mediators.Razor.Models;

@{
    List<ComponentModel> articleList = Fields.Articles;
}

I was hoping I would be able to do something like articleList.OrderByDescending(...).

Can anyone point me in the right direction please?

3
  • 3
    Did you already include System.Linq? That would give you OrderByDescending and other methods like that. If that didn't work for you, could you elaborate on the issue? Mar 21, 2013 at 10:37
  • Thanks Peter, yes I have System.Linq I have tried adding articleList.OrderByDescending(x => x.Fields.Articles.Date) - can I do this considering Articles is a list of component links? I don't get any errors but to test if this works I need to write out my results. I assumed I could do this articleList.Title, articleList.Date, articleList.Body and so on? Mar 21, 2013 at 10:44
  • 2
    Pretty sure this isn't going to work, as you can't use lambda expressions over dynamic types.
    – richeym
    Mar 21, 2013 at 10:54

2 Answers 2

5

I'm assuming based on your code and comments that you are attempting to do something along the lines of:

(I modified the code a little to what the LINQ statement should look like, assuming that Fields.Articles is a list of Component Links, and each of those Components contains a field with Xml Name of "Date").

@using System.Linq;
@using Tridion.Extensions.Mediators.Razor.Models;

@{
    List<ComponentModel> articleList = Fields.Articles;
    articleList.OrderByDescending(x => x.Fields.Date);
}

@foreach (var article in articleList) { ... }

The reason that you are not seeing any error and that the list is not sorting is because OrderByDescending returns a new sorted list... it doesn't alter the original list. For your sample to work, you'd have to create one more list:

@{
    List<ComponentModel> articleList = Fields.Articles;
    var orderedList = articleList.OrderByDescending(x => x.Fields.Date);
}

You can then loop through your orderedList and it would be descending by date as expected.

A shorter version of the above using casting and creating less variables would be:

@{
    var articleList = ((List<ComponentModel>)Fields.Articles).OrderByDescending(x => x.Fields.Date);
}

Hope that helps!

3
  • I'm not sure that this will work - I have had trouble in the past using extension methods from System.Linq in Razor templates, without using them as a static method of Enumerable as detailed in my answer.
    – Ant P
    Mar 21, 2013 at 13:40
  • Hi, do you remember the error or issue you were having? We currently do something very similar to what the OP is trying to do on my current project (sorting a bunch of articles on a page), as well as pretty extensive use of other LINQ statements. The code in my code last block is almost identical to what we are using on one of our templates.
    – Alex Klock
    Mar 21, 2013 at 14:03
  • As I recall it was a simple List has no method Take on doing a list.Take(int n) after @using System.Linq. Doing Enumerable.Take(list, n) instead resolved the issue.
    – Ant P
    Mar 21, 2013 at 18:34
3

I seem to recall that the Razor Mediator has problems with extension methods. This means that, in order to use OrderByDescending and other Linq extensions, you'd have to do something like:

@ {
    using System.Linq;

    List<ComponentModel> articleList =
        Enumerable.OrderByDescending(Fields.Articles, x => x.FieldToSort).ToList();
}

@foreach(var article in articleList)
{
    <h2>@article.Fields.Title</h2>
    <p>@article.Fields.Summary</h2>
    ...
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.