I have an item with a General Link field named "MyLinkField". In my view I have the following:
@Sitecore.Html().Field("MyLinkField")
That works great to output the link. Now I have added a multiselect field to the source item called "QueryStringItems". This allows the author to select one or more query string content items. Each query string content item has a field called "Key" and field called "Value". This allows us to have a central listing of query string key/value pairs. We want the author to be able to easily select which key/value pairs they would like to add to the query string for a given link.
Is this even possible using the out of the box Sitecore helpers? Is there some way I could write a custom helper to extend the out of the box one to also include any selected QueryStringItems?
UPDATE: Building off of Dan's answer, here is the code that I got to work both with Internal and External General Links.
public class CustomLinkRenderer : LinkRenderer
{
public CustomLinkRenderer(Item item) : base(item)
{ }
protected override string GetUrl(XmlField field)
{
if(field?.InnerField?.Item != null)
{
MultilistField queryStringItemsField = (MultilistField)field.InnerField.Item.Fields["Query String Items"];
Item[] queryStringItems = queryStringItemsField?.GetItems();
if(queryStringItems != null && queryStringItems.Length > 0)
{
SafeDictionary<string> existingQueryString = WebUtil.ParseQueryString(field.GetAttribute("querystring"));
foreach(Item queryStringItem in queryStringItems)
{
existingQueryString[queryStringItem["Key"]] = queryStringItem["Value"];
}
field.SetAttribute("querystring", WebUtil.BuildQueryString(existingQueryString, false));
var linkType = field.GetAttribute("linktype");
if(linkType == "external")
{
var url = field.GetAttribute("url");
if(!string.IsNullOrEmpty(url))
{
if (!url.StartsWith("/", StringComparison.InvariantCulture) && url.IndexOf("://", StringComparison.InvariantCulture) < 0)
url = "http://" + url;
var queryString = WebUtil.BuildQueryString(existingQueryString, false);
if (url.Contains("?"))
{ url += "&" + queryString; }
else
{ url += "?" + queryString; }
return url;
}
}
else
{
return (new LinkUrl()).GetUrl(field, this.Item.Database);
}
}
}
return base.GetUrl(field);
}
}