Resolve Wildcard (*) Item

In one of our #Sitecore project we have requirement that we need to keep Events at a common place outside the Home node. So we thought to keep them in common Globals Folder. Now the biggest challenge is that how to resolve these events.

From where we got an idea of wildcard item (*). This is the Sitecore structure.

  • sitecore
    • content
      • SiteItem1
        • Home
          • Event Landing Page
            • *
        • Globals
          • Site Setting Item
          • Event Folder
            • Event Detail Page1
            • Event Detail Page2

So according to this structure we have #Wildcard Item(*) under home node. It is like event detail page that is under Event landing page.

 

WildcardItem.png

 

And in Globals folder we have all events, those are actual Event Detail Pages, we need to resolve.

 

WildcardEvents.png

Also you can see that I have created a Site Setting Item, in which I have some settings as you can see below image –

 

WildcardSiteSettingItem.png

 

On site setting item I have 2 fields –

  1. Event Calendar Root
  2. Fallback Events Detail Page

 

Okay, Its time for code now. First of all I have created a custom LinkProvider.config. That is as follows –

<?xml version=”1.0″?>
<configuration xmlns:patch=”http://www.sitecore.net/xmlconfig/”&gt;
<sitecore>
<pipelines>
<overrideItemUrl>
<processor type=”Sitecore.xyz.Pipelines.UrlOverrides.EventUrlOverride, Sitecore.EventCalendar” />
</overrideItemUrl>
</pipelines>
<linkManager>
<patch:attribute name=”defaultProvider”>fullcalendar</patch:attribute>
<providers>
<add name=”sitecore”>
<patch:attribute name=”name”>fullcalendar</patch:attribute>
<patch:attribute name=”type”>Sitecore.xyz.Links.LinkProvider, Sitecore.EventCalendar</patch:attribute>
<patch:attribute name=”lowercaseUrls”>true</patch:attribute>
<patch:attribute name=”languageEmbedding”>never</patch:attribute>
</add>
</providers>
</linkManager>
</sitecore>
</configuration>

 

As you can see in this LinkProvider.config, I have created a pipeline named overrideItemUrl and then created a defaultprovider. So first talk about defaultprovioder. I have created a provider with the name “xyz”, in which I am calling a class “LinkProvider“. The code for this LinkProvider is here –

 

public class LinkProvider : Sitecore.Links.LinkProvider
{
public override string GetItemUrl(Item item, UrlOptions options)
{
var args = new WildcardItemUrlArgs(item, options)
{
BaseAction = base.GetItemUrl
};

CorePipeline.Run(“overrideItemUrl”, args);

if (args.HasOverride && !string.IsNullOrEmpty(args.Url))
{
return args.Url;
}

return base.GetItemUrl(item, options);
}

public override UrlOptions GetDefaultUrlOptions()
{
var urlOptions = base.GetDefaultUrlOptions();
urlOptions.SiteResolving = Settings.Rendering.SiteResolving;
return urlOptions;
}
}

 

Basically Linkprovider is used to resolve links. So I am overriding its default method GetItemUrl, in which I am calling another method that is “WildcardItemUrlArgs”.

 

public class WildcardItemUrlArgs : PipelineArgs
{
public WildcardItemUrlArgs(Item item, UrlOptions urlOptions)
{
Item = item;
UrlOptions = urlOptions;
}

public Item Item { get; private set; }
public UrlOptions UrlOptions { get; private set; }
public string Url { get; set; }
public bool HasOverride { get; set; }
public Func<Item, UrlOptions, string> BaseAction { get; set; }
}

 

Then I am calling overrideItemUrl pipeline, as you can see in LinkProvider class.

 

<pipelines>
<overrideItemUrl>
<processor type=”Sitecore.xyz.Pipelines.UrlOverrides.EventUrlOverride, Sitecore.xyz” />
</overrideItemUrl>
</pipelines>

 

So now in overrideItemUrl pipeline I am calling a processor.

So now in EventUrlOverride class –

 

public class EventUrlOverride : BaseUrlOverride
{
public void Process(WildcardItemUrlArgs args)
{
if (args.HasOverride || !args.Item.InheritsTemplate(“Event Detail Page Template ID”) || Sitecore.Context.Item == null)
{
return;
}

var settingItem = Sitecore.Context.Database.GetItem(“Site Setting item id”);
if (settingItem != null)
{
if (settingItem.Fields[“Fallback Events Detail Page”] != null && !settingItem.Fields[“Fallback Events Detail Page”].Value.IsNullOrEmpty())
{
var fieldId = settingItem.Fields[“Fallback Events Detail Page”].ID;

if (!fieldId.IsNull)
{
Item detailItem = GetWildcardDetailPage(“Event landing page template id”,
fieldId);

if (detailItem != null)
{
args.Url = GetItemUrl(detailItem, args.Item, args.UrlOptions,args);
args.HasOverride = true;
}
}
}
}
}
}

 

In this class I am checking the wildcard item and trying to get it by Site setting item.

As you can see I am also inheriting a class named BaseUrlOverride in EventUrlOverride class. The code of EventUrlOverride class is here –

 

public class BaseUrlOverride
{
private string GetFriendlyUrl(Item item)
{
return item.Name.ToLower().Replace(” “, “-“);
}

protected string GetItemUrl(Item detailItem, Item targetItem, UrlOptions urlOptions, WildcardItemUrlArgs args)
{
var friendlyUrl = GetFriendlyUrl(targetItem);
return args.BaseAction(detailItem, urlOptions)
.Replace(Constants.Wildcard.UrlToken, friendlyUrl)
.Replace(Constants.Wildcard.Node, friendlyUrl);
}

protected Item GetWildcardDetailPage(string landingPageTemplateId, ID fieldId, Item currentItem = null)
{
Item detailItem = null;

var context = Context.Item;

// Handle case where context page is either the wildcard node or landing page
if (context.Name.StartsWith(Constants.Wildcard.Node) &&
context.Parent.InheritsTemplate(landingPageTemplateId))
{
detailItem = context;
}
else if (context.InheritsTemplate(landingPageTemplateId))
{
detailItem =
context.Children
.FirstOrDefault(i => i.Name.StartsWith(“*”));
}

if (detailItem == null)
{
var settingItem = Sitecore.Context.Database.GetItem(“Site setting item id”);
if (settingItem != null)
{
var siteLookupField = new LookupField(settingItem.Fields[fieldId]);
var selectedPage = siteLookupField.TargetItem;
if (selectedPage != null && selectedPage.Name.StartsWith(“*”))
{
detailItem = selectedPage;
}
}
}

return detailItem;
}
}

 

So basically in EventUrlOverride class firstly we are trying to get WildCardItem (*), then we are calling GetItemUrl method to resolve actual EventDetailPage Item.

Phewww!!! Thats it finally. Enough coding.

Happy Coding 🙂 and happy wildcard item also 🙂

Advertisements

One thought on “Resolve Wildcard (*) Item

Leave a Reply

Fill in your details below or click an icon to log in:

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