February 24, 2011

Links as Items Redux!

Previously I had posted on how to set up items in your content tree to act as external links to other pages (for use with Navigation mainly – for example if you have a blog elsewhere but still want it listed in the main navigation). However, Ivan Buzyka pointed out some issues with the simple implementation so I added creating a better redirect to my ‘to do’ list for the blog. The time has come!

Let’s pretend we are modifying an existing site, we don’t want to change the navigation so that won’t be covered here – we just want to update our layout to work a little more universally. Our new items need to be able to link to an internal, external or Media item reliably for display in our navigation. Our template will consist of similar things to last time:

Link: General Link

Nav Title: Text -> standard values: $name

In Navigation: Checkbox ->standard values: checked

Create the template, add in standard values for it with the above settings and now we can create our Layout which should be assigned to the standard values of the new template.

In my layout is the following (inside the page load):

String url;
Item extItem = Sitecore.Context.Item;
LinkField extLink = (LinkField)(extItem.Fields["Link"]);
if (extLink != null)
{
if (extLink.IsInternal && extLink.TargetItem != null)
{
url = Sitecore.Links.LinkManager.GetItemUrl(extLink.TargetItem);
}
else if (extLink.IsMediaLink && extLink.TargetItem != null)
{
url = Sitecore.StringUtil.EnsurePrefix('/', Sitecore.Resources.Media.MediaManager.GetMediaUrl(extLink.TargetItem));
}
else
{
url = extLink.Url;
}
}
else
{
Item homeItem = Sitecore.Context.Database.GetItem(Sitecore.Context.Site.StartPath);
url = Sitecore.Links.LinkManager.GetItemUrl(homeItem);
}
if (!String.IsNullOrEmpty(url))
{
Response.Redirect(url);
}

To step through it: we’re setting the default to bring the user back to the home page just in case something goes wrong. From there, we check to see if the Link field exists and what type of link it is.

For an internal link, we grab the url for the item itself, and for the media item, we’re grabbing the url for the Media item to be displayed (or pdf etc.), and if it’s external – we’re just redirecting them to the url they specified.

If we stopped here, everything would be working great as long as the content was entered appropriately, however, that doesn’t always happen and we’d like to avoid this going boom. To do that we can add a simple validator: open up the content tree within Sitecore and then head to your template, expanding out the children and select the Link field item.

Scroll down to Validation in the Data section.

We want to make sure that the Link field is Always one of the following: and Internal link, a Media item, or an external Link. Also, we want it to have Some value.

Within Validation you’ll need to put the actual content you want to validate, and ValidationText is what will appear if that is not met. This will pop up when the user tries to save the item with an improper value.

validation

Shown above is the Validation and our error message: linktype is how we can determine what sort of link it is, and is generated automatically when a user selects their link (unless they are editing raw values). Our validation just makes sure that the linktype text contains one of those three options (internal, media, or external) and as long as one of those match the text in the raw value for the field we have a valid link.

This helps prevent a scenario where the user has used one of the other options for an external link which would stop the page from going anywhere.

You can also add in some of the default validation options – I'd recommend adding the Required field validator as well.

If you have any tips to help improve this further please let me know!

3 comments:

  1. What if you override the link provider to return the URL in the Link field for items that have such a field (basically the equivalent of the code above)? I think then you wouldn't need to think about it or remember to use this code - just use standard Sitecore constructs.

    ReplyDelete
  2. The validation to check if its a certain type of link from the General Link looks really useful. Could have used that technique on several projects. Thanks!

    ReplyDelete
  3. Amy, I loved your link validation as it is extremely helpful for me to validate the link is only of a certain type. I'm currently getting push back that people are not able to save without valid links. Could this be accomplished with using Validation Rules instead? Would this be similar to "Broken Links" and "External Link Target"?

    ReplyDelete