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 let placeholder: String private let fullDateFormatter: DateFormatter private let month: DateFormatter private let day: DateFormatter var language: String { topBar.language } // MARK: Thumbnails func thumbnail(style: ThumbnailStyle) -> ThumbnailTemplate { switch style { case .large: return factory.largeThumbnail case .square: return factory.squareThumbnail case .small: return factory.smallThumbnail } } // MARK: Pages var overviewPage: OverviewPageTemplate { factory.overviewPage } var contentPage: ContentPageTemplate { factory.contentPage } init(factory: TemplateFactory, language: String, site: Site, imageProcessor: ImageProcessor) throws { self.author = site.metadata.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.elements.map { PrefilledTopBarTemplate.SectionInfo( id: $0.sectionId, name: $0.title(for: language), url: "\($0.path)/\(language).html") } let metadata = site.localized(for: language) let title = site.metadata.topBarTitle ?? metadata.linkPreviewTitle self.topBar = try .init( template: factory.topBar, language: language, sections: sections, topBarWebsiteTitle: title) self.pageHead = PageHeadGenerator( factory: factory, imageProcessor: imageProcessor) self.overviewSection = OverviewSectionGenerator( factory: factory, imageProcessor: imageProcessor) self.placeholder = factory.placeholder.generate([ .title: metadata.placeholderTitle, .text: metadata.placeholderText]) } // MARK: Content func makeBackLink(text: String, language: String) -> String { let content: [BackNavigationTemplate.Key : String] = [ .text: text, .url: "../\(language).html" ] return backNavigation.generate(content) } #warning("Move HTML code to single location") func makePrevText(_ text: String) -> String { "\(text)" } func makeNextText(_ text: String) -> String { "\(text)" } func makeDateString(start: Date, end: Date?) -> String { 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: ",") } }