Simplify images, tag overview

This commit is contained in:
Christoph Hagen
2025-01-04 08:44:26 +01:00
parent 4d4275e072
commit 22e7d9a05a
49 changed files with 603 additions and 509 deletions

View File

@ -0,0 +1,87 @@
import Foundation
final class FeedPageGenerator {
let results: PageGenerationResults
let content: Content
init(content: Content, results: PageGenerationResults) {
self.content = content
self.results = results
}
private func includeSwiper(in headers: inout Set<HeaderElement>) {
if let swiperCss = content.settings.posts.swiperCssFile {
headers.insert(.css(file: swiperCss, order: HeaderElement.swiperCssFileOrder))
results.require(file: swiperCss)
}
if let swiperJs = content.settings.posts.swiperJsFile {
headers.insert(.js(file: swiperJs, defer: true))
results.require(file: swiperJs)
}
}
func generatePage(language: ContentLanguage,
posts: [FeedEntryData],
title: String,
description: String?,
showTitle: Bool,
pageNumber: Int,
totalPages: Int,
languageButtonUrl: String,
linkPrefix: String) -> String {
var headers = content.defaultPageHeaders
var footer = ""
if posts.contains(where: { $0.images.count > 1 }) {
// Sort swiper style sheet before default style sheet
includeSwiper(in: &headers)
footer = swiperInitScript(posts: posts)
}
let iconUrl = content.settings.navigation.localized(in: language).rootUrl
let languageButton = NavigationBar.Link(
text: language.next.rawValue,
url: languageButtonUrl)
let pageHeader = PageHeader(
language: language,
title: title,
description: description,
iconUrl: iconUrl,
languageButton: languageButton,
links: content.navigationBar(in: language),
headers: headers,
icons: [])
let page = GenericPage(
header: pageHeader,
additionalFooter: footer) { content in
if showTitle {
content += "<h1>\(title)</h1>"
}
for post in posts {
content += FeedEntry(data: post).content
}
if totalPages > 1 {
content += PostFeedPageNavigation(
linkPrefix: linkPrefix,
currentPage: pageNumber,
numberOfPages: totalPages).content
}
}
return page.content
}
func swiperInitScript(posts: [FeedEntryData]) -> String {
var result = "<script> window.onload = () => { "
for post in posts {
guard post.images.count > 1 else {
continue
}
result += ImageGallery.swiperInit(id: post.entryId)
}
result += "}; </script>"
return result
}
}

View File

@ -0,0 +1,93 @@
final class PageGenerator {
private let content: Content
init(content: Content) {
self.content = content
}
private func makeHeaders(requiredItems: Set<KnownHeaderElement>, results: PageGenerationResults) -> Set<HeaderElement> {
var result = content.defaultPageHeaders
for item in requiredItems {
guard let header = item.header(content: content) else {
results.warning("Header \(item) not configured in settings")
continue
}
result.insert(header)
}
return result
}
private func makeEmptyPageContent(in language: ContentLanguage) -> String {
#warning("Configure empty page text in settings")
switch language {
case .english:
return ContentBox(
title: "Content not available",
text: "This page is not available yet. Try the German version or check back later.")
.content
case .german:
return ContentBox(
title: "Inhalt nicht verfügbar",
text: "Diese Seite ist noch nicht verfügbar. Versuche die englische Version oder komm später hierher zurück.")
.content
}
}
func generate(page: Page, language: ContentLanguage, results: PageGenerationResults) -> String? {
let contentGenerator = PageContentParser(
content: content,
language: language, results: results)
let rawPageContent: String
if let existing = content.storage.pageContent(for: page.id, language: language) {
rawPageContent = existing
} else {
rawPageContent = makeEmptyPageContent(in: language)
results.markPageAsEmpty()
}
let pageContent = contentGenerator.generatePage(from: rawPageContent)
let localized = page.localized(in: language)
let tags: [FeedEntryData.Tag] = page.tags.map { tag in
.init(name: tag.localized(in: language).name,
url: tag.absoluteUrl(in: language))
}
let headers = makeHeaders(requiredItems: results.requiredHeaders, results: results)
results.require(files: headers.compactMap { $0.file })
let iconUrl = content.settings.navigation.localized(in: language).rootUrl
let languageUrl = page.absoluteUrl(in: language.next)
let languageButton = NavigationBar.Link(
text: language.next.rawValue,
url: languageUrl)
let pageHeader = PageHeader(
language: language,
title: localized.linkPreviewTitle ?? localized.title,
description: localized.linkPreviewDescription,
iconUrl: iconUrl,
languageButton: languageButton,
links: content.navigationBar(in: language),
headers: headers,
icons: results.requiredIcons)
let fullPage = GenericPage(
header: pageHeader,
additionalFooter: results.requiredFooters.sorted().joined()) { content in
content += "<article>"
if !localized.hideTitle {
content += "<h3>\(page.dateText(in: language))</h3>"
content += "<h1>\(localized.title)</h1>"
content += TagList(tags: tags).content
}
content += pageContent
content += "</article>"
}
return fullPage.content
}
}

View File

@ -0,0 +1,74 @@
final class TagOverviewGenerator {
let content: Content
let language: ContentLanguage
let results: PageGenerationResults
init(content: Content, language: ContentLanguage, results: PageGenerationResults) {
self.content = content
self.language = language
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)
let localized = overview.localized(in: language)
let pageHeader = PageHeader(
language: language,
title: localized.linkPreviewTitle ?? localized.title,
description: localized.linkPreviewDescription,
iconUrl: iconUrl,
languageButton: languageButton,
links: content.navigationBar(in: language),
headers: content.defaultPageHeaders,
icons: [])
let page = GenericPage(
header: pageHeader,
additionalFooter: "") { content in
content += "<h1>\(localized.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)
content += RelatedPageLink(
title: title,
description: description,
url: url,
image: image)
.content
}
// if totalPages > 1 {
// content += PostFeedPageNavigation(currentPage: pageNumber, numberOfPages: totalPages, language: language).content
// }
}
let fileContent = page.content
let url = overview.absoluteUrl(in: language) + ".html"
guard content.storage.write(fileContent, to: url) else {
results.unsavedOutput(url, source: .tagOverview)
return
}
}
private func makePageImage(item: LinkPreviewItem) -> ImageSet? {
item.linkPreviewImage.map { image in
let size = content.settings.pages.pageLinkImageSize
let imageSet = image.imageSet(width: size, height: size, language: language)
results.require(imageSet: imageSet)
return imageSet
}
}
}