I try to count items inside the embedded content datatypes by using the following script:
Model.AncestorOrSelf().footerBottomLinks.Count();
It always shows an error:
'umbraco.MacroEngines.DynamicXml' does not contain a definition for 'Count'
Any idea?
What i try to do is to loop through the items and mark the last item with a different css class. I also tried it by using .IsLast in the foreach loop but this also does not work
If you look at the XML in umbraco.config you should spot the issue with your above code - the "footerBottomLinks" actually contains a 'data' child node which itself contains an 'item' child node for each link you have defined in your footer.
Alright, I just did a quick proof of concept in v4.8.0. I do recall that the DynamicXML problem you're having was fixed in 4.7.2 so I recommend upgrading to at least that version (but why stop there, 4.8.0 is great as well).
I installed embedded content and configured it as such, note the "link" alias here:
Then, I wrote the following Razor script for it. Note that I am assuming that you want to check if the current page has any footer links, if not you want to look at the parent for footer links, then the parent's parent etc. The "link" alias returns in the line that gets the nodeId (footerBottomLink.link.InnerText):
@{
var node = Model; while (node.Level >= 1 && node.footerBottomLinks.Count() == 0) { node = node.Parent; } }
FOr me its hard to update to a newer version because everything must be checked again by our QA. Is there any workarround to get this running with umbraco 4.7.0?
It seems like @node.footerBottomLinks.Count() is not working in version 4.7.0?
Dominik, did you try using the simple foreach loop method? If you are not able to upgrade and the helper methods are unavailable, this may be the best workaround.
var count =0; foreach(dynamic item inModel.AncestorOrSelf().footerBottomLinks) { count++; }
Its a bit of a kludge but I would do one loop to make the count (as above) and then a second loop
var i = 0; foreach (dynamic item in Model.AncestorOrSelf().footerBottomLinks) { i++; var cssClass = (i == count) ? "last" : "normal"; <li class="@cssClass">@item.Name</li> }
To be quite honest I would solve this problem with jQuery usually, as I pointed out above, but this option may not be viable for you:
Sorry if I am misinterpreting what you want, but do you want to do ?
which is effecxtively what barry and Sebaastian have suggedsted I've just combined it to a bit of pseudo code to understand what you want? or are you also getting issues using the IsLast?
Ravi
var count =0; foreach(dynamic item inModel.AncestorOrSelf().footerBottomLinks) { if @footerBottomLinks.IsLast() { Do your stuff here } count++; }
So, I installed 4.7.0 and combined the solutions by Barrry and Ravi here, this works for me now (remember that in the embedded content datatype definition the links are aliassed as "link" which I'm using in @Model.NodeById(item.link)
@{
var count = 0;
foreach(dynamic item in Model.AncestorOrSelf().footerBottomLinks)
{
count++;
}
var count2 = 0;
foreach(dynamic item in Model.AncestorOrSelf().footerBottomLinks)
{
count2++;
var IsLast = count == count2;
<p>@Model.NodeById(item.link).Name - IsLast: @IsLast</p>
}
}
foreach(dynamic item in Model.AncestorOrSelf().footerLinksRight.Take(5)
and
foreach(dynamic item in Model.AncestorOrSelf().footerLinksRight.Skip(5).Take(5)
Not sure if this will work on your version as it seems a lot of the Razor stuff in 4.7.0 is buggy. Sebastiaan will test I'm sure!
By the way, please mark the post that best answered your original issue as the solution, and then create a new topic for this new issue. That will help others when searching for answers in the future. Thanks.
Skip and Take don't work, you will have to do the same trick with a counter and then inside the foreach do if (count <= 5) { // do something }
I have no other suggestion than to upgrade to 4.7.2 where all these things have been ironed out. Other than that you'll just have to be creative I'm afraid.
As i am not able to update to version 4.7.2 I tried to use this if statement but the problem is that if have to place a div outside of the foreach loop
As an example
<div class="column1">should include <ul><li>item1 - 5</li></ul></div> <div class="column2">should include <ul><li>item6 - 10</li></ul></div>
If i try to use the if statement it just checks if there are more than 5 and applies always the column2 class
Well, as said, be creative, but you're soon getting code explosion (as you can see below), hardcoded values and triple enumeration, which will start to hurt performance.
How hard would it be to sneak in ONLY 4.7.2's umbraco.MacroEngines.dll? So you would ONLY upgrade the razor implementation and nothing else, everything else will be plain old 4.7.0. If that's still impossible, you might want to keep using XSLT and start using Razor in the next site you're doing.
Will XSLT scripts work in Umbraco 5 or have i to replace all of my xslt scripts (about 40) ?
I think before i have to change all the scripts to razor we are forced to update our umbraco version otherwise I will not be able to use razor in the correct way.
In case you hadn't noticed, Umbraco v5 got pulled. There are currently no plans in the roadmap to remove XSLT from v4, so it will still keep working for a long time to come.
Count Items issue (mark last item)
Hello,
I try to count items inside the embedded content datatypes by using the following script:
Model.AncestorOrSelf().footerBottomLinks.Count();
It always shows an error:
'umbraco.MacroEngines.DynamicXml' does not contain a definition for 'Count'
Any idea?
What i try to do is to loop through the items and mark the last item with a different css class.
I also tried it by using .IsLast in the foreach loop but this also does not work
Thanks
If you look at the XML in umbraco.config you should spot the issue with your above code - the "footerBottomLinks" actually contains a 'data' child node which itself contains an 'item' child node for each link you have defined in your footer.
You could try using xPath:
Model.XPath("//footerBottomLinks/data/item").Count();
or you could count in a loop
Another solution, if you are using jQuery, is to use the last() method. So say your items are all <li>'s inside a <ul> of class 'footerlinks':
Which version of Umbraco are you using? I've just tested this on 4.8.0 and it works perfectly for me.
Hello
I am using version 4.7.0
I also tried the count in the loop but how can i use the "IsLast" helper method? I still cant get it working
I would like to reproduce, which datatype are you using for your footerBottomLinks property?
Hi Sebastian i am using EmbeddedContent Datatype
Alright, I just did a quick proof of concept in v4.8.0. I do recall that the DynamicXML problem you're having was fixed in 4.7.2 so I recommend upgrading to at least that version (but why stop there, 4.8.0 is great as well).
I installed embedded content and configured it as such, note the "link" alias here:
Then, I wrote the following Razor script for it. Note that I am assuming that you want to check if the current page has any footer links, if not you want to look at the parent for footer links, then the parent's parent etc. The "link" alias returns in the line that gets the nodeId (footerBottomLink.link.InnerText):
Hi Sebastian,
FOr me its hard to update to a newer version because everything must be checked again by our QA. Is there any workarround to get this running with umbraco 4.7.0?
It seems like @node.footerBottomLinks.Count() is not working in version 4.7.0?
Dominik, did you try using the simple foreach loop method? If you are not able to upgrade and the helper methods are unavailable, this may be the best workaround.
Hi Barry,
How can i get the last item with your foreach loop?
I can loop through all items - that works but how can i now apply a specific cssClass for the last item?
THanks
Its a bit of a kludge but I would do one loop to make the count (as above) and then a second loop
To be quite honest I would solve this problem with jQuery usually, as I pointed out above, but this option may not be viable for you:
Sorry if I am misinterpreting what you want, but do you want to do ?
which is effecxtively what barry and Sebaastian have suggedsted I've just combined it to a bit of pseudo code to understand what you want? or are you also getting issues using the IsLast?
Ravi
var count =0;
foreach(dynamic item inModel.AncestorOrSelf().footerBottomLinks)
{
if @footerBottomLinks.IsLast() {
Do your stuff here
}
count++;
}
Hi Ravi the IsLast() method does not work on 4.7.0 apparently so we wre offering some workarounds..
that was what i was double checking and making sure we hadn't missed the obvious.
So, I installed 4.7.0 and combined the solutions by Barrry and Ravi here, this works for me now (remember that in the embedded content datatype definition the links are aliassed as "link" which I'm using in @Model.NodeById(item.link)
HI Sebastian,
This works - thanks a lot
Now i got another issue
I want to create two divs. one for the first 5 items and the other for the second 5 items of the embedded content
If i try to use Where statement:
foreach(dynamic item in Model.AncestorOrSelf().footerLinksRight.Where(@i < 6)
i always get:
'umbraco.MacroEngines.DynamicXml' does not contain a definition for 'Where'
It looks like i am not allowed to use filters.
Thanks
Try
foreach(dynamic item in Model.AncestorOrSelf().footerLinksRight.Take(5)
and
foreach(dynamic item in Model.AncestorOrSelf().footerLinksRight.Skip(5).Take(5)
Not sure if this will work on your version as it seems a lot of the Razor stuff in 4.7.0 is buggy. Sebastiaan will test I'm sure!
By the way, please mark the post that best answered your original issue as the solution, and then create a new topic for this new issue. That will help others when searching for answers in the future. Thanks.
Its really hard if most of the code described in the razor cheat sheet is not working on version 4.7.0
I am not able to update to a newer version without a lot of effort but i want to change my xslt macros to razor
Any suggestions how to proceed here?
Skip and Take don't work, you will have to do the same trick with a counter and then inside the foreach do if (count <= 5) { // do something }
I have no other suggestion than to upgrade to 4.7.2 where all these things have been ironed out. Other than that you'll just have to be creative I'm afraid.
Hi Sebastian
As i am not able to update to version 4.7.2 I tried to use this if statement but the problem is that if have to place a div outside of the foreach loop
As an example
<div class="column1">should include <ul><li>item1 - 5</li></ul></div>
<div class="column2">should include <ul><li>item6 - 10</li></ul></div>
If i try to use the if statement it just checks if there are more than 5 and applies always the column2 class
Well, as said, be creative, but you're soon getting code explosion (as you can see below), hardcoded values and triple enumeration, which will start to hurt performance.
How hard would it be to sneak in ONLY 4.7.2's umbraco.MacroEngines.dll? So you would ONLY upgrade the razor implementation and nothing else, everything else will be plain old 4.7.0. If that's still impossible, you might want to keep using XSLT and start using Razor in the next site you're doing.
Thanks a lot Sebastian,
Will XSLT scripts work in Umbraco 5 or have i to replace all of my xslt scripts (about 40) ?
I think before i have to change all the scripts to razor we are forced to update our umbraco version otherwise I will not be able to use razor in the correct way.
In case you hadn't noticed, Umbraco v5 got pulled. There are currently no plans in the roadmap to remove XSLT from v4, so it will still keep working for a long time to come.
is working on a reply...