Wednesday, April 30, 2014

Map Icon URL for SharePoint webpart

Scenario :
I have come across to develop a webpart, which is to list certain assets from SharePoint library. The key is to display icons for each asset in the webpart, so that end user can easily identify the type of assets listed in the webpart. If you do not use the SPUtility method to map the icon URL, you have to go on a hard way to identify the file extension and map the relevant icon from style library.

Solution :
The SPUtility.MapToIcon(SPWeb, string, string, IconSize) allows you to retrieve the relevant icon file name, which resides inside hive folder.
Then you just need to concatenate the retrieved icon URL with hive relative folder to make the URL server relative. Check the following for the reference :

SPUtility.ConcatUrls("/_layouts/15/images/", SPUtility.MapToIcon(item.Web, SPUtility.ConcatUrls(item.Web.Url, item.Url), "", IconSize.Size16));

You may check the documentation from Microsoft for further reading here.

Further Notes :
MP3/MP2 icons are not available in the hive by default. You need to add those icons with 16*16 size to hive folder and update the  DOCICON.XML file.

In order to automate the above scenario, you may add a feature event receiver to update the DOCICON.CML file.


public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
            string[,] iconInformation = new string[,] { { "mp3", "ICMP3.png" }, { "mp2", "ICMP2.png" } }; 
            string docIconXml = SPUtility.GetVersionedGenericSetupPath(string.Format("Template\\XML\\{0}", "/DOCICON.XML"), 15);
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(docIconXml);
            XmlNode documentElement = xmlDocument.DocumentElement;

            for (int i = 0; i < iconInformation.Rank; i++)
            {
                XmlNode iconNode = documentElement.SelectSingleNode(string.Format("ByExtension/Mapping[@Key='{0}']", iconInformation[i, 0]));
                if (iconNode == null)
                {
                    iconNode = xmlDocument.CreateElement("Mapping");
                    iconNode.Attributes.Append(xmlDocument.CreateAttribute("Key")).Value = iconInformation[i, 0];
                    iconNode.Attributes.Append(xmlDocument.CreateAttribute("Value")).Value = iconInformation[i, 1];
                    bool wasAdded = false;
                    XmlNode byExtensionNode = documentElement.SelectSingleNode("ByExtension");
                    foreach (XmlNode node in byExtensionNode.ChildNodes)
                    {
                        if (node.Attributes["Key"].Value.CompareTo(iconInformation[i, 0]) > 0)
                        {
                            byExtensionNode.InsertBefore(iconNode, node);
                            wasAdded = true;
                            break;
                        }
                    }

                    if (!wasAdded)
                        byExtensionNode.AppendChild(iconNode);

                    xmlDocument.Save(docIconXml);
                }
            }
}



Happy coding!