Skip to content

Instantly share code, notes, and snippets.

@cyfer13
Created March 21, 2011 18:02
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save cyfer13/879888 to your computer and use it in GitHub Desktop.
Save cyfer13/879888 to your computer and use it in GitHub Desktop.
A navigation control written using c# Razor
@inherits umbraco.MacroEngines.DynamicNodeContext
@using umbraco.MacroEngines
@{
Page.useStartingNodeAsHeaderNode = ConvertStringToBool(@Parameter.useStartingNodeAsHeaderNode);
Page.startingNodeId = ConvertStringToInt(@Parameter.startingNodeId);
Page.numberOfLevelsToDisplay = GetNumberOfLevelsToDisplay(@Parameter.numberOfLevelsToDisplay);
Page.cssClassForActiveTree = GetStringvalue(@Parameter.cssClassForActiveTree, "active");
Page.cssClassForCurrentlySelectedNode = GetStringvalue(@Parameter.cssClassForCurrentlySelectedNode, "selected");
Page.startingLevel = GetStartingLevel();
var cssClassForUnorderedList = @Parameter.cssClassForUnorderedList;
var idForUnorderedList = @Parameter.idForUnorderedList;
dynamic startingNode = GetStartingNode(Page.startingNodeId);
int countOfStartingNodesValidChildren = GetCountOfValidChildren(startingNode);
if (IsUserAllowedToViewNode(startingNode) && (Page.useStartingNodeAsHeaderNode || countOfStartingNodesValidChildren > 0))
{
<ul@DisplayStartingUlClass(idForUnorderedList, cssClassForUnorderedList)>
@if (Page.useStartingNodeAsHeaderNode)
{
<li>
<h3>@DisplayLink(startingNode)</h3>
@DisplayChildrenOfCurrentNode(startingNode)
</li>
}
else
{
@DisplayChilrenOfCurrentNodeWithoutUnorderList(startingNode)
}
</ul>
}
}
@helper DisplayStartingUlClass(string idForUnorderedList, string cssClassForUnorderedList) {
@Html.Raw(GetAttributeandValue("id", idForUnorderedList))@Html.Raw(GetAttributeandValue("class", cssClassForUnorderedList))
}
@helper DisplayLink(dynamic currentNode) {
string nodesUrl = GetUrl(currentNode);
string nodeName = GetStringvalue(currentNode.navigationOverride, currentNode.Name);
string cssClass = GetStringvalue(currentNode.cssClass, string.Empty);
bool isExternalHyperlink = ConvertStringToBool(currentNode.umbracoExternalRedirect);
<a href="@nodesUrl" title="name"@Html.Raw(GetAttributeandValue("class", cssClass))@Html.Raw(GetAttributeandValue(isExternalHyperlink, "rel", "external"))>@nodeName</a>
}
@helper DisplayChildrenOfCurrentNode(dynamic parentNode) {
if (IsCurrentLevelViewable(parentNode))
{
<ul>
@{
var nodesToDisplay = parentNode.Children.Where("umbracoNaviHide != true");
foreach (var node in nodesToDisplay)
{
<li@Html.Raw(GetAttributeandValue("class", setCssClassForLi(node)))>@DisplayLink(node)
@DisplayChildrenOfCurrentNode(node)</li>
}
}
</ul>
}
}
@helper DisplayChilrenOfCurrentNodeWithoutUnorderList(dynamic parentNode) {
if (IsCurrentLevelViewable(parentNode))
{
var nodesToDisplay = parentNode.Children.Where("umbracoNaviHide != true");
foreach (var node in nodesToDisplay)
{
<li@Html.Raw(GetAttributeandValue("class", setCssClassForLi(node)))>@DisplayLink(node)
@DisplayChildrenOfCurrentNode(node)</li>
}
}
}
@functions {
string setCssClassForLi(dynamic currentNode)
{
string currentCssClass = string.Empty;
if (isTheDescendantOfthisNodeSelected(currentNode))
{
currentCssClass = Page.cssClassForActiveTree;
}
if (isNodeSelected(currentNode))
{
currentCssClass += Page.cssClassForCurrentlySelectedNode;
}
return currentCssClass;
}
bool isTheDescendantOfthisNodeSelected(dynamic currentNode)
{
var nodes = currentNode.DescendantsOrSelf().Where("Id == " + Model.Id.ToString());
if (nodes.Count() > 0)
{
return true;
}
return false;
}
bool isNodeSelected(dynamic currentNode)
{
if (currentNode.Id == Model.Id)
{
return true;
}
return false;
}
string GetStringvalue(string valueToCheck, string defaultValue)
{
if (!string.IsNullOrEmpty(valueToCheck))
{
return valueToCheck;
}
return defaultValue;
}
bool IsCurrentLevelViewable(dynamic currentParentNode)
{
int startingLevel = GetStartingLevel();
int countOfValidChildNodes = GetCountOfValidChildren(currentParentNode);
return (currentParentNode.Level < startingLevel + Page.numberOfLevelsToDisplay) && countOfValidChildNodes > 0;
}
string GetUrl(dynamic currentNode)
{
string nodesUrl = currentNode.Url;
if (currentNode.umbracoRedirect is int && currentNode.umbracoRedirect > 0)
{
nodesUrl = umbraco.library.NiceUrl(currentNode.umbracoRedirect);
}
if (!string.IsNullOrEmpty(currentNode.umbracoExternalRedirect))
{
nodesUrl = currentNode.umbracoExternalRedirect;
}
return nodesUrl;
}
dynamic GetStartingNode(int startingNodeId)
{
dynamic startingNode = new DynamicNode(startingNodeId);
if (startingNode == null || startingNode.Id <= 0)
{
startingNode = @Model.AncestorOrSelf();
}
return startingNode;
}
int ConvertStringToInt(string stringToConvert)
{
int output = 0;
int.TryParse(stringToConvert, out output);
return output;
}
bool ConvertStringToBool(string stringToConvert)
{
bool output = false;
bool.TryParse(stringToConvert, out output);
return output;
}
int GetNumberOfLevelsToDisplay(string stringToConvert)
{
var amountOfLevelsToDisplay = ConvertStringToInt(stringToConvert);
if (amountOfLevelsToDisplay == 0)
{
return 1;
}
return amountOfLevelsToDisplay;
}
bool IsUserAllowedToViewNode(dynamic currentNode)
{
if (!currentNode.IsProtected && currentNode.HasAccess)
{
return true;
}
return false;
}
int GetCountOfValidChildren(dynamic startingNode)
{
var listOfChildren = startingNode.Children.Where("umbracoNaviHide != true");
return listOfChildren.Count();
}
string GetAttributeandValue(string attributeName, string value)
{
if (!string.IsNullOrEmpty(value))
{
return string.Format(" {0}=\"{1}\"", attributeName, value);
}
return string.Empty;
}
string GetAttributeandValue(bool displayAttribute, string attributeName, string value)
{
if (displayAttribute)
{
return GetAttributeandValue(attributeName, value);
}
return string.Empty;
}
int GetStartingLevel()
{
if (Page.startingLevel == null || Page.startingLevel <= 0)
{
dynamic startingNode = GetStartingNode(Page.startingNodeId);
return startingNode.Level;
}
return Page.startingLevel;
}
}
@joeriks
Copy link

joeriks commented Mar 22, 2011

I think it looks great. Some minor comments:
Page is special good for use of variables across several files (when you use global vars), since you are in one and the same file you can use regular private variables inside your functions{}.
I don't think you need @ in front of Parameter as you already are in a codeblock.
Gareth made a shortcut "visible" which is really the same as "!umbracoNaviHide".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment