/// <summary>
        /// Builds a strongly typed Entity Model based on a given DXA R2 Data Model.
        /// </summary>
        /// <param name="entityModel">The strongly typed Entity Model to build. Is <c>null</c> for the first Entity Model Builder in the pipeline.</param>
        /// <param name="entityModelData">The DXA R2 Data Model.</param>
        /// <param name="baseModelType">The base type for the Entity Model to build.</param>
        /// <param name="localization">The context <see cref="ILocalization"/>.</param>
        public void BuildEntityModel(ref EntityModel entityModel, EntityModelData entityModelData, Type baseModelType, Localization localization)
        {
            using (new Tracer(entityModel, entityModelData, baseModelType, localization))
            {
                if (entityModel == null)
                {
                    throw new DxaException($"The {GetType().Name} must be configured after the DefaultModelBuilder.");
                }

                GenericTopic genericTopic = entityModel as GenericTopic;
                if (genericTopic != null)
                {
                    Log.Debug("Generic Topic encountered...");
                    EntityModel stronglyTypedTopic = TryConvertToStronglyTypedTopic(genericTopic);
                    if (stronglyTypedTopic != null)
                    {
                        Log.Debug($"Converted {genericTopic} to {stronglyTypedTopic}");
                        entityModel = stronglyTypedTopic;
                    }
                    else
                    {
                        Log.Debug($"Unable to convert {genericTopic} to Strongly Typed Topic.");
                    }
                }
            }
        }
        public void BuildEntityModel_TitleBodySections_Success()
        {
            string       testTitle    = "DITA title";
            string       testBody     = "<div class=\"section \">First section</div><div class=\"section \">Second section</div>";
            GenericTopic genericTopic = new GenericTopic
            {
                TopicTitle = "<Test topic title>",
                TopicBody  = $"<h1 class=\"title \">{testTitle}</h1><div class=\"body \">{testBody}</div>"
            };

            EntityModel testEntityModel = genericTopic;

            _testModelBuilder.BuildEntityModel(ref testEntityModel, null, null, TestFixture.ParentLocalization);

            OutputJson(testEntityModel);

            TestStronglyTypedTopic result = testEntityModel as TestStronglyTypedTopic;

            Assert.IsNotNull(result, "result");
            Assert.AreEqual(genericTopic.TopicTitle, result.TopicTitle, "result.TopicTitle");
            Assert.AreEqual(testTitle, result.Title, "result.Title");
            Assert.AreEqual("First sectionSecond section", result.Body, "result.Body"); // HTML tags should get stripped ("InnerText")
            Assert.IsNotNull(result.BodyRichText, "result.BodyRichText");
            Assert.AreEqual(testBody, result.BodyRichText.ToString(), "result.BodyRichText.ToString()");
            Assert.AreEqual("First section", result.FirstSection, "result.FirstSection");
            Assert.IsNotNull(result.Sections, "result.Sections");
            Assert.AreEqual(2, result.Sections.Count, "result.Sections.Count");
            Assert.AreEqual(result.FirstSection, result.Sections[0], "result.Sections[0]");
            Assert.IsNull(result.Links, "result.Links");
            Assert.IsNull(result.FirstChildLink, "result.FirstChildLink");
            Assert.IsNull(result.ChildLinks, "result.ChildLinks");
            Assert.IsNotNull(result.MvcData, "result.MvcData");
            Assert.AreEqual(result.GetDefaultView(null), result.MvcData, "result.MvcData");
        }
        public void TryConvertToStronglyTypedTopic_Links_Success()
        {
            GenericTopic genericTopic = new GenericTopic
            {
                Id        = "16121970",
                TopicBody = "<div class=\"body \" /><div class=\"related-links \">" +
                            "<div class=\"childlink \"><strong><a class=\"link \" href=\"/firstlink.html\">First link text</a></strong></div>" +
                            "<div class=\"childlink \"><strong><a class=\"link \" href=\"/secondlink.html\">Second link text</a></strong></div>" +
                            "<div class=\"parentlink \"><strong><a class=\"link \" href=\"/thirdlink.html\">Third link text</a></strong></div>" +
                            "</div>"
            };

            TestStronglyTypedTopic result = _testModelBuilder.TryConvertToStronglyTypedTopic <TestStronglyTypedTopic>(genericTopic);

            Assert.IsNotNull(result, "result");

            OutputJson(result);

            Assert.AreEqual(genericTopic.Id, result.Id, "result.Id");
            Assert.IsNull(result.Title, "result.Title");
            Assert.AreEqual(string.Empty, result.Body, "result.Body");
            Assert.IsNotNull(result.Links, "result.Links");
            Assert.AreEqual(3, result.Links.Count, "result.Links.Count");
            Assert.IsNotNull(result.FirstChildLink, "result.FirstChildLink");
            Assert.AreEqual("/firstlink.html", result.FirstChildLink.Url, "result.FirstChildLink.Url");
            Assert.AreEqual("First link text", result.FirstChildLink.LinkText, "result.FirstChildLink.LinkText");
            Assert.IsNull(result.FirstChildLink.AlternateText, "result.FirstChildLink.AlternateText");
            Assert.IsNotNull(result.ChildLinks, "result.ChildLinks");
            Assert.AreEqual(2, result.ChildLinks.Count, "result.ChildLinks.Count");
        }
        public void BuildEntityModel_TopicBodyIllFormedXml_Success()
        {
            GenericTopic genericTopic = new GenericTopic
            {
                TopicBody = "<IllFormedXML>"
            };

            EntityModel testEntityModel = genericTopic;

            _testModelBuilder.BuildEntityModel(ref testEntityModel, null, null, TestFixture.ParentLocalization);

            Assert.AreSame(genericTopic, testEntityModel, "testEntityModel");
        }
        public void BuildEntityModel_NoMatchingStronglyTypedTopic_Success()
        {
            GenericTopic genericTopic = new GenericTopic
            {
                TopicBody = null
            };

            EntityModel testEntityModel = genericTopic;

            _testModelBuilder.BuildEntityModel(ref testEntityModel, null, null, TestFixture.ParentLocalization);

            Assert.AreSame(genericTopic, testEntityModel, "testEntityModel");
        }
