From deb7e6187e2269c6a44c78488e85c98f116314d7 Mon Sep 17 00:00:00 2001 From: Christoph Hagen Date: Mon, 5 Dec 2022 17:25:07 +0100 Subject: [PATCH] Fix links to external pages --- Sources/Generator/Content/Element.swift | 26 +++++++++++++------ .../Generators/PageContentGenerator.swift | 7 +++-- .../Processing/GenerationResultsHandler.swift | 12 +++++---- Sources/Generator/run.swift | 16 ++++++------ 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/Sources/Generator/Content/Element.swift b/Sources/Generator/Content/Element.swift index 957a468..a60db5c 100644 --- a/Sources/Generator/Content/Element.swift +++ b/Sources/Generator/Content/Element.swift @@ -289,16 +289,23 @@ struct Element { self.readElements(in: folder, source: path, log: log) } - func getContainedIds(log: MetadataInfoLogger) -> [String : String] { - elements.reduce(into: [id : path]) { dict, element in - element.getContainedIds(log: log).forEach { id, path in - if let existing = dict[id] { - log.error("Conflicting id with \(existing)", source: path) - } else { - dict[id] = path - } + func getExternalPageMap(language: String) -> [String : String] { + var result = [String : String]() + if let ext = getExternalLink(for: language) { + result[id] = ext + } else { + result[id] = path + Element.htmlPagePathAddition(for: language) + } + elements.forEach { element in + element.getExternalPageMap(language: language).forEach { key, value in + result[key] = value } } + return result + } + + private func getExternalLink(for language: String) -> String? { + languages.first { $0.language == language }?.externalUrl } } @@ -381,6 +388,9 @@ extension Element { - Returns: The relative url from a localized page of the element to the target file. */ func relativePathToOtherSiteElement(file: String) -> String { + guard !file.hasPrefix("/") else { + return file + } // Note: The element `path` is missing the last component // i.e. travel/alps instead of travel/alps/en.html let ownParts = path.components(separatedBy: "/") diff --git a/Sources/Generator/Generators/PageContentGenerator.swift b/Sources/Generator/Generators/PageContentGenerator.swift index 1f6c2d2..fb78772 100644 --- a/Sources/Generator/Generators/PageContentGenerator.swift +++ b/Sources/Generator/Generators/PageContentGenerator.swift @@ -47,13 +47,12 @@ struct PageContentGenerator { let file = markdown.between("(", and: ")") if file.hasPrefix("page:") { let pageId = file.replacingOccurrences(of: "page:", with: "") - guard let pagePath = results.getPagePath(for: pageId, source: page.path) else { + guard let pagePath = results.getPagePath(for: pageId, source: page.path, language: language) else { // Remove link since the page can't be found return markdown.between("[", and: "]") } - let fullPath = pagePath + Element.htmlPagePathAddition(for: language) // Adjust file path to get the page url - let url = page.relativePathToOtherSiteElement(file: fullPath) + let url = page.relativePathToOtherSiteElement(file: pagePath) return html.replacingOccurrences(of: file, with: url) } @@ -244,7 +243,7 @@ struct PageContentGenerator { private func handlePageLink(page: Element, language: String, pageId: String) -> String { guard let linkedPage = siteRoot.find(pageId) else { // Checking the page path will add it to the missing pages - _ = results.getPagePath(for: pageId, source: page.path) + _ = results.getPagePath(for: pageId, source: page.path, language: language) // Remove link since the page can't be found return "" } diff --git a/Sources/Generator/Processing/GenerationResultsHandler.swift b/Sources/Generator/Processing/GenerationResultsHandler.swift index 184271d..83e1cf2 100644 --- a/Sources/Generator/Processing/GenerationResultsHandler.swift +++ b/Sources/Generator/Processing/GenerationResultsHandler.swift @@ -8,6 +8,8 @@ enum MinificationType { case css } +typealias PageMap = [(language: String, pages: [String : String])] + final class GenerationResultsHandler { /// The content folder where the input data is stored @@ -23,7 +25,7 @@ final class GenerationResultsHandler { This relation is used to generate relative links to pages using the ``Element.id` */ - private let pagePaths: [String: String] + private let pageMap: PageMap private let configuration: Configuration @@ -31,11 +33,11 @@ final class GenerationResultsHandler { private let numberOfTotalPages: Int - init(in input: URL, to output: URL, configuration: Configuration, fileUpdates: FileUpdateChecker, pagePaths: [String: String], pageCount: Int) { + init(in input: URL, to output: URL, configuration: Configuration, fileUpdates: FileUpdateChecker, pageMap: PageMap, pageCount: Int) { self.contentFolder = input self.fileUpdates = fileUpdates self.outputFolder = output - self.pagePaths = pagePaths + self.pageMap = pageMap self.configuration = configuration self.numberOfTotalPages = pageCount } @@ -86,8 +88,8 @@ final class GenerationResultsHandler { // MARK: Page data - func getPagePath(for id: String, source: String) -> String? { - guard let pagePath = pagePaths[id] else { + func getPagePath(for id: String, source: String, language: String) -> String? { + guard let pagePath = pageMap.first(where: { $0.language == language})?.pages[id] else { missingLinkedPages[id] = source return nil } diff --git a/Sources/Generator/run.swift b/Sources/Generator/run.swift index 03db8b4..e11d3ee 100644 --- a/Sources/Generator/run.swift +++ b/Sources/Generator/run.swift @@ -31,7 +31,7 @@ private func loadConfiguration(at configPath: String) -> Configuration? { return config } -private func loadSiteData(in folder: URL, runFolder: URL) throws -> (root: Element, ids: [String : String])? { +private func loadSiteData(in folder: URL, runFolder: URL) throws -> (root: Element, pageMap: PageMap)? { print("--- SOURCE FILES -----------------------------------") print(" ") @@ -48,22 +48,22 @@ private func loadSiteData(in folder: URL, runFolder: URL) throws -> (root: Eleme print(" Error: No site root loaded, aborting generation") return nil } - let ids = root.getContainedIds(log: log) + let pageMap = root.languages.map { (language: $0.language, pages: root.getExternalPageMap(language: $0.language)) } log.printMetadataScanOverview(languages: root.languages.count) - return (root, ids) + return (root, pageMap) } -private func generatePages(from root: Element, configuration: Configuration, fileUpdates: FileUpdateChecker, ids: [String: String], runFolder: URL) -> (ImageData, FileData)? { +private func generatePages(from root: Element, configuration: Configuration, fileUpdates: FileUpdateChecker, pageMap: PageMap, runFolder: URL) -> (ImageData, FileData)? { print("--- GENERATION -------------------------------------") print(" ") - let pageCount = ids.count * root.languages.count + let pageCount = pageMap.reduce(0) { $0 + $1.pages.count } let results = GenerationResultsHandler( in: configuration.contentDirectory, to: configuration.outputDirectory, configuration: configuration, fileUpdates: fileUpdates, - pagePaths: ids, + pageMap: pageMap, pageCount: pageCount) defer { results.printOverview() } @@ -149,7 +149,7 @@ private func generate(configPath: String) throws { let runFolder = configuration.contentDirectory.appendingPathComponent("run") // 2. Scan site elements - guard let (siteRoot, ids) = try loadSiteData(in: configuration.contentDirectory, runFolder: runFolder) else { + guard let (siteRoot, pageMap) = try loadSiteData(in: configuration.contentDirectory, runFolder: runFolder) else { return } @@ -165,7 +165,7 @@ private func generate(configPath: String) throws { // 3. Generate pages - guard let (images, files) = generatePages(from: siteRoot, configuration: configuration, fileUpdates: fileUpdates, ids: ids, runFolder: runFolder) else { + guard let (images, files) = generatePages(from: siteRoot, configuration: configuration, fileUpdates: fileUpdates, pageMap: pageMap, runFolder: runFolder) else { return }