diff --git a/common/app/model/dotcomrendering/ElementsEnhancer.scala b/common/app/model/dotcomrendering/ElementsEnhancer.scala index e9d7bacef48..e303f3b2953 100644 --- a/common/app/model/dotcomrendering/ElementsEnhancer.scala +++ b/common/app/model/dotcomrendering/ElementsEnhancer.scala @@ -2,50 +2,55 @@ package model.dotcomrendering import play.api.libs.json.{Json, _} -object ElementsEnhancer { +/** + * The `ElementsEnhancer` object provides functions to enhance JSON representations of elements used in Dotcom Rendering. + * It adds unique identifiers to elements, as expected by the DCR schemas. More information on the decision for this can be found in PageElement-Identifiers.md or by searching for "03feb394-a17d-4430-8384-edd1891e0d01" + * + */ - // Note: - // In the file PageElement-Identifiers.md you will find a discussion of identifiers used by PageElements - // Also look for "03feb394-a17d-4430-8384-edd1891e0d01" +object ElementsEnhancer { def enhanceElement(element: JsValue): JsValue = { + // Add an elementId to the element val elementWithId = element.as[JsObject] ++ Json.obj("elementId" -> java.util.UUID.randomUUID.toString) + // Extract element type val elementType = elementWithId.value("_type").as[String] - val elementIsList = elementType == "model.dotcomrendering.pageElements.ListBlockElement" - val elementIsTimeline = elementType == "model.dotcomrendering.pageElements.TimelineBlockElement" + // If element has further nesting, continue to enhance. otherwise, return the enhanced element + elementType match { + case "model.dotcomrendering.pageElements.ListBlockElement" => enhanceListBlockElement(elementWithId) + case "model.dotcomrendering.pageElements.TimelineBlockElement" => enhanceTimelineBlockElement(elementWithId) + case _ => elementWithId; + } - if (elementIsList) { - val listItems = elementWithId.value("items").as[JsArray] - val listItemsWithIds = listItems.value.map { item => - val obj = item.as[JsObject] - obj ++ Json.obj("elements" -> enhanceElements(obj.value("elements"))) - } - elementWithId ++ Json.obj("items" -> listItemsWithIds) - } else if (elementIsTimeline) { - val sectionsList = elementWithId.value("sections").as[List[JsObject]] - val sectionListWithIds = sectionsList.map { section => - val eventList = section.value("events").as[List[JsObject]] - val eventListWithIds = eventList.map { event => - val bodyList = event.value("body").as[JsArray] - val bodyListWithIds = bodyList.value.map(currentBlock => { - enhanceElement(currentBlock) - }) - event ++ Json.obj("body" -> bodyListWithIds) - } - section ++ Json.obj("events" -> eventListWithIds) + } + def enhanceListBlockElement(elementWithId: JsObject): JsObject = { + val listItems = elementWithId.value("items").as[JsArray] + val listItemsWithIds = listItems.value.map { item => + val obj = item.as[JsObject] + obj ++ Json.obj("elements" -> enhanceElements(obj.value("elements"))) + } + elementWithId ++ Json.obj("items" -> listItemsWithIds) + } + + def enhanceTimelineBlockElement(element: JsObject): JsObject = { + val sectionsList = element.value("sections").as[List[JsObject]] + val sectionsListWithIds = sectionsList.map { section => + val eventsList = section.value("events").as[List[JsObject]] + val eventsListWithIds = eventsList.map { event => + val bodyElementsWithIds = enhanceElements(event.value("body").as[JsArray]) + event.as[JsObject] ++ Json.obj("body" -> bodyElementsWithIds) } - elementWithId ++ Json.obj("sections" -> sectionListWithIds) - } else { - elementWithId + section.as[JsObject] ++ Json.obj("events" -> eventsListWithIds) } + element ++ Json.obj("sections" -> sectionsListWithIds) } def enhanceElements(elements: JsValue): IndexedSeq[JsValue] = { elements.as[JsArray].value.map(element => enhanceElement(element)) }.toIndexedSeq - def enhanceObjectWithElementsAtDepth1(obj: JsValue): JsValue = { + def enhanceObjectWithElements(obj: JsValue): JsValue = { obj.asOpt[JsObject] match { case Some(o) => val elements = o.value("elements") @@ -54,21 +59,21 @@ object ElementsEnhancer { } } - def enhanceObjectsWithElementsAtDepth1(objs: JsValue): IndexedSeq[JsValue] = { - objs.as[JsArray].value.map(obj => enhanceObjectWithElementsAtDepth1(obj)) + def enhanceObjectsWithElements(objs: JsValue): IndexedSeq[JsValue] = { + objs.as[JsArray].value.map(obj => enhanceObjectWithElements(obj)) }.toIndexedSeq def enhanceBlocks(obj: JsObject): JsObject = { obj ++ - Json.obj("blocks" -> enhanceObjectsWithElementsAtDepth1(obj.value("blocks"))) + Json.obj("blocks" -> enhanceObjectsWithElements(obj.value("blocks"))) } def enhanceDcrObject(obj: JsObject): JsObject = { obj ++ - Json.obj("blocks" -> enhanceObjectsWithElementsAtDepth1(obj.value("blocks"))) ++ + Json.obj("blocks" -> enhanceObjectsWithElements(obj.value("blocks"))) ++ Json.obj("mainMediaElements" -> enhanceElements(obj.value("mainMediaElements"))) ++ - Json.obj("keyEvents" -> enhanceObjectsWithElementsAtDepth1(obj.value("keyEvents"))) ++ - Json.obj("pinnedPost" -> enhanceObjectWithElementsAtDepth1(obj.value("pinnedPost"))) ++ + Json.obj("keyEvents" -> enhanceObjectsWithElements(obj.value("keyEvents"))) ++ + Json.obj("pinnedPost" -> enhanceObjectWithElements(obj.value("pinnedPost"))) ++ Json.obj("promotedNewsletter" -> obj.value("promotedNewsletter")) } } diff --git a/common/app/model/dotcomrendering/pageElements/PageElement.scala b/common/app/model/dotcomrendering/pageElements/PageElement.scala index 4fb6c3d9073..be45f3b6e79 100644 --- a/common/app/model/dotcomrendering/pageElements/PageElement.scala +++ b/common/app/model/dotcomrendering/pageElements/PageElement.scala @@ -1481,7 +1481,6 @@ object PageElement { }.toList case Timeline => - println("inside timeline") element.timelineTypeData.map { timelineTypeData => TimelineBlockElement( sections = makeTimelineSection(