Exemple #6
0
        protected void Application_Start()
        {
            InitializeDependencyInjection();
            SiteConfiguration.InitializeProviders(DependencyResolver.Current.GetService);

            DataFormatters.Formatters.Add("json", new JsonFormatter());
            DataFormatters.Formatters.Add("rss", new RssFormatter());
            DataFormatters.Formatters.Add("atom", new AtomFormatter());

            RegisterRoutes(RouteTable.Routes);
            AreaRegistration.RegisterAllAreas();
            GenericTopic.Register(); // Register generic Topic View Model so that Tridion Docs content can be handled.
            RegisterDisplayModes();
            _initialized = true;
        }
        /// <summary>
        /// Tries to convert a given generic Topic to a Strongly Typed Topic Model.
        /// </summary>
        /// <param name="genericTopic">The generic Topic to convert.</param>
        /// <param name="ofType">The type of the Strongly Typed Topic Model to convert to. If not specified (or <c>null</c>), the type will be determined from the XHTML.</param>
        /// <returns>The Strongly Typed Topic Model or <c>null</c> if the generic Topic cannot be converted.</returns>
        public EntityModel TryConvertToStronglyTypedTopic(GenericTopic genericTopic, Type ofType = null)
        {
            using (new Tracer(genericTopic, ofType))
            {
                Log.Debug($"Trying to convert {genericTopic} to Strongly Typed Topic Model...");

                IEnumerable <Tuple <string, Type> > registeredTopicTypes = ModelTypeRegistry.GetModelTypesForVocabulary(ViewModel.DitaVocabulary);
                if (registeredTopicTypes == null)
                {
                    Log.Debug("No Strongly Typed Topic Models registered.");
                    return(null);
                }

                XmlElement rootElement = null;
                try
                {
                    rootElement = ParseXhtml(genericTopic);
                }
                catch (Exception ex)
                {
                    Log.Error("Unable to parse generic Topic XHTML.");
                    Log.Debug(genericTopic.TopicBody);
                    Log.Error(ex);
                    return(null);
                }

                Type topicType = ofType;
                if (ofType == null)
                {
                    topicType = DetermineTopicType(rootElement, registeredTopicTypes);
                    if (topicType == null)
                    {
                        Log.Debug("No matching Strongly Typed Topic Model found.");
                        return(null);
                    }
                }

                EntityModel stronglyTypedTopic = BuildStronglyTypedTopic(topicType, rootElement);

                if (stronglyTypedTopic.Id == null)
                {
                    stronglyTypedTopic.Id = genericTopic.Id;
                }

                return(stronglyTypedTopic);
            }
        }
        public void TryConvertToStronglyTypedTopic_SpecializedTopic_Success()
        {
            string       testTitle    = "DITA title";
            string       testBody     = "<div class=\"section lcIntro \" id=\"s1\">Intro section</div><div class=\"section lcObjectives \" id=\"s2\">Objectives section</div>";
            GenericTopic genericTopic = new GenericTopic
            {
                TopicTitle = "Specialized topic title",
                TopicBody  = $"<h1 class=\"title \">{testTitle}</h1><div class=\"body lcBaseBody lcOverviewBody \" id=\"b1\">{testBody}</div>"
            };

            TestSpecializedTopic result = _testModelBuilder.TryConvertToStronglyTypedTopic(genericTopic) as TestSpecializedTopic;

            Assert.IsNotNull(result, "result");

            OutputJson(result);

            Assert.IsNotNull(result.Intro, "result.Intro");
            Assert.IsNotNull(result.Objectives, "result.Objectives");
            Assert.IsNotNull(result.Body, "result.Body");
            Assert.IsNotNull(result.Body.Intro, "result.Body.Intro");
            Assert.IsNotNull(result.Body.Objectives, "result.Body.Objectives");
            Assert.IsNotNull(result.Body.Objectives.Content, "result.Body.Objectives.Content");
            Assert.IsNotNull(result.Body.Sections, "result.Body.Sections");

            Assert.AreEqual("Intro section", result.Intro.ToString(), "result.Intro.ToString()");
            Assert.AreEqual("Objectives section", result.Objectives.ToString(), "result.Objectives.ToString()");

            Assert.AreEqual("b1", result.Body.Id, "result.Body.Id");
            Assert.AreEqual("body lcBaseBody lcOverviewBody ", result.Body.HtmlClasses, "body lcBaseBody lcOverviewBody ");
            Assert.AreEqual("Intro section", result.Body.Intro.ToString(), "result.Body.Intro.ToString()");

            Assert.AreEqual("s2", result.Body.Objectives.Id, "result.Body.Objectives.Id");
            Assert.AreEqual("section lcObjectives ", result.Body.Objectives.HtmlClasses, "result.Body.Objectives.HtmlClasses");
            Assert.AreEqual("Objectives section", result.Body.Objectives.Content.ToString(), "result.Body.Objectives.Content.ToString()");

            Assert.AreEqual(2, result.Body.Sections.Count, "result.Body.Sections.Count");
            Assert.AreEqual("s1", result.Body.Sections[0].Id, "result.Body.Sections[0].Id");
            Assert.AreEqual("s2", result.Body.Sections[1].Id, "result.Body.Sections[1].Id");
            Assert.AreEqual("section lcIntro ", result.Body.Sections[0].HtmlClasses, "result.Body.Sections[0].HtmlClasses");
            Assert.AreEqual("section lcObjectives ", result.Body.Sections[1].HtmlClasses, "result.Body.Sections[1].HtmlClasses");

            Assert.IsNotNull(result.MvcData, "result.MvcData");
            Assert.AreEqual(result.GetDefaultView(null), result.MvcData, "result.MvcData");
            Assert.IsNotNull(result.Body.MvcData, "result.Body.MvcData");
            Assert.AreEqual(result.Body.GetDefaultView(null), result.Body.MvcData, "result.Body.MvcData");
        }
        protected virtual XmlElement ParseXhtml(GenericTopic genericTopic)
        {
            using (new Tracer(genericTopic))
            {
                XmlDocument topicXmlDoc = new XmlDocument();
                topicXmlDoc.LoadXml($"<topic>{genericTopic.TopicBody}</topic>");

                XmlElement topicElement = topicXmlDoc.DocumentElement;

                // Inject GenericTopic's TopicTitle as additional HTML element
                XmlElement topicTitleElement = topicXmlDoc.CreateElement("h1");
                topicTitleElement.SetAttribute("class", "_topicTitle");
                topicTitleElement.InnerText = genericTopic.TopicTitle;
                topicElement.AppendChild(topicTitleElement);

                return(topicElement);
            }
        }
        public void BuildEntityModel_ThroughModelBuilderPipeline_Success()
        {
            Localization testLocalization = new DocsLocalization();

            testLocalization.EnsureInitialized();

            string       testTopicId  = "1612-1970";
            string       testTitle    = "DITA title";
            string       testBody     = "<div class=\"section \">First section</div><div class=\"section \">Second section</div>";
            GenericTopic genericTopic = new GenericTopic
            {
                TopicTitle = "<Test topic title>",
                TopicBody  = $"<h1 class=\"title \">{testTitle}</h1><div class=\"body \">{testBody}</div>"
            };

            PageModelData testPageModelData = new PageModelData
            {
                Id      = "666",
                Regions = new List <RegionModelData>
                {
                    new RegionModelData
                    {
                        Name     = "Main",
                        Entities = new List <EntityModelData>
                        {
                            new EntityModelData
                            {
                                Id       = testTopicId,
                                SchemaId = "1",  // Tridion Docs uses a hard-coded/fake Schema ID.
                                Content  = new ContentModelData
                                {
                                    { "topicTitle", genericTopic.TopicTitle },
                                    { "topicBody", genericTopic.TopicBody }
                                },
                                MvcData = new DataModel.MvcData
                                {
                                    AreaName = "Ish",
                                    ViewName = "Topic"
                                }
                            }
                        },
                        MvcData = new DataModel.MvcData
                        {
                            AreaName = "Core", // TODO: test with ISH data
                            ViewName = "Main"
                        }
                    }
                },
                MvcData = new DataModel.MvcData
                {
                    AreaName = "Test",
                    ViewName = "SimpleTestPage"
                }
            };

            PageModel pageModel = ModelBuilderPipeline.CreatePageModel(testPageModelData, false, testLocalization);

            Assert.IsNotNull(pageModel, "pageModel");

            OutputJson(pageModel);

            TestStronglyTypedTopic result = pageModel.Regions["Main"].Entities[0] as TestStronglyTypedTopic;

            Assert.IsNotNull(result);

            Assert.AreEqual(testTopicId, result.Id, "result.Id");
            Assert.AreEqual(genericTopic.TopicTitle, result.TopicTitle, "result.TopicTitle");
            Assert.AreEqual(testTitle, result.Title, "result.Title");
            Assert.AreEqual(testBody, result.BodyRichText.ToString(), "result.BodyRichText.ToString()");
            Assert.AreEqual("First section", result.FirstSection, "result.FirstSection");
            Assert.AreEqual(result.GetDefaultView(null), result.MvcData, "result.MvcData");
        }
 /// <summary>
 /// Tries to convert a given generic Topic to a Strongly Typed Topic Model.
 /// </summary>
 /// <param name="genericTopic">The generic Topic to convert.</param>
 /// <typeparam name="T">The type of the Strongly Typed Topic Model to convert to.</typeparam>
 /// <returns>The Strongly Typed Topic Model or <c>null</c> if the generic Topic cannot be converted to the given type.</returns>
 public T TryConvertToStronglyTypedTopic <T>(GenericTopic genericTopic) where T : EntityModel
 => (T)TryConvertToStronglyTypedTopic(genericTopic, typeof(T));
