List complete structure under current node in Ascx without codebehind

I thought this was so cool so I decided to write a separate short blog post about it. In my last blog post I wrote recursion seemed impossible to do directly in code block syntax within Ascx. I was wrong. With the help of an anonymous function here’s one way to do a list complete structure under current node ul/li without codebehind.

(This is about recursion – for most presentation logic anonymous functions is not necessary.)

<%@ Control Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="umbraco.presentation.nodeFactory" %>

<%
Action<Node> printNodesRecursively = null;
printNodesRecursively = (Node n) => {
	if (n.Children.Count==0) return;
%>
	<ul class="node-list">
<%
	foreach (Node c in n.Children) {
	%>
	<li><a href="<% =umbraco.library.NiceUrl(c.Id) %>">
		<%=c.Name%></a>
		<%printNodesRecursively(c);%>
	</li>
	<%
	}
%>
    </ul>
<%
};
printNodesRecursively(Node.GetCurrent());
%>
Don’t you just love it? Here’s where I got the idea from. I agree with Elad Ossadon (as a goal, however sometimes its just not right to be a purist on that) :
I think HTML should never be written in a C# class, but only in the template itself. I take this approach also to RoR and every other web framework. The code is minimal and very readable, much more than concatenating HTML strings.

Where to draw the line between presentation and business logic?

To me the above code is pure presentation logic and as such perfectly placed in a template / ascx. Just as using a Xslt that produce the same markup. However when the presentation logic becomes complex over a certain extent, one has to decide if it’s too hard to maintain that code in the template and because of that use a codebehind. With Asp Net Mvc we can choose our own view engine and hopefully these things will be easier.

Could I use a Repeater or DataList for the above?

Using data bound controls is a nice way to separate out Html. However I ran into a dead end trying to do a conditional with Eval. If Eval(“”)=”” …  Guess it’s not possible. I would be happy to be proven wrong on that aswell, most happy on the example below.
Using a Repeater I ended up using Html in my Codebehind anyway, which I was trying to avoid. Also – I dont miss that extra databinding syntax. Using conditions in the code blocks like above is ofcourse no problem. And when the objects and logic is taken care of in existing classes (nodefactory / orm / linq2umbraco) this technique seems just perfect too me.

Adding conditions to not display hidden and protected nodes

<%@ Control Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="umbraco.presentation.nodeFactory" %>
<%
    Action<Node> printNodesRecursively = null;
    printNodesRecursively = (Node n) =>
    {
        if (n.Children.Count == 0) return;
%>
<ul class="node-list depth-<%= n.Path.Split(",").Length.ToString() %>">
    <%
        foreach (Node c in n.Children)
        {

            if ((c.GetProperty("umbracoNaviHide") != null ||
                c.GetProperty("umbracoNaviHide").Value != "1")
                &&
                (!umbraco.library.IsProtected(c.Id, c.Path) ||
                umbraco.library.HasAccess(c.Id, c.Path)))
            {
	%>
    <li><a href="<% =umbraco.library.NiceUrl(c.Id) %>">
        <%=c.Name%></a>
        <%printNodesRecursively(c);%>
    </li>
    <%}
        }
%>
</ul>
<%
    };
    printNodesRecursively(Node.GetCurrent());
%>
Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s