import Foundation final class PostListPageGenerator { let source: PostListPageGeneratorSource init(source: PostListPageGeneratorSource) { self.source = source } private var language: ContentLanguage { source.language } private var mainContentMaximumWidth: Int { source.content.settings.posts.contentWidth } private var postsPerPage: Int { source.content.settings.posts.postsPerPage } private func pageUrl(in language: ContentLanguage, pageNumber: Int) -> String { "\(source.pageUrlPrefix(for: language))/\(pageNumber).html" } func createPages(for posts: [Post]) { let totalCount = posts.count guard totalCount > 0 else { return } 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 = posts[startIndex..) { let posts: [FeedEntryData] = posts.map { post in let localized: LocalizedPost = post.localized(in: language) let linkUrl = post.linkedPage.map { FeedEntryData.Link( url: $0.absoluteUrl(in: language), text: language == .english ? "View" : "Anzeigen") // TODO: Add to settings } let tags: [FeedEntryData.Tag] = post.tags.filter { $0.isVisible }.map { tag in .init(name: tag.localized(in: language).name, url: tag.absoluteUrl(in: language)) } let images = localized.images.map(createFeedImage) return FeedEntryData( entryId: post.id, title: localized.title, textAboveTitle: post.dateText(in: language), link: linkUrl, tags: tags, text: localized.text.components(separatedBy: "\n"), images: images) } let feedPageGenerator = FeedPageGenerator(content: source.content, results: source.results) let languageButtonUrl = pageUrl(in: language.next, pageNumber: pageIndex) let fileContent = feedPageGenerator.generatePage( language: language, posts: posts, title: source.pageTitle, description: source.pageDescription, showTitle: source.showTitle, pageNumber: pageIndex, totalPages: pageCount, languageButtonUrl: languageButtonUrl) let filePath = pageUrl(in: language, pageNumber: pageIndex) guard save(fileContent, to: filePath) else { source.results.unsavedOutput(filePath, source: .feed) return } } private func createFeedImage(for image: FileResource) -> FeedEntryData.Image { source.results.requireImageSet(for: image, size: mainContentMaximumWidth) return .init( rawImagePath: image.absoluteUrl, width: mainContentMaximumWidth, height: mainContentMaximumWidth, altText: image.localized(in: language)) } private func save(_ content: String, to relativePath: String) -> Bool { source.content.storage.write(content, to: relativePath) } }