103 lines
3.2 KiB
Swift
103 lines
3.2 KiB
Swift
import Foundation
|
|
|
|
struct WebsiteGeneratorConfiguration {
|
|
|
|
let language: ContentLanguage
|
|
|
|
let postsPerPage: Int
|
|
|
|
let postFeedTitle: String
|
|
|
|
let postFeedDescription: String
|
|
|
|
let postFeedUrlPrefix: String
|
|
}
|
|
|
|
final class WebsiteGenerator {
|
|
|
|
let language: ContentLanguage
|
|
|
|
let content: Content
|
|
|
|
let postsPerPage: Int
|
|
|
|
let postFeedTitle: String
|
|
|
|
let postFeedDescription: String
|
|
|
|
let postFeedUrlPrefix: String
|
|
|
|
init(content: Content, configuration: WebsiteGeneratorConfiguration) {
|
|
self.content = content
|
|
self.language = configuration.language
|
|
self.postsPerPage = configuration.postsPerPage
|
|
self.postFeedTitle = configuration.postFeedTitle
|
|
self.postFeedDescription = configuration.postFeedDescription
|
|
self.postFeedUrlPrefix = configuration.postFeedUrlPrefix
|
|
}
|
|
|
|
func generateWebsite() {
|
|
createPostFeedPages()
|
|
}
|
|
|
|
private func createPostFeedPages() {
|
|
let totalCount = content.posts.count
|
|
guard totalCount > 0 else { return }
|
|
|
|
let navBarData = createNavigationBarData()
|
|
|
|
let numberOfPages = (totalCount + postsPerPage - 1) / postsPerPage // Round up
|
|
for pageIndex in 1...numberOfPages {
|
|
let startIndex = (pageIndex - 1) * postsPerPage
|
|
let endIndex = min(pageIndex * postsPerPage, totalCount)
|
|
let postsOnPage = content.posts[startIndex..<endIndex]
|
|
createPostFeedPage(pageIndex, pageCount: numberOfPages, posts: postsOnPage, bar: navBarData)
|
|
}
|
|
}
|
|
|
|
private func createNavigationBarData() -> NavigationBarData {
|
|
let data = content.websiteData.localized(in: language)
|
|
let navigationItems: [NavigationBarLink] = content.websiteData.navigationTags.map {
|
|
let localized = $0.localized(in: language)
|
|
return .init(text: localized.name, url: localized.urlComponent)
|
|
}
|
|
return NavigationBarData(
|
|
navigationIconPath: "/assets/icons/ch.svg",
|
|
iconDescription: data.iconDescription,
|
|
navigationItems: navigationItems)
|
|
}
|
|
|
|
private func createPostFeedPage(_ pageIndex: Int, pageCount: Int, posts: ArraySlice<Post>, bar: NavigationBarData) {
|
|
let posts = posts.map { $0.feedEntry(for: language) }
|
|
|
|
let feed = PageInFeed(
|
|
language: language,
|
|
title: postFeedTitle,
|
|
description: postFeedDescription,
|
|
navigationBarData: bar,
|
|
pageNumber: pageIndex,
|
|
totalPages: pageCount,
|
|
posts: posts)
|
|
let fileContent = feed.content
|
|
|
|
if pageIndex == 1 {
|
|
save(fileContent, to: "\(postFeedUrlPrefix).html")
|
|
} else {
|
|
save(fileContent, to: "\(postFeedUrlPrefix)-\(pageIndex).html")
|
|
}
|
|
}
|
|
|
|
private func save(_ content: String, to relativePath: String) {
|
|
Content.accessFolderFromBookmark(key: Storage.outputPathBookmarkKey) { folder in
|
|
let outputFile = folder.appendingPathComponent(relativePath, isDirectory: false)
|
|
do {
|
|
try content
|
|
.data(using: .utf8)!
|
|
.write(to: outputFile)
|
|
} catch {
|
|
print("Failed to save: \(error)")
|
|
}
|
|
}
|
|
}
|
|
}
|