IContentFinder
If you want to create your own content finder implement the IContentFinder interface:
public interface IContentFinder
{
bool TryFindContent(PublishedContentRequest contentRequest);
}
// Some are registered by default
// But feel free to use your owns
public class ContentFinderResolver
{ … }
Umbraco runs all content finders, stops at the first one that returns true. Finder can set content, template, redirect…
Example
public class MyContentFinder : IContentFinder
{
public bool TryFindContent(PublishedContentRequest contentRequest)
{
var path = contentRequest.Uri.GetAbsolutePathDecoded();
if (!path.StartsWith("/woot"))
return false; // not found
// have we got a node with ID 1234?
var contentCache = contentRequest.RoutingContext.UmbracoContext.ContentCache;
var content = contentCache.GetById(1234);
if (content == null) return false; // not found
// render that node
contentRequest.PublishedContent = content;
return true;
}
}
Example Default content finder
public class ContentFinderByNiceUrl : IContentFinder
{
public virtual bool TryFindContent(PublishedContentRequest contentRequest)
{
string path = contentRequest.HasDomain
// eg. 5678/path/to/node
? contentRequest.Domain.RootNodeId.ToString() + …
// eg. /path/to/node
: contentRequest.Uri.GetAbsolutePathDecoded();
var node = FindContent(contentRequest, path);
return node != null;
}
}
Default finder will look for content under the domain root. This is an un-breaking change.
Example wire up
this example shows how to add custom content finder to (and how to remove ContentFinderByNiceUrl from) the ContentFinderResolver.
public class MyApplication : ApplicationEventHandler
{
protected override void ApplicationStarting(…)
{
// Insert my finder before ContentFinderByNiceUrl
ContentFinderResolver.Current
.InsertTypeBefore<ContentFinderByNiceUrl, MyContentFinder>();
// Remove ContentFinderByNiceUrl
ContentFinderResolver.Current.RemoveType<ContentFinderByNiceUrl>();
}
}
NotFoundHandlers
To set your own 404 finder create an IContentFinder and set it as the ContentLastChanceFinder.
A ContentLastChanceFinder will always return a 404 status code. This example creates a new implementation of the IContentFinder and checks whether the requested content could not be found by using the default Is404
property presented in the PublishedContentRequest
class.
public class My404ContentFinder : IContentFinder {
public bool TryFindContent(PublishedContentRequest contentRequest) {
// logic to find your 404 page and set it to contentRequest.PublishedContent
CultureInfo culture = null;
if (contentRequest.HasDomain) {
culture = CultureInfo.GetCultureInfo(contentRequest.UmbracoDomain.LanguageIsoCode);
}
// replace 'home_doctype_alias' with the alias of your homepage
IPublishedContent rootNode = contentRequest.RoutingContext.UmbracoContext.ContentCache.GetByXPath("root/home_doctype_alias").FirstOrDefault(n => n.GetCulture().ThreeLetterWindowsLanguageName == culture.ThreeLetterWindowsLanguageName);
// replace '404_doctype_alias' with the alias of your 404 page
IPublishedContent notFoundNode = contentRequest.RoutingContext.UmbracoContext.ContentCache.GetByXPath(String.Format("root/homeDocType[@id={0}]/404_doctype_alias", rootNode.Id)).FirstOrDefault(n => n.GetCulture().ThreeLetterWindowsLanguageName == culture.ThreeLetterWindowsLanguageName);
if (notFoundNode != null) {
contentRequest.PublishedContent = notFoundNode;
} else if (rootNode != null) {
contentRequest.PublishedContent = rootNode;
} else {
contentRequest.PublishedContent = contentRequest.RoutingContext.UmbracoContext.ContentCache.GetAtRoot().FirstOrDefault(n => n.GetTemplateAlias() != "");
}
return contentRequest.PublishedContent != null;
}
}
Example on how to register your own implementation:
ContentLastChanceFinderResolver.Current.SetFinder(new My404ContentFinder());