Extract as much HTML as possible from ArticleRenderer

This commit is contained in:
Maurice Parker 2021-09-17 14:10:33 -05:00
parent ad9c059b8b
commit 48b2a5ca0f
3 changed files with 123 additions and 52 deletions

View File

@ -41,6 +41,69 @@ struct ArticleRenderer {
private let title: String
private let body: String
private let baseURL: String?
private static let longDateTimeFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .medium
return formatter
}()
private static let mediumDateTimeFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
return formatter
}()
private static let shortDateTimeFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .short
return formatter
}()
private static let longDateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .none
return formatter
}()
private static let mediumDateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
return formatter
}()
private static let shortDateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .none
return formatter
}()
private static let longTimeFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .none
formatter.timeStyle = .long
return formatter
}()
private static let mediumTimeFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .none
formatter.timeStyle = .medium
return formatter
}()
private static let shortTimeFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .none
formatter.timeStyle = .short
return formatter
}()
private init(article: Article?, extractedArticle: ExtractedArticle?, theme: ArticleTheme) {
self.article = article
@ -135,13 +198,6 @@ private extension ArticleRenderer {
return articleTheme.template ?? ArticleRenderer.defaultTemplate
}
func titleOrTitleLink() -> String {
if let link = article?.preferredLink {
return title.htmlByAddingLink(link)
}
return title
}
func articleSubstitutions() -> [String: String] {
var d = [String: String]()
@ -150,15 +206,16 @@ private extension ArticleRenderer {
return d
}
let title = titleOrTitleLink()
d["title"] = title
d["preferred_link"] = article.preferredLink ?? ""
if let externalLink = article.externalURL, externalLink != article.preferredLink {
let displayLink = externalLink.strippingHTTPOrHTTPSScheme
let regarding = NSLocalizedString("Link", comment: "Link")
let externalLinkString = "\(regarding): <a href=\"\(externalLink)\">\(displayLink)</a>"
d["external_link"] = externalLinkString
d["external_link_label"] = NSLocalizedString("Link:", comment: "Link")
d["external_link_stripped"] = externalLink.strippingHTTPOrHTTPSScheme
d["external_link"] = externalLink
} else {
d["external_link_label"] = ""
d["external_link_stripped"] = ""
d["external_link"] = ""
}
@ -175,7 +232,7 @@ private extension ArticleRenderer {
d["avatar_src"] = imageIconURLString
}
else {
d["avatars"] = ""
d["avatar_src"] = ""
}
if self.title.isEmpty {
@ -184,33 +241,22 @@ private extension ArticleRenderer {
d["dateline_style"] = "articleDateline"
}
var feedLink = ""
if let feedTitle = article.webFeed?.nameForDisplay {
feedLink = feedTitle
if let feedURL = article.webFeed?.homePageURL {
feedLink = feedLink.htmlByAddingLink(feedURL, className: "feedLink")
}
}
d["feedlink"] = feedLink
let datePublished = article.logicalDatePublished
let longDate = dateString(datePublished, .long, .medium)
let mediumDate = dateString(datePublished, .medium, .short)
let shortDate = dateString(datePublished, .short, .short)
if let permalink = article.url {
d["date_long"] = longDate.htmlByAddingLink(permalink)
d["date_medium"] = mediumDate.htmlByAddingLink(permalink)
d["date_short"] = shortDate.htmlByAddingLink(permalink)
}
else {
d["date_long"] = longDate
d["date_medium"] = mediumDate
d["date_short"] = shortDate
}
d["feed_link_title"] = article.webFeed?.nameForDisplay ?? ""
d["feed_link"] = article.webFeed?.homePageURL ?? ""
d["byline"] = byline()
let datePublished = article.logicalDatePublished
d["datetime_long"] = Self.longDateTimeFormatter.string(from: datePublished)
d["datetime_medium"] = Self.mediumDateTimeFormatter.string(from: datePublished)
d["datetime_short"] = Self.shortDateTimeFormatter.string(from: datePublished)
d["date_long"] = Self.longDateFormatter.string(from: datePublished)
d["date_medium"] = Self.mediumDateFormatter.string(from: datePublished)
d["date_short"] = Self.shortDateFormatter.string(from: datePublished)
d["time_long"] = Self.longTimeFormatter.string(from: datePublished)
d["time_medium"] = Self.mediumTimeFormatter.string(from: datePublished)
d["time_short"] = Self.shortTimeFormatter.string(from: datePublished)
return d
}
@ -265,13 +311,6 @@ private extension ArticleRenderer {
return byline
}
func dateString(_ date: Date, _ dateStyle: DateFormatter.Style, _ timeStyle: DateFormatter.Style) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = dateStyle
dateFormatter.timeStyle = timeStyle
return dateFormatter.string(from: date)
}
#if os(iOS)
func styleSubstitutions() -> [String: String] {
var d = [String: String]()

View File

@ -1,15 +1,47 @@
<!-- Template Variables
title: The title of the article
preferred_link: The best link to associate with the article for linking out.
external_link_label: A localized label for the external link.
external_link_stripped: The external link minus the scheme. Useful for displaying the external link.
external_link: The external link of the article if there is one provided by the author.
feed_link_title: The name of the feed associated with this article.
feed_link: The URL of the feed associated with this article.
byline: HTML that combines all the authors and links to them if available.
avatar_src: The image source URL for the feed icon / avatar.
dateline_style: Either "articleDateline" or "articleDatelineTitle" depending on if the title was populated or not.
datetime_long: Long version of a combined publish date and time.
datetime_medium: Medium length version of a combined publish date and time.
datetime_short: Short version of a combined publish date and time.
date_long: Long version of the publish date.
date_medium: Medium version of the publish date.
date_short: Long version of the publish date.
time_long: Long version of the publish time.
time_medium: Medium version of the publish time.
time_short: Long version of the publish time.
text_size_class: The size class that the user has selected in Preferences for article text.
body: The body of the article.
-->
<header class="headerContainer">
<table cellpadding=0 cellspacing=0 border=0 class="headerTable">
<tr>
<td class="header leftAlign"><span class="feedlink">[[feedlink]]</span><br />[[byline]]</td>
<td class="header leftAlign"><a class="feedlink" href="[[feed_link]]">[[feed_link_title]]</a><br />[[byline]]</td>
<td class="header rightAlign avatar"><img id="nnwImageIcon" src="[[avatar_src]]" height=48 width=48 /></td>
</tr>
</table>
</header>
<article>
<div class="articleTitle"><h1>[[title]]</h1></div>
<div class="[[dateline_style]]">[[date_medium]]</div>
<div class="externalLink">[[external_link]]</div>
<div class="articleTitle"><h1><a href="[[preferred_link]]">[[title]]</a></h1></div>
<div class="[[dateline_style]]"><a href="[[preferred_link]]">[[datetime_medium]]</a></div>
<div class="externalLink">[[external_link_label]] <a href="[[external_link]]">[[external_link_stripped]]</a></div>
<div id="bodyContainer" class="articleBody [[text_size_class]]">[[body]]</div>
</article>

View File

@ -1,15 +1,15 @@
<header class="headerContainer">
<table cellpadding=0 cellspacing=0 border=0 class="headerTable">
<tr>
<td class="header leftAlign"><span class="feedlink">[[feedlink]]</span><br />[[byline]]</td>
<td class="header leftAlign"><a class="feedlink" href="[[feed_link]]">[[feed_link_title]]</a><br />[[byline]]</td>
<td class="header rightAlign avatar"><img id="nnwImageIcon" src="[[avatar_src]]" height=48 width=48 /></td>
</tr>
</table>
</header>
<article>
<div class="articleTitle"><h1>[[title]]</h1></div>
<div class="[[dateline_style]]">[[date_medium]]</div>
<div class="externalLink">[[external_link]]</div>
<div class="articleTitle"><h1><a href="[[preferred_link]]">[[title]]</a></h1></div>
<div class="[[dateline_style]]"><a href="[[preferred_link]]">[[datetime_medium]]</a></div>
<div class="externalLink">[[external_link_label]] <a href="[[external_link]]">[[external_link_stripped]]</a></div>
<div id="bodyContainer" class="articleBody [[text_size_class]]">[[body]]</div>
</article>