First version
This commit is contained in:
167
WebsiteGenerator/Templates/Filled/LocalizedSiteTemplate.swift
Normal file
167
WebsiteGenerator/Templates/Filled/LocalizedSiteTemplate.swift
Normal file
@@ -0,0 +1,167 @@
|
||||
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 {
|
||||
"<span class=\"icon-back\"></span>\(text)"
|
||||
}
|
||||
|
||||
func makeNextText(_ text: String) -> String {
|
||||
"\(text)<span class=\"icon-next\"></span>"
|
||||
}
|
||||
|
||||
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: ",")
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,58 @@
|
||||
import Foundation
|
||||
|
||||
struct PrefilledTopBarTemplate {
|
||||
|
||||
let language: String
|
||||
|
||||
let sections: [SectionInfo]
|
||||
|
||||
let topBarWebsiteTitle: String
|
||||
|
||||
private let topBar: TopBarTemplate
|
||||
|
||||
init(template: TopBarTemplate, language: String, sections: [SectionInfo], topBarWebsiteTitle: String) throws {
|
||||
self.topBar = template
|
||||
self.language = language
|
||||
self.sections = sections
|
||||
self.topBarWebsiteTitle = topBarWebsiteTitle
|
||||
}
|
||||
|
||||
func generate(section: String?, languageButton: String?) -> String {
|
||||
var content = [TopBarTemplate.Key : String]()
|
||||
content[.title] = topBarWebsiteTitle
|
||||
content[.titleLink] = topBarWebsiteTitle(language: language)
|
||||
content[.elements] = elements(activeSection: section)
|
||||
content[.languageButton] = languageButton.unwrapped(topBarLanguageButton) ?? ""
|
||||
return topBar.generate(content)
|
||||
}
|
||||
|
||||
private func elements(activeSection: String?) -> String {
|
||||
sections
|
||||
.map {
|
||||
topBarNavigationLink(url: $0.url, text: $0.name, isActive: activeSection == $0.id)
|
||||
}
|
||||
.joined(separator: "\n")
|
||||
}
|
||||
|
||||
#warning("Move HTML code to single location")
|
||||
private func topBarWebsiteTitle(language: String) -> String {
|
||||
"/\(language).html"
|
||||
}
|
||||
|
||||
private func topBarLanguageButton(_ language: String) -> String {
|
||||
"<a href=\"\(language).html\">\(language)</a>"
|
||||
}
|
||||
|
||||
private func topBarNavigationLink(url: String, text: String, isActive: Bool) -> String {
|
||||
"<a\(isActive ? " class=\"active\"" : "") href=\"/\(url)\">\(text)</a>"
|
||||
}
|
||||
|
||||
struct SectionInfo {
|
||||
|
||||
let id: String
|
||||
|
||||
let name: String
|
||||
|
||||
let url: String
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user