import Foundation import Ink struct LocalizedSiteTemplate { let author: String let factory: TemplateFactory let topBar: PrefilledTopBarTemplate // MARK: Site Elements var backNavigation: BackNavigationTemplate { factory.backNavigation } let pageHead: PageHeadGenerator let overviewSection: OverviewSectionGenerator private let fullDateFormatter: DateFormatter private let month: DateFormatter private let day: DateFormatter var language: String { topBar.language } // MARK: Pages var page: PageTemplate { factory.page } init(factory: TemplateFactory, language: String, site: Element) throws { self.author = site.author self.factory = factory let df = DateFormatter() df.dateStyle = .long df.timeStyle = .none df.locale = Locale(identifier: language) self.fullDateFormatter = df let df2 = DateFormatter() df2.dateFormat = "MMMM" df2.locale = Locale(identifier: language) self.month = df2 let df3 = DateFormatter() df3.dateFormat = "dd" df3.locale = Locale(identifier: language) self.day = df3 let sections = site.sortedItems.map { PrefilledTopBarTemplate.SectionInfo( name: $0.title(for: language), url: "\($0.path)/\(language).html") } self.topBar = try .init( factory: factory, language: language, sections: sections, topBarWebsiteTitle: site.topBarTitle) self.pageHead = PageHeadGenerator( factory: factory) self.overviewSection = OverviewSectionGenerator( factory: factory) } // MARK: Content func makePlaceholder(metadata: Element.LocalizedMetadata) -> String { factory.placeholder.generate([ .title: metadata.placeholderTitle, .text: metadata.placeholderText]) } func makeBackLink(text: String, language: String) -> String { let content: [BackNavigationTemplate.Key : String] = [ .text: text, .url: "../\(language).html" ] return backNavigation.generate(content) } func makeDateString(start: Date?, end: Date?) -> String { guard let start = start else { return "" } guard let end = end else { return fullDateFormatter.string(from: start) } switch language { case "de": return makeGermanDateString(start: start, end: end) case "en": fallthrough default: return makeEnglishDateString(start: start, end: end) } } private func makeGermanDateString(start: Date, end: Date) -> String { guard Calendar.current.isDate(start, equalTo: end, toGranularity: .year) else { return "\(fullDateFormatter.string(from: start)) - \(fullDateFormatter.string(from: end))" } let startDay = day.string(from: start) guard Calendar.current.isDate(start, equalTo: end, toGranularity: .month) else { let startMonth = month.string(from: start) return "\(startDay). \(startMonth) - \(fullDateFormatter.string(from: end))" } return "\(startDay). - \(fullDateFormatter.string(from: end))" } private func makeEnglishDateString(start: Date, end: Date) -> String { guard Calendar.current.isDate(start, equalTo: end, toGranularity: .year) else { return "\(fullDateFormatter.string(from: start)) - \(fullDateFormatter.string(from: end))" } guard Calendar.current.isDate(start, equalTo: end, toGranularity: .month) else { let startDay = day.string(from: start) let startMonth = month.string(from: start) return "\(startMonth) \(startDay) - \(fullDateFormatter.string(from: end))" } return fullDateFormatter.string(from: start) .insert(" - \(day.string(from: end))", beforeLast: ",") } func makeHeaderContent(page: Element, metadata: Element.LocalizedMetadata, language: String) -> [HeaderKey : String] { let backText = page.backLinkText(for: language) var content = [HeaderKey : String]() if let backText = backText.nonEmpty { content[.backLink] = makeBackLink(text: backText, language: language) } if let suffix = metadata.titleSuffix { content[.title] = factory.html.make(title: metadata.title, suffix: suffix) } else { content[.title] = metadata.title } content[.subtitle] = metadata.subtitle content[.date] = makeDateString(start: page.date, end: page.endDate) return content } }