this post applies to Sitecore v5.3.1So, i was thinking about the pipelines and processors available in Sitecore, and more specifically the availability of hooking into them and how it could be used on the rich text fields.. there's actually a great processor to use called uiSaveHtml that you can hook into - and so i wrote a small module/add-on that can be used to automatically convert word(s) to links, all specified in a sitecore structure and easily managed.
Here's what i ended up doing, and if you follow these steps you'll have a working AutoLink add-on:
step 1: creating the autolink item template and sample itemcreate a new template called '
autolinkitem'. this template we will use to define each of the substituting 'autolinks'. now, go ahead and add the following fields to it:
- AutoLink - text
- Target - link
- NewWindow - checkbox
after that - save, build & publish it.
now we're going to wanna create a sample item so we'll know if it's working or not, so first create a folder somewhere called 'Autolinks' and then create a new autolinkitem (based on the above created template) in that folder (i've went with /sitecore/content/global/autolinks as the path for my folder) and set the fields to something nice..
screenshot #1: the template & sample item
step 2: create the processorcreate a new C# class library (or add to an existing one) that we'll use to store our code in and reference in the processor later on. throughout this post the namespace will be 'usoniandream.autolink' but you can of course name it whatever you wish.
- add a reference to System.Web (nice to have)
- add a reference to Sitecore.Kernel (don't copy local).
- add an empty class called AutoLinkProcessor.cs
now, go ahead and add the following code to your new processor:
using System;
using System.Collections.Generic;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Data.Fields;
using
Sitecore.Pipelines;
using Sitecore.Pipelines.SaveHtml;
using
Sitecore.SecurityModel;
using System.Text;
using
System.Text.RegularExpressions;
namespace usoniandream.autolink.pipelines
{
public class AutoLinkProcessor
{
///
///
processor for handling the autolink replacement of words to links
///
/// SaveHtmlArgs
public void
Process(Sitecore.Pipelines.SaveHtml.SaveHtmlArgs args)
{
// make sure we
only do this for the items that actually has some body html to parse
if
(args.Body!="")
{
try
{
// find our root folder for the autolink
items
Item autolinkfolder =
Sitecore.Context.ContentDatabase.Items[Sitecore.Configuration.Settings.GetSetting("usoniandream.autolinks.rootfolder")];
if (autolinkfolder != null)
{
// try to get the autolink items
Item[] itms = autolinkfolder.Axes.SelectItems(autolinkfolder.Paths.Path +
"/*[@@templatekey='autolinkitem']");
if (itms != null)
{
// log it
for informational purposes
Sitecore.Diagnostics.Log.Info("found " +
itms.Length.ToString() + " autolinks to try and patch with..", "AutoLinks");
// handle it as a List instead of an array (simply easier)
List
autolinks = new List- (itms);
// make sure we got some autolinks to
parse with
if (autolinks != null && autolinks.Count > 0)
{
// perform the replacement(s)
args.Body = AutoLink(args.Body,
autolinks);
}
}
else
{
// log that we didn't find any items
Sitecore.Diagnostics.Log.Info("unable to find autolink items..",
"autolink");
}
}
else
{
// log that the folder is missing
Sitecore.Diagnostics.Log.Info("unable to find autolink items root folder..",
"autolink");
}
}
catch (Exception exception)
{
// add the
message to the argument and log it for informational purposes
args.AddMessage(exception.ToString(),PipelineMessageType.Warning);
Sitecore.Diagnostics.Log.Error("autolink error:", exception, "autolink");
}
}
}
///
/// Initiates the process of iterating
through the autolink items
///
/// the body
to link within
/// Generic List of items
containing autolink information
/// the finished body html
now with linked words
private string AutoLink(string text,
List- autolinks)
{
LinkField lf;
foreach (Item itm in
autolinks)
{
lf = (LinkField)itm.Fields["target"];
if (lf!=null)
{
text = ReplaceWithAutoLinks(text, itm["autolink"], lf.Url,
itm["newwindow"]);
}
}
return text;
}
///
///
Replaces all occurances of a word with the specified link text
///
/// body html to replace within
/// the word to search for
/// the url to link to
/// taken
from the checkbox field
/// System.String
private string ReplaceWithAutoLinks(string text, string search, string link,
string newWindow)
{
// make sure we don't parse any uneccessary item
data that isn't properly entered..
if (text!=string.Empty &&
search!=string.Empty && link!=string.Empty)
{
// build our
replacement link
string replacewith = " <a href="/" alt="'\">"
+ search + "</a> ";
// define our (sorry, but extremely weak)
regex pattern that'll match our words with whitespaces before and after it..
string pattern = @"\s" + search + @"\s";
// redefine the replacement
link if it's for a new window
if (newWindow == "1")
{
replacewith =
" <a href="/" target="'\" alt="'\">" + search +
"</a> ";
}
// log it so we know what's happening..
Sitecore.Diagnostics.Log.Info("autolink pattern '" + pattern + "' will be
replaced with '" + replacewith, "autolink");
// return the parsed text
text = System.Text.RegularExpressions.Regex.Replace(text, pattern,
replacewith, RegexOptions.IgnoreCase);
}
else
{
Sitecore.Diagnostics.Log.Error("autolink couldn't parse since the input data
wasn't properly supplied", "autolink");
}
return text;
}
}
}
once that's done we're gonna have to
compile it and make sure it ends up in the bin folder so the system can find it when we're gonna call it.
step 3: editing the web.config file and hooking into the processornow that we're ready to go and have our code put to use we'll need to tell sitecore that it should, so here's what we're gonna do:
- locate the uiSaveHtml processor element in the web.config file
add the following line within it as the first processor in the list:
<processor type="usoniandream.autolink.pipelines.AutoLinkProcessor, usoniandream.autolink" mode="on">
- add a setting so we can easily find our autolinks root folder
add the following line anywhere within the Settings section:
<setting name="usoniandream.autolinks.rootfolder" value="/sitecore/content/global/autolinks">
as you can see that setting points to a folder i mentioned earlier in the post, but as always you can name it anything you like and have it point anywhere you like.
step 4: the finished product
now you're all set and ready to run the finished add-on! Open the content editor and go to any item that has a rich text field on it, double click it so it opens in the editor, write the autolink word(s) that you specified in your sample item (created in step 1) somewhere and click on Accept.
screenshot #2: text before it's automatically converted (just plain text in a richtext field)
Assuming you've followed the above steps correctly you should now see that the word has been replaced with a link instead.
screenshot #3: automatically converted the word 'sitecore' to a link to the sitecore website
step 5: go to bed..well, that's it for me. time for some much needed sleep.
take care,
P.