Is there any way to get the descedant nodes by their actual sort order? :-) I know I could just order the nodes by their Id, createDate or updateDate, but it doesn't make sense since it's news items.
to explain fully I was having the same issue as Bo but the pages in question were people profiles.
Within umbraco the nodes were ordered like so:
People - Management Team - - Person 1 - - Person 2 - - Person 3 - Training Team - - Person 4 - - Person 5 - - Person 6 - Admin Team - - Person 7 - - Person 8 - - Person 9
When listed on the page using SortOrder they listed like so:
Person 1 Person 4 Person 7 Person 2 Person 5 Person 8 Person 3 Person 6 Person 9
This is not how I was expecing them to layout. The SortOrder is a local value for the current folder and the values work out as follows:
People : SortOrder = 1 - Management Team : SortOrder = 1 - - Person 1 : SortOrder = 1 - - Person 2 : SortOrder = 2 - - Person 3 : SortOrder = 3 - Training Team : SortOrder = 2 - - Person 4 : SortOrder = 1 - - Person 5 : SortOrder = 2 - - Person 6 : SortOrder = 3 - Admin Team: SortOrder = 3 - - Person 7 : SortOrder = 1 - - Person 8 : SortOrder = 2 - - Person 9 : SortOrder = 3
I had to use a sort as I was using a pre-built C# pager that required a sort to be passed and it would default to SortOrder if no sort had been passed. To get around this I used the SortOrder of the parents first and then as a second sort I used the SortOrder of the people nodes.
Thank you for you answer, I asume its a good workaround for others, but I still having difficalt with this because Im using a paging for this big list of Descendants which I want to sort, so I cant group it and loop every group apart.
my tree looks a little different:
Folder
-Folder
--children 1
--children 2
--children 3
-children 4
-children 5
...
I want all childrens to sort like the logic sort order, so I have liste the by Descendants("DocumentType") and sorted them. And then get the sort issue.
If you go direct to the level you should get the order from the front end,
var blob = Model.Content.AncestorsOrSelf(1).Descendants(3).Where("Visible");
then @foreach (var item in blob.OrderBy("Person or whatever you need - if you do not add orderBy it will give you tree order"))
{ @item.Person }
This will give all children on the level you require, you may have to play with it as I cannot see your whole tree, if you have other descendants elsewhere on that level you can add a blob.Where("DocTypeAlias ==("the one you want")") or something very similar
var category = Model.Content.AncestorsOrSelf("category");
var products = category.Descendants();
var subProduct = products("subCategory").Children();
@{
foreach var product in products
{ if category.Down(1).IsdocTypeAlias("subCategory")
{ foreach var subCategoryProduct in subProduct
@subCategoryProduct.Url
}
else{
@product.Url
}
}
this is the logic that should get you that list and will not include the parent node in the subcategory - this is all of course version dependent, so best to run through it with intellisense, or just use straight == for docTypeAlias or whichever way you are more comfortable.
or you could use if product.docTypeAlias == subCategory loop children either way this will take each descendant node in turn, then if it has children list them, if not, will just list that node, this should give you the logical order.
Your solution doesnt sorts any list, it just looping the childrens of each level. As i mentioned I'm trying to sort 1 list of items from two different levels.
I am not using Dynamic Razor and I am not very well versed with Dynamic Razor either.
You can see how I am getting the parent sort order form my example bellow. The OrderBy Lambada statment is selecting the parent of the current item.I know this is not what you are looking for but I belive it might be of use to others that have the same issue.
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage @{ var node = Umbraco.AssignedContentItem; var people = node.Descendants("PersonProfile").Where(x => x.IsVisible()).OrderBy(x => x.Parent.SortOrder ); } @foreach (var person in people) {
Why do you want to use the DynamicNode syntax? Does the your version of Umbraco not support the syntax Peter showed?
I can answer your question, but I need to know:
Can you use the "normal" syntax rather than the DynamicNode syntax?
This is important because the normal syntax supports lambdas, which allow you to order by more complicated expressions.
Can you store some of the results in intermediate data structures (e.g., a list or dictionary)?
This is important if you can't use lambdas in the normal syntax. The alternative would be to store results and loop over them a couple times.
By the way, after reading through this thread in more detail, I realized my above solution will not work for you due to the fact that you have products at multiple levels (i.e., some under subcategories and some under categories).
Actualy I'm not sure why, I just use to use this syntex and have no expirience with the lambada, and when I use the lambada syntex the VS intellisence says:
"Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type".
My Code looks like this:
@inherits umbraco.MacroEngines.DynamicNodeContext
@{//that macro gets a ProductsFolder and ProductsPerPage as Parameters, and display that folder items by paging.
var productsFolder = Parameter.productsFolder; // Chosen folder Id
var tempNode = Library.NodeById(productsFolder); // Temporary Node of the folder
int NumberOfItemsPerPage = Convert.ToInt32(Parameter.productsPerPage); // Number of Items to display in every page
var productsFolderDescendants = tempNode.Descendants("ProductItem").Where("Visible").OrderBy("sortOrder desc");
...
If I replace this OrderBy with lambada syntex I get the error...
The code from that page I'm thinking you'll need is this:
UmbracoHelper _helper = new UmbracoHelper(UmbracoContext.Current);
var newModel = _helper.TypedContent(blogParentNode.Id);
From there, you should be able to use the methods that make use of lambdas (I think). Also note that some of the code at that page is part of uBlogsy, so don't let that confuse you. Also, you may or may not need to import a few namespaces to access UmbracoHelper, UmbracoContext, and the extension methods on IPublishedContent (such as Descendants).
Glad to say it done! thanks to your direction.
I hade to switch to partial view macro and update a lot of the code, but it was the right way to the solution.
Descendant nodes and OrderBy SortOrder
Hi all,
I'm having a bit of trouble sorting descendant nodes by their sortOrder property.
If I have the following content structure:
If I want the descendants nodes of type "NewsItem" like this (Model being the "News" node):
the DynamicNodeList will look like this:
Is there any way to get the descedant nodes by their actual sort order? :-) I know I could just order the nodes by their Id, createDate or updateDate, but it doesn't make sense since it's news items.
Thanks in advance.
All the best,
Bo
Hi Bo
You want the order that you have them in, ie the way they appear in the tree?
If you just leave it blank, should work;
Loop on that and it will give by sort order - just to make sure move a couple and check, but should be ok.
Regards G
I have come across this issue too. I am using a pager so just using the below code will not work.
It seems that the SortOrder of the nodes is baised on the parent node.
The real sort order is as follows.
This means theu will be listed incorrectly.
Hi Peter
What are you wanting to achieve? Do you want them to be in date order?
I'm a little confused so can you post what it is you want and we should be able to work a solution
Cheers
gary
Hi Gary,
Sorry for very delayed reply.
I found a work around to this issue.
to explain fully I was having the same issue as Bo but the pages in question were people profiles.
Within umbraco the nodes were ordered like so:
People
- Management Team
- - Person 1
- - Person 2
- - Person 3
- Training Team
- - Person 4
- - Person 5
- - Person 6
- Admin Team
- - Person 7
- - Person 8
- - Person 9
When listed on the page using SortOrder they listed like so:
Person 1
Person 4
Person 7
Person 2
Person 5
Person 8
Person 3
Person 6
Person 9
This is not how I was expecing them to layout. The SortOrder is a local value for the current folder and the values work out as follows:
People : SortOrder = 1
- Management Team : SortOrder = 1
- - Person 1 : SortOrder = 1
- - Person 2 : SortOrder = 2
- - Person 3 : SortOrder = 3
- Training Team : SortOrder = 2
- - Person 4 : SortOrder = 1
- - Person 5 : SortOrder = 2
- - Person 6 : SortOrder = 3
- Admin Team: SortOrder = 3
- - Person 7 : SortOrder = 1
- - Person 8 : SortOrder = 2
- - Person 9 : SortOrder = 3
I had to use a sort as I was using a pre-built C# pager that required a sort to be passed and it would default to SortOrder if no sort had been passed.
To get around this I used the SortOrder of the parents first and then as a second sort I used the SortOrder of the people nodes.
That resolved the issue I was having.
Thanks
Hi Peter,
Just expirienced the same problem.
May I ask for your code for the workaround? because I cant figure out how should I relate their parent sortOrder?
This is my code:
var productsFolderDescendants = tempNode.Descendants("ProductItem").Where("Visible").OrderBy("sortOrder desc");
How would you would make them sort by their parent sortOrder?
Hi AvihayBit
You can use .GroupBy(), so using Peters example above
var blob = Model.Content.AncestorsOrSelf(1).Descendants("teamNode").GroupBy("TeamNode");
then @foreach (var item in blob.OrderBy("Person"))
{ @item.Person }
To expalain, use GroupBy on your parent node, then foreach on the children and you should get your result.
There is info in the wiki on groupBy which I have used so know it is ok.
Hope this helps
Gary
If you get stuck I have some working code that I can post.
Hi Gary,
Thank you for you answer, I asume its a good workaround for others, but I still having difficalt with this because Im using a paging for this big list of Descendants which I want to sort, so I cant group it and loop every group apart.
my tree looks a little different:
Folder
-Folder
--children 1
--children 2
--children 3
-children 4
-children 5
...
I want all childrens to sort like the logic sort order, so I have liste the by Descendants("DocumentType") and sorted them. And then get the sort issue.
Any new Idea but groups?
Hi
That paging issue again, ok.
If you go direct to the level you should get the order from the front end,
var blob = Model.Content.AncestorsOrSelf(1).Descendants(3).Where("Visible");
then @foreach (var item in blob.OrderBy("Person or whatever you need - if you do not add orderBy it will give you tree order"))
{ @item.Person }
This will give all children on the level you require, you may have to play with it as I cannot see your whole tree, if you have other descendants elsewhere on that level you can add a blob.Where("DocTypeAlias ==("the one you want")") or something very similar
Hope this helps more
Gary
Hi
All the problem started because Im trying to sort a list from two different levels. Like all the previous posts here.
What you suggests sorting only one level...
lets say its the whole tree:
Catalog
- Category
- - SubCategory
- - - Product 1
- - - Product 2
- - - Product 3
- - Product 4
- - Product 5
I want the products in one list (for paging) that sorts like the above tree...
BUT sortOrder cat give me this wish because Products 1-3 is in a different level of 4-5...
ok
var category = Model.Content.AncestorsOrSelf("category");
var products = category.Descendants();
var subProduct = products("subCategory").Children();
@{
foreach var product in products
{ if category.Down(1).IsdocTypeAlias("subCategory")
{ foreach var subCategoryProduct in subProduct
@subCategoryProduct.Url
}
else{
@product.Url
} }
this is the logic that should get you that list and will not include the parent node in the subcategory - this is all of course version dependent, so best to run through it with intellisense, or just use straight == for docTypeAlias or whichever way you are more comfortable.
or you could use if product.docTypeAlias == subCategory loop children either way this will take each descendant node in turn, then if it has children list them, if not, will just list that node, this should give you the logical order.
Regards
Gary
Hi Gary,
Thank you, but its not the solution I'm after.
Your solution doesnt sorts any list, it just looping the childrens of each level. As i mentioned I'm trying to sort 1 list of items from two different levels.
Thanks again for trying :)
Avihay
Hi Avihay,
I am not using Dynamic Razor and I am not very well versed with Dynamic Razor either.
You can see how I am getting the parent sort order form my example bellow. The OrderBy Lambada statment is selecting the parent of the current item.I know this is not what you are looking for but I belive it might be of use to others that have the same issue.
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
var node = Umbraco.AssignedContentItem;
var people = node.Descendants("PersonProfile").Where(x => x.IsVisible()).OrderBy(x => x.Parent.SortOrder );
}
@foreach (var person in people) {
@person.Name
}
Thanks,
Pete
If that doesn't work quite right, this may work too:
Thanks You Peter and Nicholas,
Nicholas- your code looks like the exact way for the solution but I cant figure out how to change it to the DynamicNode syntex...
If anyone know how to 'translate' that it would be really helpfull...
Hi AvihayBit,
Why do you want to use the DynamicNode syntax? Does the your version of Umbraco not support the syntax Peter showed?
I can answer your question, but I need to know:
By the way, after reading through this thread in more detail, I realized my above solution will not work for you due to the fact that you have products at multiple levels (i.e., some under subcategories and some under categories).
Hi Nicholas,
Actualy I'm not sure why, I just use to use this syntex and have no expirience with the lambada, and when I use the lambada syntex the VS intellisence says:
"Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type".
My Code looks like this:
If I replace this OrderBy with lambada syntex I get the error...
Its a webform project if its changes anything.
Thanks!!
I have to sleep, so I can't dig into this right now. But basically I'm thinking you can convert your dynamic node stuff into an IPublishedContent and go from there. Refer to this page: http://our.umbraco.org/projects/starter-kits/ublogsy/ublogsy-razor-blog/46773-Error-on-ToIPublishedContent(true)
The code from that page I'm thinking you'll need is this:
From there, you should be able to use the methods that make use of lambdas (I think). Also note that some of the code at that page is part of uBlogsy, so don't let that confuse you. Also, you may or may not need to import a few namespaces to access UmbracoHelper, UmbracoContext, and the extension methods on IPublishedContent (such as Descendants).
If you want to learn more about UmbracoHelper, you can start here: http://our.umbraco.org/documentation/Reference/Querying/UmbracoHelper/
Of particular note is this sentence from that link:
So I guess that means you can use UmbracoHelper even though you are using WebForms.
Hi Nicholas,
Glad to say it done! thanks to your direction. I hade to switch to partial view macro and update a lot of the code, but it was the right way to the solution.
Thanks again!!
is working on a reply...