While setting up an Umbraco site you'll probably end up with some "site settings" that will eather be on a top level node or on a child settings node. Think things like setting up the nav, the footer...
These are items you only set up once a site and want to manage in a global way.
You can of course write a query each time to traverse the tree... but something that v8 makes easy and possible is to extend the UmbracoHelper that is available in your Razor Views.
Imagine that you can simply do @Umbraco.WebSiteSettings.Footer and that you get the data you want (strongly typed). THis is nice and readable and folks without a lot of razor knowledge can also see what is happening...(maybe if a frontend dev needs to do some changes).
Ok let's get started. First of all, to do the stronlgy typed stuff, use Modelbuilders (duh).
I tend to use this config:
Once generated you'll need to include the files in the vs project...
With that in place I now have strongly typed models of my document types...
Next is to get into the DI magic of V8, and build a custom Service
Define an interface (I called mine ISiteService)
It has 2 methods, 1 that fetches a Website doc based on id and one that will fetch the SearchPage doc based on id (both returning strongly typed models generated by ModelsBuilder)
The implementation looks like this
So using the alias of the type. And then looks for the ancestor of the current fed in node id of that alias (since the website will always be at the top of the tree)
For the Searchpage, it first fetched the Website and then looks for the child of the correct alias (since it will be located directly under the website node)
Of course for all of this to work we need to register the custom service
And now we can inject it where we want...
But I'll also create an extension for the UmbracoHelper
Since it is static I can't use the standard constructor approach for injecting my custom service but I can still get to it with
Umbraco.Web.Composing.Current.Factory.GetInstance();
And with all that in place I can now access my service from the Umbraco Helper in views:
Top comments (7)
Hi Tim,
Getting the alias can be done a lot easier... just use Website.ModelTypeAlias
But in fact you don't need it. You can also do this :
Personally I also would create a overload for the SiteService methods... where you can pass in a IPublishedContent so you can eliminate the the GetById call.
sweet, updating...
I needed a htmlHelper to get the renderedGrid content from
using (UmbracoContextReference umbracoContextReference = _umbracoContextFactory.EnsureUmbracoContext())
{
var currentContext = umbracoContextReference.UmbracoContext;
var developments = currentContext.Content.GetByContentType(DevelopmentPage.GetModelContentType()).First();
development.GetGridHtml(htmlHelper, "gridContent", "Bootstrap3-Fluid")
}
I ended up using
public static class HtmlExtensions
rather thanUmbracoHelperExtensions
as I didn't need the UmbracoHelper...If I was to need both, is there a way to get both other than passing the one we haven't extended into the constructor?
I had just created my own service, and was using Umbraco.Web.Composing.Current.Factory.GetInstance(); in loads of places.. (templates/partials) adding on to the umbracoHelper is so cool!
Would it be worth adding some caching for these ask once and remember globalish settings (dependant on publish)?
Just thinking you could have multiple partials on a single page all requiring to know the website root..
Or is dom traversal in Umbraco performant so don't need to worry?
yeah makes sense! But remember it is already using cache, so adding a cache layer on top of cache might have strange results... but can be tweaked :)
I always create a custom viewpage.
The 2 advantages in my opinion are:
Nice, thanks for sharing!