With its 6.1 release, Umbraco got some new API’s, which allow developers to tap in the logic that parses the URLs and retrieves content nodes – the Request Pipeline.

Recenlty I had a use case where I needed to conceal nodes from being rendered. Consider the following sample site structure:

A sample content section
A sample content section

My goal was to stop the ‘Thank You’ node from being served when the user types ‘/contact/thank-you’ and show the 404 page (the screenshot shows a random site from the internet just to demonstrate the concept).

Normally I would add a sibling node to Home and add all my hidden content there or try to use UrlRewriting.

In this case, the writers wanted to have the hidden nodes next to the nodes, which were using them – for example, in the screenshot ‘Thank You’ would be rendered only if a user submits the ‘Contact’ form. Normally ‘Thank You’ should not be reachable even if you type in its url.

About the Request Pipeline

Following is a very good document explaining Umbraco’s Request Pipelie: The Umbraco 6 RequestPipeline (see page 57 and the IContentFinder interface)

Solution

The Request Pipeline would enumerate all IContentFinder objects in its ContentFinderResolver and ask them to retrieve a node – it would stop when a finder returns a node. I did not find a mechanism to cancel the enumeration of the finder and decided to do a little hack. My custom NaviHideContentFinder extends ContentFinderByNiceUrl (which is used for the URLs) and checks if the node needs to be concealed. For this I use the ‘umbracoNaviHide’ property – when the finder finds a node with umbracoNaviHide = true, it returns true (found) but doest not set the actual IPublishedContent node.

This solution is the result of my toying around with the Request Pipeline and might break in future versions of the API 🙂

Implementing the NaviHideContentFinder

I first implemented an IContentFinder, which concealed all nodes just to test it – it worked. Then I added the check for ‘umbracoNaviHide’ property to determine which nodes to hide, I didn’t have the chance to test the following snippet, but it should do the trick :).

The code can be further extended to check for ‘umbracoNaviHide’ on all parent nodes – this will conceal an entire sub-tree.

public class NaviHideCotnentFinder : ContentFinderByNiceUrl
{
    public override bool TryFindContent(PublishedContentRequest request)
    {
        if (base.TryFindContent(request) 
            && request.PublishedContent.GetPropertyValue<bool>("umbracoNaviHide"))
        {
            // Clear the node that was found.
            request.PublishedContent = null;
            // Return true to prevent other IContentFinder from executing.
            return true;
        }

        return false;
    }
}

Registering the NaviHideContentFinder on ApplicationStarting

Replace the built in ContentFinderByNiceUrl.

public class MyApplicaitonHandler : ApplicationEventHandler
{
    protected override void ApplicationStarting(
        UmbracoApplicationBase umbracoApplication,
        ApplicationContext applicationContext)
    {
        ContentFinderResolver.Current
            .InsertTypeBefore<ContentFinderByNiceUrl, NaviHideCotnentFinder>();
        ContentFinderResolver.Current
            .RemoveType<ContentFinderByNiceUrl>();
    }
}

1 Comment

Implementing Grouping Nodes in Umbraco Using the Request Pipeline | Technical Blog · February 14, 2014 at 21:08

[…] This is another post, which uses Umbraco’s Request Pipeline to customize the backoffice – see my other post Using Umbraco’s Request Pipeline to Conceal Nodes. […]

Leave a Reply

Your email address will not be published. Required fields are marked *