Example #1
0
        private void resolveLinks(Field richTextField, TcmUri pageUri)
        {
            // Find any <a> nodes with xlink:href="tcm attribute
            string      nodeText     = richTextField.Value;
            XmlDocument tempDocument = new XmlDocument();

            tempDocument.LoadXml("<tempRoot>" + nodeText + "</tempRoot>");


            XmlNamespaceManager nsManager = new XmlNamespaceManager(tempDocument.NameTable);

            nsManager.AddNamespace("xlink", "http://www.w3.org/1999/xlink");

            XmlNodeList linkNodes = tempDocument.SelectNodes("//*[local-name()='a'][@xlink:href[starts-with(string(.),'tcm:')]]", nsManager);

            foreach (XmlNode linkElement in linkNodes)
            {
                // TODO test with including the Page Uri, seems to always link with Source Page
                //string linkText = linkFactory.ResolveLink(pageUri.ToString(), linkElement.Attributes["xlink:href"].Value, "tcm:0-0-0");
                string linkText = LinkFactory.ResolveLink("tcm:0-0-0", linkElement.Attributes["xlink:href"].Value, "tcm:0-0-0");
                if (!string.IsNullOrEmpty(linkText))
                {
                    XmlAttribute linkUrl = tempDocument.CreateAttribute("href");
                    linkUrl.Value = linkText;
                    linkElement.Attributes.Append(linkUrl);

                    // Remove the other xlink attributes from the a element
                    for (int attribCount = linkElement.Attributes.Count - 1; attribCount >= 0; attribCount--)
                    {
                        if (!string.IsNullOrEmpty(linkElement.Attributes[attribCount].NamespaceURI))
                        {
                            linkElement.Attributes.RemoveAt(attribCount);
                        }
                    }
                }
            }

            if (linkNodes.Count > 0)
            {
                richTextField.Values.Clear();
                richTextField.Values.Add(tempDocument.DocumentElement.InnerXml);
            }
        }
        /// <summary>
        /// Extension method on String to resolve rich text. 
        /// Use as: Model.Field["key"].Value.ResolveRichText()
        /// </summary>
        /// <param name="value"></param>
        /// <returns>MvcHtmlString (resolved rich text)</returns>
        public static MvcHtmlString ResolveRichText(this String value)
        {
            LinkFactory linkFactory = new LinkFactory();
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(string.Format("<xhtml>{0}</xhtml>", value));
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml");
            nsmgr.AddNamespace("xlink", "http://www.w3.org/1999/xlink");

            // resolve links which haven't been resolved
            foreach (XmlNode link in doc.SelectNodes("//xhtml:a[@xlink:href[starts-with(string(.),'tcm:')]][@xhtml:href='' or not(@xhtml:href)]", nsmgr))
            {
                string tcmuri = link.Attributes["xlink:href"].Value;
                string linkUrl = linkFactory.ResolveLink(tcmuri);
                if (!string.IsNullOrEmpty(linkUrl))
                {
                    // add href
                    XmlAttribute href = doc.CreateAttribute("xhtml:href");
                    href.Value = linkUrl;
                    link.Attributes.Append(href);

                    // remove all xlink attributes
                    foreach (XmlAttribute xlinkAttr in link.SelectNodes("//@xlink:*", nsmgr))
                    {
                        link.Attributes.Remove(xlinkAttr);
                    }
                }
                else
                {
                    // copy child nodes of link so we keep them
                    foreach (XmlNode child in link.ChildNodes)
                    {
                        link.ParentNode.InsertBefore(child.CloneNode(true), link);
                    }
                    // remove link node
                    link.ParentNode.RemoveChild(link);
                }
            }

            return new MvcHtmlString(doc.DocumentElement.InnerXml);
        }