Fix links to external pages

This commit is contained in:
Christoph Hagen 2022-12-05 17:25:07 +01:00
parent 464ece4a03
commit deb7e6187e
4 changed files with 36 additions and 25 deletions

View File

@ -289,16 +289,23 @@ struct Element {
self.readElements(in: folder, source: path, log: log) self.readElements(in: folder, source: path, log: log)
} }
func getContainedIds(log: MetadataInfoLogger) -> [String : String] { func getExternalPageMap(language: String) -> [String : String] {
elements.reduce(into: [id : path]) { dict, element in var result = [String : String]()
element.getContainedIds(log: log).forEach { id, path in if let ext = getExternalLink(for: language) {
if let existing = dict[id] { result[id] = ext
log.error("Conflicting id with \(existing)", source: path)
} else { } else {
dict[id] = path 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. - Returns: The relative url from a localized page of the element to the target file.
*/ */
func relativePathToOtherSiteElement(file: String) -> String { func relativePathToOtherSiteElement(file: String) -> String {
guard !file.hasPrefix("/") else {
return file
}
// Note: The element `path` is missing the last component // Note: The element `path` is missing the last component
// i.e. travel/alps instead of travel/alps/en.html // i.e. travel/alps instead of travel/alps/en.html
let ownParts = path.components(separatedBy: "/") let ownParts = path.components(separatedBy: "/")

View File

@ -47,13 +47,12 @@ struct PageContentGenerator {
let file = markdown.between("(", and: ")") let file = markdown.between("(", and: ")")
if file.hasPrefix("page:") { if file.hasPrefix("page:") {
let pageId = file.replacingOccurrences(of: "page:", with: "") 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 // Remove link since the page can't be found
return markdown.between("[", and: "]") return markdown.between("[", and: "]")
} }
let fullPath = pagePath + Element.htmlPagePathAddition(for: language)
// Adjust file path to get the page url // 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) return html.replacingOccurrences(of: file, with: url)
} }
@ -244,7 +243,7 @@ struct PageContentGenerator {
private func handlePageLink(page: Element, language: String, pageId: String) -> String { private func handlePageLink(page: Element, language: String, pageId: String) -> String {
guard let linkedPage = siteRoot.find(pageId) else { guard let linkedPage = siteRoot.find(pageId) else {
// Checking the page path will add it to the missing pages // 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 // Remove link since the page can't be found
return "" return ""
} }

View File

@ -8,6 +8,8 @@ enum MinificationType {
case css case css
} }
typealias PageMap = [(language: String, pages: [String : String])]
final class GenerationResultsHandler { final class GenerationResultsHandler {
/// The content folder where the input data is stored /// 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` 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 private let configuration: Configuration
@ -31,11 +33,11 @@ final class GenerationResultsHandler {
private let numberOfTotalPages: Int 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.contentFolder = input
self.fileUpdates = fileUpdates self.fileUpdates = fileUpdates
self.outputFolder = output self.outputFolder = output
self.pagePaths = pagePaths self.pageMap = pageMap
self.configuration = configuration self.configuration = configuration
self.numberOfTotalPages = pageCount self.numberOfTotalPages = pageCount
} }
@ -86,8 +88,8 @@ final class GenerationResultsHandler {
// MARK: Page data // MARK: Page data
func getPagePath(for id: String, source: String) -> String? { func getPagePath(for id: String, source: String, language: String) -> String? {
guard let pagePath = pagePaths[id] else { guard let pagePath = pageMap.first(where: { $0.language == language})?.pages[id] else {
missingLinkedPages[id] = source missingLinkedPages[id] = source
return nil return nil
} }

View File

@ -31,7 +31,7 @@ private func loadConfiguration(at configPath: String) -> Configuration? {
return config 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("--- SOURCE FILES -----------------------------------")
print(" ") print(" ")
@ -48,22 +48,22 @@ private func loadSiteData(in folder: URL, runFolder: URL) throws -> (root: Eleme
print(" Error: No site root loaded, aborting generation") print(" Error: No site root loaded, aborting generation")
return nil 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) 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("--- GENERATION -------------------------------------")
print(" ") print(" ")
let pageCount = ids.count * root.languages.count let pageCount = pageMap.reduce(0) { $0 + $1.pages.count }
let results = GenerationResultsHandler( let results = GenerationResultsHandler(
in: configuration.contentDirectory, in: configuration.contentDirectory,
to: configuration.outputDirectory, to: configuration.outputDirectory,
configuration: configuration, configuration: configuration,
fileUpdates: fileUpdates, fileUpdates: fileUpdates,
pagePaths: ids, pageMap: pageMap,
pageCount: pageCount) pageCount: pageCount)
defer { results.printOverview() } defer { results.printOverview() }
@ -149,7 +149,7 @@ private func generate(configPath: String) throws {
let runFolder = configuration.contentDirectory.appendingPathComponent("run") let runFolder = configuration.contentDirectory.appendingPathComponent("run")
// 2. Scan site elements // 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 return
} }
@ -165,7 +165,7 @@ private func generate(configPath: String) throws {
// 3. Generate pages // 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 return
} }