Add navigation settings, fix page generation
This commit is contained in:
@ -106,20 +106,6 @@ extension Content {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Paths to items
|
||||
|
||||
private func makeCleanAbsolutePath(_ path: String) -> String {
|
||||
("/" + path).replacingOccurrences(of: "//", with: "/")
|
||||
}
|
||||
|
||||
func absoluteUrlPrefixForTag(_ tag: Tag, language: ContentLanguage) -> String {
|
||||
makeCleanAbsolutePath(settings.paths.tagsOutputFolderPath + "/" + tag.localized(in: language).urlComponent)
|
||||
}
|
||||
|
||||
func absoluteUrlToTag(_ tag: Tag, language: ContentLanguage) -> String {
|
||||
absoluteUrlPrefixForTag(tag, language: language) + ".html"
|
||||
}
|
||||
|
||||
// MARK: Find items by id
|
||||
|
||||
func page(_ pageId: String) -> Page? {
|
||||
@ -145,7 +131,7 @@ extension Content {
|
||||
// MARK: Generation input
|
||||
|
||||
func navigationBar(in language: ContentLanguage) -> [NavigationBar.Link] {
|
||||
settings.navigationItems.map {
|
||||
settings.navigation.navigationItems.map {
|
||||
.init(text: $0.title(in: language),
|
||||
url: $0.absoluteUrl(in: language))
|
||||
}
|
||||
@ -197,9 +183,6 @@ extension Content {
|
||||
continue
|
||||
}
|
||||
for language in ContentLanguage.allCases {
|
||||
guard page.hasContent(in: language) else {
|
||||
continue
|
||||
}
|
||||
generateInternal(page, in: language)
|
||||
}
|
||||
}
|
||||
@ -213,14 +196,12 @@ extension Content {
|
||||
for language in ContentLanguage.allCases {
|
||||
guard shouldGenerateWebsite else { return }
|
||||
let results = results.makeResults(for: .feed, in: language)
|
||||
let generator = PostListPageGenerator(
|
||||
let source = FeedGeneratorSource(
|
||||
language: language,
|
||||
content: self,
|
||||
results: results,
|
||||
showTitle: false,
|
||||
pageTitle: settings.localized(in: language).title,
|
||||
pageDescription: settings.localized(in: language).description,
|
||||
pageUrlPrefix: settings.localized(in: language).feedUrlPrefix)
|
||||
results: results)
|
||||
|
||||
let generator = PostListPageGenerator(source: source)
|
||||
generator.createPages(for: posts)
|
||||
}
|
||||
|
||||
@ -249,16 +230,12 @@ extension Content {
|
||||
let posts = posts.filter { $0.tags.contains(tag) }
|
||||
guard posts.count > 0 else { continue }
|
||||
|
||||
let localized = tag.localized(in: language)
|
||||
let urlPrefix = absoluteUrlPrefixForTag(tag, language: language)
|
||||
let generator = PostListPageGenerator(
|
||||
let source = TagPageGeneratorSource(
|
||||
language: language,
|
||||
content: self,
|
||||
results: results,
|
||||
showTitle: true,
|
||||
pageTitle: localized.name,
|
||||
pageDescription: localized.description ?? "",
|
||||
pageUrlPrefix: urlPrefix)
|
||||
tag: tag)
|
||||
let generator = PostListPageGenerator(source: source)
|
||||
generator.createPages(for: posts)
|
||||
}
|
||||
}
|
||||
|
@ -146,52 +146,10 @@ extension Content {
|
||||
self.files = files.values.sorted { $0.id }
|
||||
self.posts = posts.values.sorted(ascending: false) { $0.startDate }
|
||||
self.tagOverview = tagOverview
|
||||
self.settings = makeSettings(settings, tags: tags, pages: pages, files: files, posts: posts)
|
||||
self.settings = .init(file: settings, tags: tags, pages: pages, files: files, posts: posts, tagOverview: tagOverview)
|
||||
print("Content loaded")
|
||||
}
|
||||
|
||||
private func makeSettings(_ settings: SettingsFile,
|
||||
tags: [String : Tag],
|
||||
pages: [String : Page],
|
||||
files: [String : FileResource],
|
||||
posts: [String : Post]) -> Settings {
|
||||
|
||||
#warning("Notify about missing links")
|
||||
let navigationItems: [Item] = settings.navigationItems.compactMap { raw in
|
||||
guard let type = ItemType(rawValue: raw, posts: posts, pages: pages, tags: tags) else {
|
||||
return nil
|
||||
}
|
||||
switch type {
|
||||
case .general:
|
||||
return nil
|
||||
case .post(let post):
|
||||
return post
|
||||
case .feed:
|
||||
return nil // TODO: Provide feed object
|
||||
case .page(let page):
|
||||
return page
|
||||
case .tagPage(let tag):
|
||||
return tag
|
||||
case .tagOverview:
|
||||
return tagOverview
|
||||
}
|
||||
}
|
||||
|
||||
let posts = PostSettings(file: settings.posts, files: files)
|
||||
|
||||
let pages = PageSettings(file: settings.pages, files: files)
|
||||
|
||||
let paths = PathSettings(file: settings.paths)
|
||||
|
||||
return Settings(
|
||||
paths: paths,
|
||||
navigationItems: navigationItems,
|
||||
posts: posts,
|
||||
pages: pages,
|
||||
german: .init(file: settings.german),
|
||||
english: .init(file: settings.english))
|
||||
}
|
||||
|
||||
private func loadPages(_ pagesData: [String : PageFile], tags: [String : Tag], files: [String : FileResource]) -> [String : Page] {
|
||||
pagesData.reduce(into: [:]) { pages, data in
|
||||
let (pageId, page) = data
|
||||
|
@ -133,37 +133,3 @@ private extension LocalizedTag {
|
||||
originalURL: originalUrl)
|
||||
}
|
||||
}
|
||||
|
||||
extension Settings {
|
||||
|
||||
var file: SettingsFile {
|
||||
.init(
|
||||
paths: paths.file,
|
||||
navigationItems: navigationItems.map { $0.itemType.id },
|
||||
posts: posts.file,
|
||||
pages: pages.file,
|
||||
german: german.file,
|
||||
english: english.file)
|
||||
}
|
||||
}
|
||||
|
||||
private extension PostSettings {
|
||||
|
||||
var file: PostSettingsFile {
|
||||
.init(postsPerPage: postsPerPage,
|
||||
contentWidth: contentWidth,
|
||||
swiperCssFile: swiperCssFile?.id,
|
||||
swiperJsFile: swiperJsFile?.id,
|
||||
defaultCssFile: defaultCssFile?.id)
|
||||
}
|
||||
}
|
||||
|
||||
private extension LocalizedPostSettings {
|
||||
|
||||
var file: LocalizedPostSettingsFile {
|
||||
.init(
|
||||
feedTitle: title,
|
||||
feedDescription: description,
|
||||
feedUrlPrefix: feedUrlPrefix)
|
||||
}
|
||||
}
|
||||
|
@ -32,3 +32,13 @@ extension ContentLanguage: Comparable {
|
||||
lhs.rawValue < rhs.rawValue
|
||||
}
|
||||
}
|
||||
|
||||
extension ContentLanguage {
|
||||
|
||||
var next: ContentLanguage {
|
||||
switch self {
|
||||
case .english: return .german
|
||||
case .german: return .english
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,8 @@ enum FileType: String {
|
||||
|
||||
case js
|
||||
|
||||
case ttf
|
||||
|
||||
// MARK: Text
|
||||
|
||||
case json
|
||||
@ -143,7 +145,7 @@ enum FileType: String {
|
||||
return .video
|
||||
case .mp3, .aac:
|
||||
return .audio
|
||||
case .js, .css:
|
||||
case .js, .css, .ttf:
|
||||
return .asset
|
||||
case .json, .conf, .yaml:
|
||||
return .text
|
||||
@ -195,7 +197,7 @@ enum FileType: String {
|
||||
|
||||
var isAsset: Bool {
|
||||
switch self {
|
||||
case .js, .css:
|
||||
case .js, .css, .ttf:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
25
CHDataManagement/Model/Item/LocalizedPageId.swift
Normal file
25
CHDataManagement/Model/Item/LocalizedPageId.swift
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
struct LocalizedPageId: Hashable {
|
||||
|
||||
let language: ContentLanguage
|
||||
|
||||
let pageId: String
|
||||
}
|
||||
|
||||
extension LocalizedPageId: Identifiable {
|
||||
|
||||
var id: String {
|
||||
pageId + "-" + language.rawValue
|
||||
}
|
||||
}
|
||||
|
||||
extension LocalizedPageId: Comparable {
|
||||
|
||||
static func < (lhs: LocalizedPageId, rhs: LocalizedPageId) -> Bool {
|
||||
lhs.id < rhs.id
|
||||
}
|
||||
}
|
||||
|
||||
extension LocalizedPageId: Equatable {
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
import Foundation
|
||||
|
||||
final class LocalizedNavigationSettings: ObservableObject {
|
||||
|
||||
@Published
|
||||
var rootUrl: String
|
||||
|
||||
init(rootUrl: String) {
|
||||
self.rootUrl = rootUrl
|
||||
}
|
||||
|
||||
init(file: LocalizedNavigationSettingsFile) {
|
||||
self.rootUrl = file.rootUrl
|
||||
}
|
||||
|
||||
var file: LocalizedNavigationSettingsFile {
|
||||
.init(rootUrl: rootUrl)
|
||||
}
|
||||
}
|
||||
|
||||
extension LocalizedNavigationSettings {
|
||||
|
||||
static var `default`: LocalizedNavigationSettings {
|
||||
.init(rootUrl: "/")
|
||||
}
|
||||
}
|
@ -17,9 +17,18 @@ final class LocalizedPostSettings: ObservableObject {
|
||||
self.feedUrlPrefix = feedUrlPrefix
|
||||
}
|
||||
|
||||
// MARK: Storage
|
||||
|
||||
init(file: LocalizedPostSettingsFile) {
|
||||
self.title = file.feedTitle
|
||||
self.description = file.feedDescription
|
||||
self.feedUrlPrefix = file.feedUrlPrefix
|
||||
}
|
||||
|
||||
var file: LocalizedPostSettingsFile {
|
||||
.init(
|
||||
feedTitle: title,
|
||||
feedDescription: description,
|
||||
feedUrlPrefix: feedUrlPrefix)
|
||||
}
|
||||
}
|
||||
|
71
CHDataManagement/Model/Settings/NavigationSettings.swift
Normal file
71
CHDataManagement/Model/Settings/NavigationSettings.swift
Normal file
@ -0,0 +1,71 @@
|
||||
import Foundation
|
||||
|
||||
final class NavigationSettings: ObservableObject {
|
||||
|
||||
/// The items to show in the navigation bar
|
||||
@Published
|
||||
var navigationItems: [Item]
|
||||
|
||||
@Published
|
||||
var german: LocalizedNavigationSettings
|
||||
|
||||
@Published
|
||||
var english: LocalizedNavigationSettings
|
||||
|
||||
init(navigationItems: [Item], german: LocalizedNavigationSettings, english: LocalizedNavigationSettings) {
|
||||
self.navigationItems = navigationItems
|
||||
self.german = german
|
||||
self.english = english
|
||||
}
|
||||
|
||||
init(file: NavigationSettingsFile,
|
||||
tags: [String : Tag],
|
||||
pages: [String : Page],
|
||||
files: [String : FileResource],
|
||||
posts: [String : Post],
|
||||
tagOverview: TagOverviewPage?) {
|
||||
|
||||
#warning("Notify about missing links")
|
||||
self.navigationItems = file.navigationItems.compactMap { raw in
|
||||
guard let type = ItemType(rawValue: raw, posts: posts, pages: pages, tags: tags) else {
|
||||
return nil
|
||||
}
|
||||
switch type {
|
||||
case .general:
|
||||
return nil
|
||||
case .post(let post):
|
||||
return post
|
||||
case .feed:
|
||||
return nil // TODO: Provide feed object
|
||||
case .page(let page):
|
||||
return page
|
||||
case .tagPage(let tag):
|
||||
return tag
|
||||
case .tagOverview:
|
||||
return tagOverview
|
||||
}
|
||||
}
|
||||
self.german = LocalizedNavigationSettings(file: file.german)
|
||||
self.english = LocalizedNavigationSettings(file: file.english)
|
||||
}
|
||||
|
||||
var file: NavigationSettingsFile {
|
||||
.init(
|
||||
navigationItems: navigationItems.map { $0.itemType.id },
|
||||
german: german.file,
|
||||
english: english.file)
|
||||
}
|
||||
}
|
||||
|
||||
extension NavigationSettings: LocalizedItem {
|
||||
|
||||
}
|
||||
|
||||
extension NavigationSettings {
|
||||
|
||||
static var `default`: NavigationSettings {
|
||||
.init(navigationItems: [],
|
||||
german: .default,
|
||||
english: .default)
|
||||
}
|
||||
}
|
@ -31,6 +31,8 @@ final class PostSettings: ObservableObject {
|
||||
self.defaultCssFile = defaultCssFile
|
||||
}
|
||||
|
||||
// MARK: Storage
|
||||
|
||||
init(file: PostSettingsFile, files: [String : FileResource]) {
|
||||
self.postsPerPage = file.postsPerPage
|
||||
self.contentWidth = file.contentWidth
|
||||
@ -38,4 +40,12 @@ final class PostSettings: ObservableObject {
|
||||
self.swiperJsFile = file.swiperJsFile.map { files[$0] }
|
||||
self.defaultCssFile = file.defaultCssFile.map { files[$0] }
|
||||
}
|
||||
|
||||
var file: PostSettingsFile {
|
||||
.init(postsPerPage: postsPerPage,
|
||||
contentWidth: contentWidth,
|
||||
swiperCssFile: swiperCssFile?.id,
|
||||
swiperJsFile: swiperJsFile?.id,
|
||||
defaultCssFile: defaultCssFile?.id)
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ final class Settings: ObservableObject {
|
||||
|
||||
/// The items to show in the navigation bar
|
||||
@Published
|
||||
var navigationItems: [Item]
|
||||
var navigation: NavigationSettings
|
||||
|
||||
@Published
|
||||
var posts: PostSettings
|
||||
@ -21,9 +21,9 @@ final class Settings: ObservableObject {
|
||||
@Published
|
||||
var english: LocalizedPostSettings
|
||||
|
||||
init(paths: PathSettings, navigationItems: [Item], posts: PostSettings, pages: PageSettings, german: LocalizedPostSettings, english: LocalizedPostSettings) {
|
||||
init(paths: PathSettings, navigation: NavigationSettings, posts: PostSettings, pages: PageSettings, german: LocalizedPostSettings, english: LocalizedPostSettings) {
|
||||
self.paths = paths
|
||||
self.navigationItems = navigationItems
|
||||
self.navigation = navigation
|
||||
self.posts = posts
|
||||
self.pages = pages
|
||||
self.german = german
|
||||
@ -36,4 +36,48 @@ final class Settings: ObservableObject {
|
||||
case .german: return german
|
||||
}
|
||||
}
|
||||
|
||||
init(file: SettingsFile,
|
||||
tags: [String : Tag],
|
||||
pages: [String : Page],
|
||||
files: [String : FileResource],
|
||||
posts: [String : Post],
|
||||
tagOverview: TagOverviewPage?) {
|
||||
|
||||
self.navigation = NavigationSettings(
|
||||
file: file.navigation,
|
||||
tags: tags,
|
||||
pages: pages,
|
||||
files: files,
|
||||
posts: posts,
|
||||
tagOverview: tagOverview)
|
||||
|
||||
self.posts = PostSettings(file: file.posts, files: files)
|
||||
self.pages = PageSettings(file: file.pages, files: files)
|
||||
self.paths = PathSettings(file: file.paths)
|
||||
|
||||
self.german = .init(file: file.german)
|
||||
self.english = .init(file: file.english)
|
||||
}
|
||||
|
||||
var file: SettingsFile {
|
||||
.init(
|
||||
paths: paths.file,
|
||||
navigation: navigation.file,
|
||||
posts: posts.file,
|
||||
pages: pages.file,
|
||||
german: german.file,
|
||||
english: english.file)
|
||||
}
|
||||
}
|
||||
|
||||
extension Settings {
|
||||
|
||||
static let `default`: Settings = .init(
|
||||
paths: .default,
|
||||
navigation: .default,
|
||||
posts: .default,
|
||||
pages: .default,
|
||||
german: .german,
|
||||
english: .english)
|
||||
}
|
||||
|
Reference in New Issue
Block a user