Generate tag overview, add file action

This commit is contained in:
Christoph Hagen
2025-01-05 09:21:21 +01:00
parent 0dca633805
commit 01baf560ee
27 changed files with 501 additions and 137 deletions

View File

@ -1,10 +1,78 @@
private struct TagData {
let url: String
let title: String
let localized: LocalizedTag
init(tag: Tag, language: ContentLanguage) {
let localized = tag.localized(in: language)
self.url = tag.absoluteUrl(in: language)
self.title = localized.linkPreviewTitle ?? localized.name
self.localized = localized
}
}
extension TagData: Comparable {
static func < (lhs: TagData, rhs: TagData) -> Bool {
lhs.title < rhs.title
}
static func == (lhs: TagData, rhs: TagData) -> Bool {
lhs.title == rhs.title
}
}
private struct TagHeaderContent {
let language: ContentLanguage
let title: String
let description: String?
let iconUrl: String
let links: [NavigationBar.Link]
let headers: Set<HeaderElement>
let baseUrl: String
let localizedBaseUrl: String
private func url(pageNumber: Int) -> String {
baseUrl + "/\(pageNumber)"
}
func fileUrl(pageNumber: Int) -> String {
url(pageNumber: pageNumber) + ".html"
}
func pageHeader(pageNumber: Int) -> PageHeader {
.init(
language: language,
title: title,
description: description,
iconUrl: iconUrl,
languageButton: .init(
text: language.next.rawValue,
url: localizedBaseUrl + "/\(pageNumber)"),
links: links,
headers: headers,
icons: [])
}
}
final class TagOverviewGenerator {
let content: Content
let language: ContentLanguage
let results: PageGenerationResults
init(content: Content, language: ContentLanguage, results: PageGenerationResults) {
@ -13,49 +81,67 @@ final class TagOverviewGenerator {
self.results = results
}
func generatePage(tags: [Tag], overview: TagOverviewPage) {
let iconUrl = content.settings.navigation.localized(in: language).rootUrl
let languageUrl = overview.absoluteUrl(in: language.next)
let languageButton = NavigationBar.Link(
text: language.next.rawValue,
url: languageUrl)
func generatePages(tags: [Tag], overview: TagOverviewPage) {
let localized = overview.localized(in: language)
let pageHeader = PageHeader(
let header = TagHeaderContent(
language: language,
title: localized.linkPreviewTitle ?? localized.title,
description: localized.linkPreviewDescription,
iconUrl: iconUrl,
languageButton: languageButton,
iconUrl: content.settings.navigation.localized(in: language).rootUrl,
links: content.navigationBar(in: language),
headers: content.defaultPageHeaders,
icons: [])
baseUrl: overview.absoluteUrl(in: language),
localizedBaseUrl: overview.absoluteUrl(in: language.next))
// Sort tags by title
let tagData = tags.map {
TagData(tag: $0, language: language)
}.sorted { $0.title }
let totalCount = tagData.count
guard totalCount > 0 else {
// Create one empty page
generatePage(tags: [], header: header, page: 1, totalPages: 1)
return
}
let tagsPerPage = content.settings.posts.postsPerPage
let numberOfPages = (totalCount + tagsPerPage - 1) / tagsPerPage // Round up
for pageIndex in 1...numberOfPages {
let startIndex = (pageIndex - 1) * tagsPerPage
let endIndex = min(pageIndex * tagsPerPage, totalCount)
let tagsOnPage = tagData[startIndex..<endIndex]
generatePage(tags: tagsOnPage, header: header, page: pageIndex, totalPages: numberOfPages)
}
}
private func generatePage(tags: ArraySlice<TagData>, header: TagHeaderContent, page pageNumber: Int, totalPages: Int) {
let pageHeader = header.pageHeader(pageNumber: pageNumber)
let page = GenericPage(
header: pageHeader,
additionalFooter: "") { content in
content += "<h1>\(localized.title)</h1>"
content += "<h1>\(header.title)</h1>"
for tag in tags {
let localized = tag.localized(in: self.language)
let url = tag.absoluteUrl(in: self.language)
let title = localized.name
let description = localized.description ?? ""
let image = self.makePageImage(item: localized)
let description = tag.localized.description ?? ""
let image = self.makePageImage(item: tag.localized)
content += RelatedPageLink(
title: title,
title: tag.title,
description: description,
url: url,
url: tag.url,
image: image)
.content
.content
}
if totalPages > 1 {
content += PostFeedPageNavigation(
linkPrefix: header.baseUrl,
currentPage: pageNumber,
numberOfPages: totalPages).content
}
// if totalPages > 1 {
// content += PostFeedPageNavigation(currentPage: pageNumber, numberOfPages: totalPages, language: language).content
// }
}
let fileContent = page.content
let url = overview.absoluteUrl(in: language) + ".html"
let url = header.fileUrl(pageNumber: pageNumber)
guard content.storage.write(fileContent, to: url) else {
results.unsavedOutput(url, source: .tagOverview)