Exemple #12
0
        internal static void RegisterViewModels()
        {
            // Entity Views
            RegisterViewModel("Article", typeof(Article));
            RegisterViewModel("Image", typeof(Image));
            RegisterViewModel("Download", typeof(Download));
            RegisterViewModel("TestEntity", typeof(TestEntity));

            RegisterViewModel("LanguageSelector", typeof(Common.Models.Configuration));

            RegisterViewModel("Breadcrumb", typeof(NavigationLinks), "Navigation");
            RegisterViewModel("LeftNavigation", typeof(NavigationLinks), "Navigation");
            RegisterViewModel("SiteMap", typeof(SitemapItem), "Navigation");
            RegisterViewModel("SiteMapXml", typeof(SitemapItem), "Navigation");
            RegisterViewModel("TopNavigation", typeof(NavigationLinks), "Navigation");

            RegisterViewModel("PagedList", typeof(ContentList <Teaser>), "List");

            RegisterViewModel("Test:TSI1758Test", typeof(Tsi1758TestEntity));
            RegisterViewModel("Test:TSI1946Test", typeof(Tsi1946TestEntity));
            RegisterViewModel("Test:TSI811Test", typeof(Tsi811TestEntity));
            RegisterViewModel("MediaManager:imagedist", typeof(MediaManagerDistribution));
            RegisterViewModel("Test:TSI1757Test1", typeof(Tsi1757TestEntity1));
            RegisterViewModel("Test:TSI1757Test2", typeof(Tsi1757TestEntity2));
            RegisterViewModel("Test:TSI1757Test3", typeof(Tsi1757TestEntity3));
            RegisterViewModel("Test:CompLinkTest", typeof(CompLinkTest));
            RegisterViewModel("Test:TSI2316Test", typeof(Tsi2316TestEntity));
            RegisterViewModel("Test:TSI2844Test", typeof(Tsi2844TestEntity));
            RegisterViewModel("Test:TSI3010Test", typeof(Tsi3010TestEntity));

            GenericTopic.Register(); // Generic Topic Model

            // Strongly Typed Topic Models
            RegisterViewModel(typeof(TestStronglyTypedTopic));
            RegisterViewModel(typeof(TestSpecializedTopic));

            // Page Views
            RegisterViewModel("GeneralPage", typeof(PageModel));
            RegisterViewModel("IncludePage", typeof(PageModel));
            RegisterViewModel("RedirectPage", typeof(PageModel));

            RegisterViewModel("Test:SimpleTestPage", typeof(PageModel));
            RegisterViewModel("Test:TSI811TestPage", typeof(Tsi811PageModel));
            RegisterViewModel("Test:TSI2285TestPage", typeof(Tsi2285PageModel));

            // Region Views
            RegisterViewModel("2-Column", typeof(RegionModel));
            RegisterViewModel("3-Column", typeof(RegionModel));
            RegisterViewModel("4-Column", typeof(RegionModel));
            RegisterViewModel("Hero", typeof(RegionModel));
            RegisterViewModel("Info", typeof(RegionModel));
            RegisterViewModel("Left", typeof(RegionModel));
            RegisterViewModel("Links", typeof(RegionModel));
            RegisterViewModel("Logo", typeof(RegionModel));
            RegisterViewModel("Main", typeof(RegionModel));
            RegisterViewModel("Nav", typeof(RegionModel));
            RegisterViewModel("Tools", typeof(RegionModel));

            RegisterViewModel("SmartTarget:SmartTargetRegion", typeof(SmartTargetRegion));
            RegisterViewModel("SmartTarget:2-Column", typeof(SmartTargetRegion));

            // Region Views for Include Pages
            RegisterViewModel("Header", typeof(RegionModel));
            RegisterViewModel("Footer", typeof(RegionModel));
            RegisterViewModel("Left Navigation", typeof(RegionModel));
            RegisterViewModel("Content Tools", typeof(RegionModel));
        }