import Foundation final class PostListPageGenerator { private let language: ContentLanguage private let content: Content private let imageGenerator: ImageGenerator private let navigationBarLinks: [NavigationBar.Link] private let showTitle: Bool private let pageTitle: String private let pageDescription: String /// The url of the page, excluding the extension private let pageUrlPrefix: String init(language: ContentLanguage, content: Content, imageGenerator: ImageGenerator, navigationBarLinks: [NavigationBar.Link], showTitle: Bool, pageTitle: String, pageDescription: String, pageUrlPrefix: String) { self.language = language self.content = content self.imageGenerator = imageGenerator self.navigationBarLinks = navigationBarLinks self.showTitle = showTitle self.pageTitle = pageTitle self.pageDescription = pageDescription self.pageUrlPrefix = pageUrlPrefix } private var mainContentMaximumWidth: CGFloat { CGFloat(content.settings.posts.contentWidth) } private var postsPerPage: Int { content.settings.posts.postsPerPage } func createPages(for posts: [Post]) -> Bool { let totalCount = posts.count guard totalCount > 0 else { return true } 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.., bar: [NavigationBar.Link]) -> Bool { let posts: [FeedEntryData] = posts.map { post in let localized: LocalizedPost = post.localized(in: language) let linkUrl = post.linkedPage.map { FeedEntryData.Link( url: content.absoluteUrlToPage($0, language: 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: content.absoluteUrlToTag(tag, language: language)) } return FeedEntryData( entryId: post.id, title: localized.title, textAboveTitle: post.dateText(in: language), link: linkUrl, tags: tags, text: [localized.content], // TODO: Convert from markdown to html images: localized.images.map(createImageSet)) } let feed = PageInFeed( language: language, title: pageTitle, showTitle: showTitle, description: pageDescription, navigationBarLinks: bar, pageNumber: pageIndex, totalPages: pageCount, posts: posts) let fileContent = feed.content if pageIndex == 1 { return save(fileContent, to: "\(pageUrlPrefix).html") } else { return save(fileContent, to: "\(pageUrlPrefix)-\(pageIndex).html") } } private func createImageSet(for image: FileResource) -> FeedEntryData.Image { imageGenerator.generateImageSet( for: image.id, maxWidth: mainContentMaximumWidth, maxHeight: mainContentMaximumWidth) return .init( rawImagePath: content.absoluteUrlToFile(image), width: Int(mainContentMaximumWidth), height: Int(mainContentMaximumWidth), altText: image.getDescription(for: language)) } private func save(_ content: String, to relativePath: String) -> Bool { do { try self.content.storage.write(content: content, to: relativePath) return true } catch { print("Failed to write page \(relativePath)") return false } } }