protected virtual object MapRichText(RichTextData richTextData, Type targetType, ILocalization localization) { IList <IRichTextFragment> fragments = new List <IRichTextFragment>(); foreach (object fragment in richTextData.Fragments) { string htmlFragment = fragment as string; if (htmlFragment == null) { // Embedded Entity Model (for Media Items) MediaItem mediaItem = (MediaItem)ModelBuilderPipeline.CreateEntityModel((EntityModelData)fragment, typeof(MediaItem), localization); mediaItem.IsEmbedded = true; if (mediaItem.MvcData == null) { mediaItem.MvcData = mediaItem.GetDefaultView(localization); } fragments.Add(mediaItem); } else { // HTML fragment. fragments.Add(new RichTextFragment(htmlFragment)); } } RichText richText = new RichText(fragments); if (targetType == typeof(RichText)) { return(richText); } return(richText.ToString()); }
private RichText ResolveRichText(XmlDocument doc, Localization localization) { const string xlinkNamespaceUri = "http://www.w3.org/1999/xlink"; XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); nsmgr.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml"); nsmgr.AddNamespace("xlink", xlinkNamespaceUri); // Process/resolve hyperlinks with XLink attributes ILinkResolver linkResolver = SiteConfiguration.LinkResolver; foreach (XmlElement linkElement in doc.SelectNodes("//a[@xlink:href]", nsmgr)) { // DD4T BinaryPublisher may have resolved a href attribute already (for links to MM Components) string linkUrl = linkElement.GetAttribute("href"); if (string.IsNullOrEmpty(linkUrl)) { // No href attribute found. Apparently the XLink refers to a regular Component; we resolve it to a URL here. string tcmUri = linkElement.GetAttribute("href", xlinkNamespaceUri); if (!string.IsNullOrEmpty(tcmUri)) { // Try to resolve directly to Binary content of MM Component. linkUrl = linkResolver.ResolveLink(tcmUri, resolveToBinary: true); } } if (!string.IsNullOrEmpty(linkUrl)) { // The link was resolved; set HTML href attribute linkElement.SetAttribute("href", linkUrl); ApplyHashIfApplicable(linkElement, localization); // Remove all XLink and data- attributes IEnumerable <XmlAttribute> attributesToRemove = linkElement.Attributes.Cast <XmlAttribute>() .Where(a => a.NamespaceURI == xlinkNamespaceUri || a.LocalName == "xlink" || a.LocalName.StartsWith("data-")).ToArray(); foreach (XmlAttribute attr in attributesToRemove) { linkElement.Attributes.Remove(attr); } } else { // The link was not resolved; remove the hyperlink. XmlNode parentNode = linkElement.ParentNode; foreach (XmlNode childNode in linkElement.ChildNodes) { parentNode.InsertBefore(childNode, linkElement); } parentNode.RemoveChild(linkElement); } } // Resolve embedded media items List <EntityModel> embeddedEntities = new List <EntityModel>(); foreach (XmlElement imgElement in doc.SelectNodes("//img[@data-schemaUri]", nsmgr)) { string[] schemaTcmUriParts = imgElement.GetAttribute("data-schemaUri").Split('-'); SemanticSchema semanticSchema = SemanticMapping.GetSchema(schemaTcmUriParts[1], localization); // The semantic mapping may resolve to a more specific model type than specified here (e.g. YouTubeVideo instead of just MediaItem) Type modelType = semanticSchema.GetModelTypeFromSemanticMapping(typeof(MediaItem)); MediaItem mediaItem = (MediaItem)modelType.CreateInstance(); mediaItem.ReadFromXhtmlElement(imgElement); if (mediaItem.MvcData == null) { // In DXA 1.1 MediaItem.ReadFromXhtmlElement was expected to set MvcData. // In DXA 1.2 this should be done in a GetDefaultView override (which is also used for other embedded Entities) mediaItem.MvcData = mediaItem.GetDefaultView(localization); } embeddedEntities.Add(mediaItem); // Replace img element with marker XML processing instruction imgElement.ParentNode.ReplaceChild( doc.CreateProcessingInstruction(EmbeddedEntityProcessingInstructionName, String.Empty), imgElement ); } // Split the XHTML into fragments based on marker XML processing instructions. string xhtml = doc.DocumentElement.InnerXml; IList <IRichTextFragment> richTextFragments = new List <IRichTextFragment>(); int lastFragmentIndex = 0; int i = 0; foreach (Match embeddedEntityMatch in EmbeddedEntityProcessingInstructionRegex.Matches(xhtml)) { int embeddedEntityIndex = embeddedEntityMatch.Index; if (embeddedEntityIndex > lastFragmentIndex) { richTextFragments.Add(new RichTextFragment(xhtml.Substring(lastFragmentIndex, embeddedEntityIndex - lastFragmentIndex))); } richTextFragments.Add(embeddedEntities[i++]); lastFragmentIndex = embeddedEntityIndex + embeddedEntityMatch.Length; } if (lastFragmentIndex < xhtml.Length) { // Final text fragment richTextFragments.Add(new RichTextFragment(xhtml.Substring(lastFragmentIndex))); } return(new RichText(richTextFragments)); }