I was trying to use a ternary in a variable to change the class on an element, but I keep getting the "expected ;" on the line where I am declaring the variable. I got it to work another way, as seen below, but this leaves a empty class on the element. Why wouldnt' my variable work? If there is no way to make it work, how can I write this so I won't have the empty class?
@{
var home = Model.AncestorOrSelf("Category2HomePage");
var nav = home.Children.Where("Visible");
@* this way causes the error *@ var alt-nav = home.Where("useAlternateNavigation == true") ? "class=alt-nav" : "";
@* this way has a blank class if "false" *@ <ul class="@(home.Where("useAlternateNavigation == true") ? "alt-nav" : "")">
It looks like you are using a "Razor Macro" which uses a model called DynamicNode. This approach is actually legacy in Umbraco v7 and not the recommended approach in v4.10+ and v6. What version of Umbraco are you using and are you using WebForms (.master) or MVC (.cshtml) templates.
We are using 4.11 running webforms, with plans to go to v6 by the end of the summer. What is the proper way to write this?
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
var home = Model.AncestorOrSelf("Category2HomePage");
var nav = home.Children.Where("Visible");
var altnav = home.useAlternateNavigation ? "class=alt-nav" : null;
@* this way works, but leaves a blank class on false <ul class="@(home.Where("useAlternateNavigation == true") ? "alt-nav" : "")"> *@
<ul @altnav >
@foreach(var item in nav){
var style = item.IsAncestorOrSelf(Model) ? "class=active" : "";
<li @style ><a href="@item.Url"><span>@item.Name</span></a>
@* test to see if there are child nodes and if so make the dropdown list *@
@if(item.Children.Count() > 0){
<ul>
@foreach(var subNav in item.Children){
var first = subNav.IsFirst() ? "class=first" : "";
<li @first ><a href="@subNav.Url"><span>@subNav.Name</span></a></li>
}
</ul>
}
</li>
}
</ul>
@* test to see if property useAlternateNavigation is checked if not load the image below the tabs *@
if(home.Where("!useAlternateNavigation")){
<img src="/static/phase2/tabNavBorderBottom.jpg" class="tabBorder" />
} else {
}
}
Ok, that makes sense then! I would only say apply the same approach to returning null as in the snippet I posted earlier (but that's just preference). e.g.
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
var home = Model.AncestorOrSelf("Category2HomePage");
var nav = home.Children.Where("Visible");
var altnav = home.useAlternateNavigation ? "class=alt-nav" : null;
@* this way works, but leaves a blank class on false <ul class="@(home.Where("useAlternateNavigation == true") ? "alt-nav" : "")"> *@
<ul @altnav>
@foreach (var item in nav)
{
var style = item.IsAncestorOrSelf(Model) ? "active" : null;
<li class="@style">
<a href="@item.Url"><span>@item.Name</span></a>
@* test to see if there are child nodes and if so make the dropdown list *@
@if (item.Children.Count() > 0)
{
<ul>
@foreach (var subNav in item.Children)
{
var first = subNav.IsFirst() ? "first" : null;
<li class="@first"><a href="@subNav.Url"><span>@subNav.Name</span></a></li>
}
</ul>
}
</li>
}
</ul>
@* test to see if property useAlternateNavigation is checked if not load the image below the tabs *@
if (home.Where("!useAlternateNavigation"))
{
<img src="/static/phase2/tabNavBorderBottom.jpg" class="tabBorder" />
}
else
{
}
}
Jeavon, thanks for your help! would it be easy to test for a true/false property on the pages and change the output of the list according to that?
I would like the option to create the top-level navigation with or without a link. sometimes the node might be created simply as a grouping, but doesn't need a page with content.
Well, I still need it in the navigation, just the ability to write a different <li> without the anchors, or a different URL.
It would be like this only if checked, so the Top Level would just show up to be a kind of grouping for the children that apper as a dropdown. So, It would have to be something like:
Sorry, don't know what happend to the original post.
That's what I was trying, but it gives me the error about missing a "}".
Here is what I have:
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
var home = Model.AncestorOrSelf("Category2HomePage");
var nav = home.Children.Where("Visible");
var altnav = home.useAlternateNavigation ? "class=alt-nav" : null;
@* this way works, but leaves a blank class on false <ul class="@(home.Where("useAlternateNavigation == true") ? "alt-nav" : null)"> *@
<ul @altnav >
@foreach(var item in nav){
@if(item.noLinkNav){
var style = item.IsAncestorOrSelf(Model) ? "class=active" : null;
<li @style ><span>@item.Name</span>
@* test to see if there are child nodes and if so make the dropdown list *@
@if(item.Children.Count() > 0){
<ul>
@foreach(var subNav in item.Children){
var first = subNav.IsFirst() ? "class=first" : null;
<li @first ><a href="@subNav.Url"><span>@subNav.Name</span></a></li>
}
</ul>
}
</li>
}
else
{
<li @style ><a href="@item.Url"><span>@item.Name</span></a>
@* test to see if there are child nodes and if so make the dropdown list *@
@if(item.Children.Count() > 0){
<ul>
@foreach(var subNav in item.Children){
var first = subNav.IsFirst() ? "class=first" : null;
<li @first ><a href="@subNav.Url"><span>@subNav.Name</span></a></li>
}
</ul>
}
</li>
}
</ul>
@* test to see if property useAlternateNavigation is checked if not load the image below the tabs *@
if(home.Where("!useAlternateNavigation")){
<img src="/static/phase2/tabNavBorderBottom.jpg" class="tabBorder" />
}
else
{
}
}
}
Ok, here is the fixed up version but there is a variable I don't know the value of in the middle there:
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
var home = Model.AncestorOrSelf("Category2HomePage");
var nav = home.Children.Where("Visible");
var altnav = home.useAlternateNavigation ? "class=alt-nav" : null;
<ul @altnav>
@foreach (var item in nav)
{
if (item.noLinkNav)
{
var style = item.IsAncestorOrSelf(Model) ? "class=active" : null;
<li @style>
<span>@item.Name</span>
@* test to see if there are child nodes and if so make the dropdown list *@
@if (item.Children.Count() > 0)
{
<ul>
@foreach (var subNav in item.Children)
{
var first = subNav.IsFirst() ? "class=first" : null;
<li @first><a href="@subNav.Url"><span>@subNav.Name</span></a></li>
}
</ul>
}
</li>
}
else
{
var style = "somethingElse?";
<li @style>
<a href="@item.Url"><span>@item.Name</span></a>
@* test to see if there are child nodes and if so make the dropdown list *@
@if (item.Children.Count() > 0)
{
<ul>
@foreach (var subNav in item.Children)
{
var first = subNav.IsFirst() ? "class=first" : null;
<li @first><a href="@subNav.Url"><span>@subNav.Name</span></a></li>
}
</ul>
}
</li>
}
}
</ul>
if (home.Where("!useAlternateNavigation"))
{
<img src="/static/phase2/tabNavBorderBottom.jpg" class="tabBorder" />
}
else
{
}
}
As you have 2 @ for code block when you are already in the code block. But there was also a issue with the closing curly brace being in the wrong place.
Have you looked at WebMatrix or Visual Web Developer Express, both understand Razor syntax so can help you work out syntax issues like this as they would highlight them if you simply open the file in them.
I was just clicking next to each of the bracket in Umbraco, which shows the corrisponding closing bracket and it was showing them in what I thought was the right place. Stupid mistake missing the @if directly after the @foreach, though.
I appreaciate your time helping me with this Jeavon!
One more quick question: Can you add more than one class using a turnary?
Using a Ternary to Change a Class
I was trying to use a ternary in a variable to change the class on an element, but I keep getting the "expected ;" on the line where I am declaring the variable. I got it to work another way, as seen below, but this leaves a empty class on the element. Why wouldnt' my variable work? If there is no way to make it work, how can I write this so I won't have the empty class?
Hi Steve,
You cannot have a variable with a hyphen in it, e.g.
var alt-nav
should bevar altnav
Also "home" is a single node, so maybe you could do something like this?
Jeavon
p.s. Razor is smart in that if the value is null it won't render a empty class=""
Thanks Jeavon! I forgot that the hyphen was not allowed in variables. I believe I was just copying the class and it slipped my mind :)
I am still kinda new to Razor, can you always use a propery e.g. "home.useAlternateNavigation", in this fashon? That would be very cool.
You're very welcome!
Yes, with dynamics you can always do that.
It looks like you are using a "Razor Macro" which uses a model called DynamicNode. This approach is actually legacy in Umbraco v7 and not the recommended approach in v4.10+ and v6. What version of Umbraco are you using and are you using WebForms (.master) or MVC (.cshtml) templates.
We are using 4.11 running webforms, with plans to go to v6 by the end of the summer. What is the proper way to write this?
Ok, that makes sense then! I would only say apply the same approach to returning null as in the snippet I posted earlier (but that's just preference). e.g.
Jeavon, thanks for your help! would it be easy to test for a true/false property on the pages and change the output of the list according to that?
I would like the option to create the top-level navigation with or without a link. sometimes the node might be created simply as a grouping, but doesn't need a page with content.
Hi Steve,
Yes, you can filter your collection further using the .Where method, e.g.
Then the nav collection would only contain only nodes that had the aTrueFalseProperty checked.
Jeavon
Well, I still need it in the navigation, just the ability to write a different <li> without the anchors, or a different URL.
It would be like this only if checked, so the Top Level would just show up to be a kind of grouping for the children that apper as a dropdown. So, It would have to be something like:
<ul>
if(item.noLinkNav == true){
<li>Top Level
} else {
<li><a href="@item.Url">Top Level</a>
}
</li></ul>
Top Level (no link)
Child 1 (link)
Child 2 (link)
Ah ok, this would simply be like this then:
Sorry, don't know what happend to the original post.
That's what I was trying, but it gives me the error about missing a "}".
Here is what I have:
Ok, here is the fixed up version but there is a variable I don't know the value of in the middle there:
Thank you! Where was my syntax off? I couldn't see it.
You're welcome, it was mainly this section:
As you have 2 @ for code block when you are already in the code block. But there was also a issue with the closing curly brace being in the wrong place.
Have you looked at WebMatrix or Visual Web Developer Express, both understand Razor syntax so can help you work out syntax issues like this as they would highlight them if you simply open the file in them.
I was just clicking next to each of the bracket in Umbraco, which shows the corrisponding closing bracket and it was showing them in what I thought was the right place. Stupid mistake missing the @if directly after the @foreach, though.
I appreaciate your time helping me with this Jeavon!
One more quick question: Can you add more than one class using a turnary?
No problem,
Yes you can, I would do this:
Remember Razor will not render a empty
class=""
if the value of altnav is nullWhen I put a space between the classes only the first one gets enclosed in the class="somestyle".
That's strange, I just double checked and it seems fine for me in Umbraco 6.1.6.
What version of Umbraco are you using?
4.11
Ah, that's it. This method was only introduced in Razor v2 which came in with Umbraco v6.
So for Razor v1, this should do the trick?
FYI, here is blog article about the introduction of this cool feature with Razor v2 :-)
Thanks Jeavon!
is working on a reply...