import Foundation extension Content { func generatePage(_ page: Page) -> Bool { guard startGenerating() else { return false } defer { endGenerating() } for language in ContentLanguage.allCases { guard generateInternal(page, in: language) else { return false } } return true } func generatePage(_ page: Page, in language: ContentLanguage) -> Bool { guard startGenerating() else { return false } defer { endGenerating() } return generateInternal(page, in: language) } private func startGenerating() -> Bool { guard !isGeneratingWebsite else { return false } // TODO: Fix bug where multiple generating operations can be started // due to dispatch of locking property on main queue DispatchQueue.main.async { self.isGeneratingWebsite = true } return true } private func endGenerating() { DispatchQueue.main.async { self.isGeneratingWebsite = false } } private func generateInternal(_ page: Page, in language: ContentLanguage) -> Bool { let generator = LocalizedWebsiteGenerator( content: self, language: language) if !generator.generate(page: page) { print("Generation failed") return false } return true } private func makeCleanAbsolutePath(_ path: String) -> String { ("/" + path).replacingOccurrences(of: "//", with: "/") } // MARK: Paths to items 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? { pages.first { $0.id == pageId } } func image(_ imageId: String) -> FileResource? { files.first { $0.id == imageId && $0.type.isImage } } func video(_ videoId: String) -> FileResource? { files.first { $0.id == videoId && $0.type.isVideo } } func file(_ fileId: String) -> FileResource? { files.first { $0.id == fileId } } func tag(_ tagId: String) -> Tag? { tags.first { $0.id == tagId } } // MARK: Generation input func navigationBar(in language: ContentLanguage) -> [NavigationBar.Link] { settings.navigationItems.map { .init(text: $0.title(in: language), url: $0.absoluteUrl(in: language)) } } var defaultPageHeaders: Set { var result: Set = [.charset, .viewport] if let defaultCss = settings.posts.defaultCssFile { result.insert(.css(file: defaultCss, order: HeaderElement.defaultCssFileOrder)) } return result } }