in common/app/common/TrailsToShowcase.scala [127:243]
def asSingleStoryPanel(content: PressedContent): Either[Seq[String], SingleStoryPanel] = {
val proposedTitle = titleOfLengthFrom(MaxSinglePanelTitleLength, content)
val proposedPanelTitle = panelTitleFrom(content)
val proposedWebUrl = webUrl(content).map(Right(_)).getOrElse(Left(Seq("Trail had no web url")))
val proposedImageUrl = singleStoryImageUrlFor(content)
// Decide which type of panel to produce
// If supporting content is present try to map into into a related articles article group for a Related Articles panel
// If then try to produce a bullet item list for a Bullets panel
// This might get more interesting if we implement Key Moments but the principal is the same.
val supportingContent = content match {
case curatedContent: CuratedContent =>
curatedContent.supportingContent
case _ => Seq.empty
}
val isRelatedArticlePanel = supportingContent.nonEmpty
val proposedArticleGroup = {
if (isRelatedArticlePanel) {
if (supportingContent.nonEmpty) {
makeArticlesFrom(
supportingContent,
2,
"Related Article",
MaxRelatedArticleTitleLength,
MaxRelatedArticleOverlineLength,
).fold(
{ l =>
Left(l)
},
{ articles: Seq[Article] =>
Right(Some(ArticleGroup(role = "RELATED_CONTENT", articles = articles)))
},
)
} else {
Right(None)
}
} else {
// Not a related article panel so we will gracefully opt out
Right(None)
}
}
val proposedBulletList = {
if (!isRelatedArticlePanel) {
content.card.trailText
.map(extractBulletsFrom)
.getOrElse(Left(Seq("No trail text available to create a bullet list from")))
.fold(
{ l => Left(l) },
{ bulletList =>
Right(Some(bulletList))
},
)
} else {
Right(None)
}
}
val proposedOverline = overlineFrom(content, MaxOverlineLength)
val proposedSummary = {
if (isRelatedArticlePanel) {
extractRelatedArticlePanelSummaryFrom(content)
} else {
Right(None)
}
}
val proposedPublicationDate =
content.card.webPublicationDateOption.toRight(Seq("Could not find web publication date for panel"))
// Collect all mandatory values; any missing will result in a None entry
val maybePanel = for {
title <- proposedTitle.toOption
maybePanelTitle <- proposedPanelTitle.toOption
webUrl <- proposedWebUrl.toOption
imageUrl <- proposedImageUrl.toOption
maybeOverline <- proposedOverline.toOption
bulletList <- proposedBulletList.toOption
articleGroup <- proposedArticleGroup.toOption
summary <- proposedSummary.toOption
published <- proposedPublicationDate.toOption
} yield {
// Build a panel
SingleStoryPanel(
title = title,
panelTitle = maybePanelTitle,
link = webUrl,
author = bylineFrom(content),
overline = maybeOverline,
imageUrl = imageUrl,
published = published,
updated = content.card.lastModifiedOption.getOrElse(published),
articleGroup = articleGroup,
bulletList = bulletList,
summary = summary,
)
}
maybePanel.map { Right(_) }.getOrElse {
// Round up all of the potential sources of hard errors and collect their objections
Left(
Seq(
proposedTitle,
proposedPanelTitle,
proposedWebUrl,
proposedImageUrl,
proposedOverline,
proposedArticleGroup,
proposedBulletList,
proposedSummary,
proposedPublicationDate,
).flatMap(_.left.toOption).flatten,
)
}
}