@inherits umbraco.MacroEngines.DynamicNodeContext
@{
@* Walk up the tree from the current page to get the root node *@
var rootNode = Model.AncestorOrself(1);
}
@*Render the sitemap by passing the root node to the traverse helper*@
<div class="sitemap">
@traverse(@Model.AncestorOrSelf())
</div>
@*Helper method to travers through all descendants*@
@helper traverse(dynamic node)
{
@*Select visible children *@
var items = node.Children.Where("Visible");
@*If any items are returned, render a list *@
if (items.Any())
{
<ul>
@foreach (var item in items)
{
if (item.hasProperty("siteMapIgnore"))
{
if (item.getProperty("siteMapIgnore") != "1")
{
<li>
<a href="@item.Url">@item.Name</a>
@*Run the traverse helper again *@
@traverse(item)
</li>
}
}
}
</ul>
}
}
But all i get on the page is Error loading MacroEngine script (file: SiteMap.cshtml)
Can someone let me know if there is a problem with version 6 and this script?
Just a very small missing capital letter in AncestorOrSelf, here is fully working version:
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
@* Walk up the tree from the current page to get the root node *@
var rootNode = Model.AncestorOrSelf(1);
}
@*Render the sitemap by passing the root node to the traverse helper*@
<div class="sitemap">
@Traverse(rootNode)
</div>
<p>ssdsdsd</p>
@*Helper method to travers through all descendants*@
@helper Traverse(dynamic node)
{
@*Select visible children *@
var items = node.Children.Where("Visible");
@*If any items are returned, render a list *@
if (items.Any())
{
<ul>
@foreach (var item in items)
{
if (item.hasProperty("siteMapIgnore"))
{
if (item.getProperty("siteMapIgnore") != "1")
{
<li>
<a href="@item.Url">@item.Name</a>
@*Run the traverse helper again *@
@Traverse(item)
</li>
}
}
}
</ul>
}
}
I try to use the default Sitemap script in my Umbraco 6.1.5 install. I have removed the @ and changed AncestorOrself to AncestorOrSelf, but it's still not working for some reason:
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
@* Walk up the tree from the current page to get the root node *@
var rootNode = Model.AncestorOrSelf(1);
}
@*Render the sitemap by passing the root node to the traverse helper*@
<div class="sitemap">
@traverse(Model.AncestorOrSelf())
</div>
@*Helper method to travers through all descendants*@
@helper traverse(dynamic node){
@*If a MaxLevelForSitemap parameter is passed to the macro, otherwise default to 4 levels*@
var maxLevelForSitemap = String.IsNullOrEmpty(Parameter.MaxLevelForSitemap) ? 4 : int.Parse(Parameter.MaxLevelForSitemap);
@*Select visible children *@
var items = node.Children.Where("Visible").Where("Level <= " + maxLevelForSitemap);
@*If any items are returned, render a list *@
if (items.Any()) {
<ul>
@foreach (var item in items) {
<li class="[email protected]">
<a href="@item.Url">@item.Name</a>
@*Run the traverse helper again *@
@traverse(item)
</li>
}
</ul>
}
}
Have you tried to pass the rootNode variable into it like this:
@inherits umbraco.MacroEngines.DynamicNodeContext
@{ @*Walk up the tree from the current page to get the root node *@ var rootNode =Model.AncestorOrself(1); }
@*Render the sitemap by passing the root node to the traverse helper*@ <div class="sitemap"> @traverse(rootNode) </div>
@*Helper method to travers through all descendants*@ @helper traverse(dynamic node){
@*If a MaxLevelForSitemap parameter is passed to the macro, otherwise default to 4 levels*@ var maxLevelForSitemap = String.IsNullOrEmpty(Parameter.MaxLevelForSitemap) ? 4 : int.Parse(Parameter.MaxLevelForSitemap);
@*Select visible children *@ var items = node.Children.Where("Visible").Where("Level <= " + maxLevelForSitemap);
@*If any items are returned, render a list *@ if (items.Any()) { <ul> @foreach (var item in items) { <li class="[email protected]"> <a href="@item.Url">@item.Name</a>
@*Run the traverse helper again *@ @traverse(item) </li> } </ul> } }
I'm pretty sure this is a bug as Model.AncestorOrSelf() is always returning 0 but I'm just looking into the exact point it might have changed. As a workaround I have found that this should work:
I change my code with your update, it now looks like this:
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
@* Walk up the tree from the current page to get the root node *@
@*var rootNode = Model.AncestorOrSelf(1); *@
dynamic rootNode = CurrentModel.AncestorOrSelf();
}
@*Render the sitemap by passing the root node to the traverse helper*@
<div class="sitemap">
@traverse(rootNode)
</div>
@*Helper method to travers through all descendants*@
@helper traverse(dynamic node){
@*If a MaxLevelForSitemap parameter is passed to the macro, otherwise default to 4 levels*@
var maxLevelForSitemap = String.IsNullOrEmpty(Parameter.MaxLevelForSitemap) ? 4 : int.Parse(Parameter.MaxLevelForSitemap);
@*Select visible children *@
var items = node.Children.Where("Visible").Where("Level <= " + maxLevelForSitemap);
@*If any items are returned, render a list *@
if (items.Any()) {
<ul>
@foreach (var item in items) {
<li class="[email protected]">
<a href="@item.Url">@item.Name</a>
@*Run the traverse helper again *@
@traverse(item)
</li>
}
</ul>
}
}
Dennis, that is awesome, drove me a little crazy yesterday! The ficklety of dynamics, although I think it should throw a error really! However I don't think this is the issue affecting Anthony....
I think that was a red herring as there was typo in the first one as the s in Self should be capitalised. It seems older Umbraco versions forgave the casing but not for some time.
Did you check if you had and other non-Umbraco dlls in your bin folder?
the above code gives me the rootnode now, but my code is still crashing on:
if (items.Any()) {
...
}
the error message in Visual Studio is:
'umbraco.MacroEngines.DynamicNodeList' does not contain a definition for 'Any'
'items' is created on this code:
@*Helper method to travers through all descendants*@
@helper traverse(dynamic node){
@*If a MaxLevelForSitemap parameter is passed to the macro, otherwise default to 4 levels*@
var maxLevelForSitemap = String.IsNullOrEmpty(Parameter.MaxLevelForSitemap) ? 4 : int.Parse(Parameter.MaxLevelForSitemap);
@*Select visible children *@
var items = node.Children.Where("Visible").Where("Level <= " + maxLevelForSitemap);
I'm running this code in a MacroScript (not a Partial View Macro File)
for completeness, and maybe someone else can make use of it, this is my entire MacroScript file for Sitemap.cshtml:
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
var rootNode1 =Model.AncestorOrSelf();
dynamic rootNode2 = CurrentModel.AncestorOrSelf();
}
@*Render the sitemap by passing the root node to the traverse helper*@
<div class="sitemap">
@traverse(rootNode2)
</div>
@*Helper method to travers through all descendants*@
@helper traverse(dynamic node){
@*If a MaxLevelForSitemap parameter is passed to the macro, otherwise default to 4 levels*@
var maxLevelForSitemap = String.IsNullOrEmpty(Parameter.MaxLevelForSitemap) ? 4 : int.Parse(Parameter.MaxLevelForSitemap);
@*Select visible children *@
var items = node.Children.Where("Visible").Where("Level <= " + maxLevelForSitemap);
@*If any items are returned, render a list *@
if (items.Count() > 0) {
<ul>
@foreach (var item in items) {
<li class="[email protected]">
<a href="@item.Url">@item.Name</a>
@*Run the traverse helper again *@
@traverse(item)
</li>
}
</ul>
}
}
That is odd, I can't remember exactly which version of DynamicNode introduced the .Any method but it certainly was a long time ago, it really seems that you have a old version of umbraco.MacroEngines.dll, maybe check your assembly version, in Umbraco v6.1.6 I have 1.0.5021.24871 and in v6.1.5 I have 1.0.4993.19251.
NuGet Did you add it through a bundling package (Optimus) or similar? You may need an assembly redirection depending on how the dependent package was compiled.
If you don't use NuGet to update, you will also have to update Antlr3.Runtime.dll as WebGrease is dependent on that.
sitemap
I have the following script
But all i get on the page is Error loading MacroEngine script (file: SiteMap.cshtml)
Can someone let me know if there is a problem with version 6 and this script?
Have you just upgraded to v6?
The Razor engine was a little more forgiving in v4 (I have no idea why) but anyway I think your only issue is now an additonal @
Should be
In v4 this would have worked but in v6 it will kick up an error.
Hope that sorts it for you?
Jeavon
Working, great, thank you
Just a very small missing capital letter in AncestorOrSelf, here is fully working version:
I try to use the default Sitemap script in my Umbraco 6.1.5 install. I have removed the @ and changed AncestorOrself to AncestorOrSelf, but it's still not working for some reason:
I ran the debugger, and the code breaks at this line:
the error message is:
Hi Anthony,
Have you tried to pass the rootNode variable into it like this:
Don´t know if this do any difference for you.
/Dennis
Dennis,
I tried your update by adding rootNode to the @travers method, but the code still breaks at the same line as mentioned above.
Hi Anthony,
I'm pretty sure this is a bug as
Model.AncestorOrSelf()
is always returning 0 but I'm just looking into the exact point it might have changed. As a workaround I have found that this should work:Thanks,
Jeavon
Hi Jeavon,
I change my code with your update, it now looks like this:
However, the code still breaks at the line:
Thanks for your help, Anthony
Hi Anthony,
What output do you get if you try this snippet?
Jeavon
Hey Anthony,
Are you using a clean v6.1.5 install or a upgraded installation?
Jeavon
I'm using a clean v6.1.5 install
Odd, do you have any Nuget packages installed that have added dlls to the bin folder that could be conflicting with the Linq extensions?
Hi Anthony and Jeavon,
I just setup an clean installation of Umbraco 6.1.5, and do the test that Jeavon suggested.
It turns out that the @rootNode1.Id retuns 0 and the @rootNode2.Id actually returns the id of the homepage.
I hope this can be useful information for both of you.
/Dennis
Oh I made a mistake in my previous post.
The mistake is: the small s in self, so it should be AncestorOrSelf
And when I change it to:
It turns out that the to lines of code returns the same ID. In my case 1051.
/Dennis
Dennis, that is awesome, drove me a little crazy yesterday! The ficklety of dynamics, although I think it should throw a error really! However I don't think this is the issue affecting Anthony....
Hi Jeavon,
Sorry, I'm not at my office right now. I'll let you know next Monday.
greetings,
Anthony
@Dennis, I tried your suggestions, but none is solving the problem. I tried
var rootNode = Model.AncestorOrSelf();
var rootNode = Model.AncestorOrSelf(1);
var rootNode = Model.AncestorOrSelf(2);
greetings,
Anthony
Hi Jeavon,
Sorry for the delay. Just tested your snippet:
The output is:
greetings,
Anthony
Hi Anthony,
I think that was a red herring as there was typo in the first one as the s in Self should be capitalised. It seems older Umbraco versions forgave the casing but not for some time.
Did you check if you had and other non-Umbraco dlls in your bin folder?
Jeavon
Hi Anthony,
It´s because of a small spell issue. the reason why you get the 0 : 1049 is because of wrong spelling AncestorOfSelf.
If you change it to this:
It´s should output the same id´s even if you are using rootNode1 or rootNode2 you should get this:
I think that Umbraco should throw an error based on incorrect spelling of the AncestorOrSelf axis.
/Dennis
Hi Dennis,
I tested your script:
this gives me indeed the output:
Thanks,
Anthony
Hi Guys,
the above code gives me the rootnode now, but my code is still crashing on:
the error message in Visual Studio is:
'items' is created on this code:
I'm running this code in a MacroScript (not a Partial View Macro File)
Does anyone has an idea why this is not working?
thanks,
Anthony
ok, solution was easier then I thought, just replaced the line:
with
now the sitemap.cshtml script works :)
for completeness, and maybe someone else can make use of it, this is my entire MacroScript file for Sitemap.cshtml:
Hi Anthony,
That is odd, I can't remember exactly which version of DynamicNode introduced the .Any method but it certainly was a long time ago, it really seems that you have a old version of umbraco.MacroEngines.dll, maybe check your assembly version, in Umbraco v6.1.6 I have 1.0.5021.24871 and in v6.1.5 I have 1.0.4993.19251.
Jeavon
Hi Jeavon,
I checked the version of umbraco.MacroEngines.dll
it's : 1.0.4993.19251
Anthony, one suggestion, maybe combine your Where into one e.g.
Hi Jeavon, thanks for the suggestion!
Hi Anthony,
Ok, so the problem is caused by WebGrease.dll, if you remove it from the bin, you should find that .Any() works again.
Now, to think about why that might be.....
Jeavon
Some good news, updating WebGrease from v1.3.0 to current v1.5.2 fixes the issue for me!
Oh I see, where can I find WebGrease v1.5.2 ?
Thanks,
Anthony
NuGet Did you add it through a bundling package (Optimus) or similar? You may need an assembly redirection depending on how the dependent package was compiled.
If you don't use NuGet to update, you will also have to update Antlr3.Runtime.dll as WebGrease is dependent on that.
Thanks,
Jeavon
Hi Jeavon,
Yes, I installed Optimus. There was a problem with that package for Umbraco 6.1.5: http://our.umbraco.org/projects/developer-tools/optimus/computer-says-no/45119-no-styles-rendered
This might explain the problem with Optimus, I'll inform Tim (Geyssens) about it.
greetings,
Anthony
Not sure if it's related, but it could be.
I actually already have a fork of Optimus where I have upgraded the Bundling.Core which includes upgrading WebGrease https://github.com/Jeavon/BundlingAndMinificationForTheMasses
Jeavon
How can I install this Optimus fork over my existing Optimus installation ?
I will send you a new package :-)
Cool!
is working on a reply...