This is part three of this series, and if you have found your
way to this post without stopping at the other two first you can
find them below:
We are at the following part in this tutorial, and will start
with the sub category navigation
Overview
Setup (Local Development & Visual
Studio)
HTML / CSS / Templates
Razor
Existing Packages To Use
Main Navigation
DocTypes
Main Category Navigation
- Sub Category
- Listing Pages
- Listing & Category Counts
- Submit Button
- Submission Form (Contour/API)
- Final Tweaks (Paging, )
Sub Category
This sub category is going to be for when a category has other
categories underneath it, and if those sub categories have sub
categories and so on - In theory it can have unlimited sub
categories, so we want to check if the current category we are on
has sub categories and then if so spin them out on the page in a
nice styled list.
To do this we will again use a similar'ish peice of code to the
'Main Category Navigation' macro, but we will just
be listing out any children nodes that are of the type
'BusinessCategory' from the current page.
Again this is actually a really simple Macro to create, so open up
Visual Studio and create a razor file called
'SubCategoryNavigation' and add the following code into it, save
and then build the solution.
@inherits umbraco.MacroEngines.DynamicNodeContext
@if (@Model.BusinessCategory.Where("Visible").Count() >
0)
{
<ul id="topcategories">
@foreach (var item in
@Model.BusinessCategory.Where("Visible"))
{
<li><a
href="@item.Url">@item.Name</a></li>
}
</ul>
}
As you can see the this is slightly different from the previous
code, as I learnt in between writing this that you can specify the
DocType directly after the model
(@Model.BusinessCategory) using the DocType
name. Have to say its a very nice feature and makes it really
readable.
Open up the Umbraco UI and create a Razor Macro called 'Sub
Category Navigation' and select the
'SubCategoryNavigation.cshtml' file you created
and click save. Now we need to add this macro to the page,
but before we do we need to add a style I missed to our style
sheet. Open up the 'styles' style sheet

And find the #topcategories and replace it with
the below.
#topcategories {padding:12px 0px; margin:0px 0px 12px 0px;
overflow:hidden;}
Now open up your 'Business Category'
template/master page and we'll add in our macro

Find the <h1> tag that holds the
'pageName' property and insert the 'Sub
Category Navigation' macro above it and save the
template

Now browse to your home page and click on a category that you
know has sub categories, for me I know Category On has sub
categories - Below is what you should see.

Great, we now have the sub categories sorted we can move onto
listing the businesses and in the category - I'm not going to
concentrate too much on things like paging here, we do that in the
final post which will be about final tweaks and suggestions on what
else could be added.
Listing Pages
All we want to do here is list out the Children nodes from the
current page that have a DocType of
'BusinessListing' and we'll spin them out in a
nicely styled format. Also we'll use an external service for
displaying a screenshot of the website, which is actually really
easy.
Jump over into Visual Studio again and create a razor file
called 'BusinessListings' and add the following
code, this code basically looks for all child BusinessListings that
have a value in the 'businessUrl' and
'umbracoNaviHide' is not ticked - It then loops
through and displays the data. You will the image is actually using
an external website called 'Thumbshots.org' which just returns a
screenshot of a site if you pass in a full URL.
@inherits umbraco.MacroEngines.DynamicNodeContext
@if (@Model.BusinessListing.Where("Visible").Count() >
0)
{
foreach (var item in
@Model.BusinessListing.Where("Visible").Where("businessUrl !=
\"\""))
{
<div
class="listingholders">
<img src="
http://open.thumbshots.org/image.pxf?url=@item.businessUrl"
alt="@item.Name" class="thumbnail" />
<h4><a
href="@item.businessUrl"
target="_blank">@item.Name</a></h4>
<p>@item.businessDescription</p>
<p
class="theurl">@item.businessUrl</p>
</div>
}
}
Build the solution and hop over to Umbraco and create a Razor
Macro called 'Business Listings' and select the
razor file you have just created. Now we just need to pop
this macro into the 'Business Category' template,
find the following bit of HTML and delete it
<p>List of businesses here</p>
Then insert your 'Business Listings' macro
where the HTML was and you will end up with a template like so.

Save it and now go to your home page and click on a category
that has some Business Listings under it, you should see the
below.

As I mentioned above we'll do a load of tweaking in the final
post, but for now we just want the listings on the page.
Listing & Category Counts
The final part of this post will be adding the counts / stats
which are always listed on the left hand side

We'll create three separate Macros for these and we will also
look at caching, because we don't want this constantly going
through every node on each page load. We'll start with the
'Main Category Count', so in Visual Studio create
a Razor file called 'MainCategoryCount' and add
the following code and save it.
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
@Model.AncestorOrSelf(1).Children.Where("nodeTypeAlias ==
\"BusinessCategory\"").Where("Visible").Count();
}
Do the same for the other two counts below, create the files and
add the code
SubCategoryCount
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
var subNodes =
Model.AncestorOrSelf().Descendants().Where("nodeTypeAlias ==
\"BusinessCategory\"").Where("Visible").Where("Level >
2");
@subNodes.Count();
}
ListedBusinessesCount
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
var businessListings =
Model.AncestorOrSelf().Descendants().Where("nodeTypeAlias ==
\"BusinessListing\"").Where("Visible");
@businessListings.Count();
}
Apart from the first count the other two use two methods which
let us go up the node tree and then come all the way back down so
we can find all nodes in the entire tree that satisfy our 'Where()'
criteras. AncestorOrSelf() tells us to go and get all the
Ancestors (Up the tree) including the current node (Self) and then
Descedants() tells us to go all the way down as far as it can.
All we have left to do now is create three macros in the Umbraco
for the above counts, and then insert them into the
'Master' template - While creating your Macro's I
mentioned above you should consider caching on these Macros,
because they are going up and down the entire tree on two occasions
on every page view. So to help performance, it would be a
good idea to cache them for a specified time period. To do
this simply add the amount of seconds you want to cache the Macro
for in the 'Cache Period' text box.
This is however completely optional, you don't have to do this
and again its completely up to you how long you want to cache them
for - I have gone for 600 seconds (10 minutes).

Now we have our count Macros we just need to add them like
so

And the result is

That's it, we now have Categories, Sub Categories, Businesses
Listed On the page and now stats… The next post will concentrate
solely on the Submission Button and the Submission Form (So people
can submit their businesses to the site via a form).