Add tag overview, improve assets

This commit is contained in:
Christoph Hagen
2024-12-15 21:20:12 +01:00
parent 8a3a0f1797
commit 1e67a99866
59 changed files with 1301 additions and 480 deletions

View File

@ -0,0 +1,55 @@
import Foundation
class Item: ObservableObject, Identifiable {
unowned let content: Content
@Published
var id: String
init(content: Content, id: String) {
self.content = content
self.id = id
}
func makeCleanAbsolutePath(_ path: String) -> String {
"/" + makeCleanRelativePath(path)
}
func makeCleanRelativePath(_ path: String) -> String {
path.components(separatedBy: "/").filter { !$0.isEmpty }.joined(separator: "/")
}
func title(in language: ContentLanguage) -> String {
fatalError()
}
func absoluteUrl(in language: ContentLanguage) -> String {
fatalError()
}
var itemType: ItemType {
fatalError()
}
}
extension Item: Equatable {
static func == (lhs: Item, rhs: Item) -> Bool {
lhs.id == rhs.id
}
}
extension Item: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
extension Item: Comparable {
static func < (lhs: Item, rhs: Item) -> Bool {
lhs.id < rhs.id
}
}

View File

@ -0,0 +1,38 @@
struct ItemId {
let itemId: String
let language: ContentLanguage
let itemType: ItemType
}
extension ItemId: Equatable {
static func == (lhs: ItemId, rhs: ItemId) -> Bool {
lhs.itemId == rhs.itemId && lhs.language == rhs.language && lhs.itemType == rhs.itemType
}
}
extension ItemId: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(itemId)
hasher.combine(language)
hasher.combine(itemType)
}
}
extension ItemId: Comparable {
static func < (lhs: ItemId, rhs: ItemId) -> Bool {
guard lhs.itemType == rhs.itemType else {
return lhs.itemType < rhs.itemType
}
guard lhs.itemId == rhs.itemId else {
return lhs.itemId < rhs.itemId
}
return lhs.language < rhs.language
}
}

View File

@ -0,0 +1,35 @@
enum ItemType: String, Codable {
case post
case tag
case page
case tagOverview
case file
}
extension ItemType: Equatable {
}
extension ItemType: Hashable {
}
extension ItemType: Identifiable {
var id: String {
rawValue
}
}
extension ItemType: Comparable {
static func < (lhs: ItemType, rhs: ItemType) -> Bool {
lhs.rawValue < rhs.rawValue
}
}

View File

@ -0,0 +1,19 @@
protocol LocalizedItem {
associatedtype Localized
var german: Localized { get }
var english: Localized { get }
}
extension LocalizedItem {
func localized(in language: ContentLanguage) -> Localized {
switch language {
case .german: return german
case .english: return english
}
}
}

View File

@ -0,0 +1,99 @@
import Foundation
final class TagOverviewPage: Item {
static let id = "all-tags"
@Published
var german: LocalizedTagOverviewPage
@Published
var english: LocalizedTagOverviewPage
init(content: Content, german: LocalizedTagOverviewPage, english: LocalizedTagOverviewPage) {
self.german = german
self.english = english
super.init(content: content, id: TagOverviewPage.id)
}
override var itemType: ItemType {
.tagOverview
}
override func title(in language: ContentLanguage) -> String {
localized(in: language).title
}
override func absoluteUrl(in language: ContentLanguage) -> String {
makeCleanAbsolutePath(internalPath(for: language))
}
func filePathRelativeToOutputFolder(for language: ContentLanguage) -> String {
makeCleanRelativePath(internalPath(for: language))
}
private func internalPath(for language: ContentLanguage) -> String {
content.settings.paths.tagsOutputFolderPath + "/" + localized(in: language).urlString
}
func contains(urlComponent: String) -> Bool {
english.urlString == urlComponent || german.urlString == urlComponent
}
var file: TagOverviewFile {
.init(german: german.file,
english: english.file)
}
}
extension TagOverviewPage: LocalizedItem {
}
final class LocalizedTagOverviewPage: ObservableObject {
@Published
var title: String
/**
The string to use when creating the url for the page.
Defaults to ``id`` if unset.
*/
@Published
var urlString: String
@Published
var linkPreviewImage: FileResource?
@Published
var linkPreviewTitle: String?
@Published
var linkPreviewDescription: String?
init(title: String, urlString: String, linkPreviewImage: FileResource? = nil, linkPreviewTitle: String? = nil, linkPreviewDescription: String? = nil) {
self.title = title
self.urlString = urlString
self.linkPreviewImage = linkPreviewImage
self.linkPreviewTitle = linkPreviewTitle
self.linkPreviewDescription = linkPreviewDescription
}
init(file: LocalizedTagOverviewFile, image: FileResource?) {
self.title = file.title
self.urlString = file.url
self.linkPreviewImage = image
self.linkPreviewTitle = file.linkPreviewTitle
self.linkPreviewDescription = file.linkPreviewDescription
}
var file: LocalizedTagOverviewFile {
.init(url: urlString,
title: title,
linkPreviewImage: linkPreviewImage?.id,
linkPreviewTitle: linkPreviewTitle,
linkPreviewDescription: linkPreviewDescription)
}
}