113 lines
4.9 KiB
Swift
113 lines
4.9 KiB
Swift
import Foundation
|
|
|
|
struct OverviewSectionGenerator {
|
|
|
|
private let factory: TemplateFactory
|
|
|
|
private let generator: ThumbnailListGenerator
|
|
|
|
private let siteRoot: Element
|
|
|
|
private let results: GenerationResultsHandler
|
|
|
|
init(factory: TemplateFactory, siteRoot: Element, results: GenerationResultsHandler) {
|
|
self.factory = factory
|
|
self.siteRoot = siteRoot
|
|
self.results = results
|
|
self.generator = ThumbnailListGenerator(factory: factory, results: results)
|
|
}
|
|
|
|
func generate(sections: [Element], in parent: Element, language: String, sectionItemCount: Int) -> String {
|
|
let content = sectionsContent(sections, in: parent, language: language, sectionItemCount: sectionItemCount)
|
|
let firstSection = firstSectionContent(for: parent, language: language, sectionItemCount: sectionItemCount)
|
|
return firstSection + content
|
|
}
|
|
|
|
private func firstSectionContent(for element: Element, language: String, sectionItemCount: Int) -> String {
|
|
guard element.needsFirstSection else {
|
|
return ""
|
|
}
|
|
let metadata = element.localized(for: language)
|
|
var result = ""
|
|
if element.showMostRecentSection {
|
|
let shownElements = element.mostRecentElements(4).enumerated().map { (number, child) in
|
|
makeSlideshowItem(child, parent: element, language: language, number: number)
|
|
}
|
|
let title = metadata.mostRecentTitle ?? "Recent"
|
|
result = factory.slideshow.generate([.content: shownElements.joined(separator: "\n"), .title: title])
|
|
}
|
|
if !element.featuredPages.isEmpty {
|
|
let elements = element.featuredPages.compactMap { id -> Element? in
|
|
guard let linked = siteRoot.find(id) else {
|
|
results.warning("Unknown id '\(id)' in 'featuredPages'", source: element.path)
|
|
return nil
|
|
}
|
|
return linked
|
|
}.prefix(4).enumerated().map { number, page in
|
|
makeSlideshowItem(page, parent: element, language: language, number: number)
|
|
}
|
|
let title = metadata.featuredTitle ?? "Featured"
|
|
result += factory.slideshow.generate([.content: elements.joined(separator: "\n"), .title: title])
|
|
}
|
|
return factory.slideshows.generate([.content : result])
|
|
}
|
|
|
|
private func makeSlideshowItem(_ item: Element, parent: Element, language: String, number: Int) -> String {
|
|
let metadata = item.localized(for: language)
|
|
var content = [SlideshowImageTemplate.Key : String]()
|
|
content[.number] = "\(number + 1)"
|
|
content[.altText] = metadata.linkPreviewDescription
|
|
|
|
if item.state.hasThumbnailLink {
|
|
let fullPageUrl = item.fullPageUrl(for: language)
|
|
let relativePageUrl = parent.relativePathToFileWithPath(fullPageUrl)
|
|
content[.url] = "href=\"\(relativePageUrl)\""
|
|
}
|
|
|
|
// Image already assumed to be generated
|
|
let (_, thumbnailDestPath) = item.thumbnailFilePath(for: language)
|
|
let thumbnailDestNoExtension = thumbnailDestPath.dropAfterLast(".")
|
|
content[.image] = parent.relativePathToFileWithPath(thumbnailDestNoExtension)
|
|
|
|
if let suffix = metadata.thumbnailSuffix {
|
|
content[.title] = factory.html.make(title: metadata.title, suffix: suffix)
|
|
} else {
|
|
content[.title] = metadata.title
|
|
}
|
|
let path = item.makePath(language: language, from: siteRoot)
|
|
content[.subtitle] = factory.pageLink.makePath(components: path)
|
|
return factory.slideshowImage.generate(content)
|
|
}
|
|
|
|
private func sectionsContent(_ sections: [Element], in parent: Element, language: String, sectionItemCount: Int) -> String {
|
|
sections.map { section in
|
|
let metadata = section.localized(for: language)
|
|
let fullUrl = section.fullPageUrl(for: language)
|
|
let relativeUrl = parent.relativePathToFileWithPath(fullUrl)
|
|
|
|
var content = [OverviewSectionTemplate.Key : String]()
|
|
content[.url] = relativeUrl
|
|
content[.title] = metadata.title
|
|
content[.items] = generator.generateContent(
|
|
items: section.itemsForOverview(sectionItemCount),
|
|
parent: parent,
|
|
language: language,
|
|
style: section.thumbnailStyle)
|
|
content[.more] = metadata.moreLinkText
|
|
|
|
return factory.overviewSection.generate(content)
|
|
}
|
|
.joined(separator: "\n")
|
|
}
|
|
|
|
func generate(section: Element, language: String) -> String {
|
|
var content = [OverviewSectionCleanTemplate.Key : String]()
|
|
content[.items] = generator.generateContent(
|
|
items: section.itemsForOverview(),
|
|
parent: section,
|
|
language: language,
|
|
style: section.thumbnailStyle)
|
|
return factory.overviewSectionClean.generate(content)
|
|
}
|
|
}
|