From 2ce214849d88dfb836127171009b3cf17911fdf8 Mon Sep 17 00:00:00 2001 From: Tom Harrington Date: Sat, 26 Feb 2022 15:41:58 -0700 Subject: [PATCH] Make .standAloneFiles work with section indexes --- Sources/Publish/API/Item.swift | 14 ++++++++++ Sources/Publish/API/PublishingStep.swift | 4 +-- Sources/Publish/API/Theme+Foundation.swift | 2 +- Sources/Publish/API/Website.swift | 5 ++++ .../Infrastructure/PublishTestCase.swift | 26 ++++++++++++++----- .../Infrastructure/WebsiteStub.swift | 3 ++- .../Tests/HTMLGenerationTests.swift | 12 +++++---- 7 files changed, 50 insertions(+), 16 deletions(-) diff --git a/Sources/Publish/API/Item.swift b/Sources/Publish/API/Item.swift index 267d684a..13946c68 100644 --- a/Sources/Publish/API/Item.swift +++ b/Sources/Publish/API/Item.swift @@ -61,3 +61,17 @@ private extension Item { "\(sectionID.rawValue)/\(relativePath)" } } + +public extension Item { + /// An `Item` location depends on the site's file mode. This function returns the appropriat path for the site. + /// - Parameter site: The site being published + /// - Returns: Path to the `Item` suitable for use in a list of links in a generated section index page. + func linkPath(for site:Site) -> String { + switch site.fileMode { + case .foldersAndIndexFiles: + return "/\(sectionID.rawValue)/\(relativePath)" + case .standAloneFiles: + return "/\(sectionID.rawValue)/\(relativePath).html" + } + } +} diff --git a/Sources/Publish/API/PublishingStep.swift b/Sources/Publish/API/PublishingStep.swift index ecd19dbe..d4f3b6cb 100644 --- a/Sources/Publish/API/PublishingStep.swift +++ b/Sources/Publish/API/PublishingStep.swift @@ -333,13 +333,13 @@ public extension PublishingStep { static func generateHTML( withTheme theme: Theme, indentation: Indentation.Kind? = nil, - fileMode: HTMLFileMode = .foldersAndIndexFiles + fileMode: HTMLFileMode? = nil ) -> Self { step(named: "Generate HTML") { context in let generator = HTMLGenerator( theme: theme, indentation: indentation, - fileMode: fileMode, + fileMode: fileMode ?? context.site.fileMode, context: context ) diff --git a/Sources/Publish/API/Theme+Foundation.swift b/Sources/Publish/API/Theme+Foundation.swift index d815219b..2f8897ac 100644 --- a/Sources/Publish/API/Theme+Foundation.swift +++ b/Sources/Publish/API/Theme+Foundation.swift @@ -197,7 +197,7 @@ private struct ItemList: Component { var body: Component { List(items) { item in Article { - H1(Link(item.title, url: item.path.absoluteString)) + H1(Link(item.title, url: item.linkPath(for: site))) ItemTagList(item: item, site: site) Paragraph(item.description) } diff --git a/Sources/Publish/API/Website.swift b/Sources/Publish/API/Website.swift index 75ae2b5a..56b12dfc 100644 --- a/Sources/Publish/API/Website.swift +++ b/Sources/Publish/API/Website.swift @@ -40,6 +40,8 @@ public protocol Website { /// The configuration to use when generating tag HTML for the website. /// If this is `nil`, then no tag HTML will be generated. var tagHTMLConfig: TagHTMLConfiguration? { get } + /// Preferred file-generation mode. Default is `.foldersAndIndexFiles` + var fileMode: HTMLFileMode { get } } // MARK: - Defaults @@ -154,4 +156,7 @@ public extension Website { func url(for location: Location) -> URL { url(for: location.path) } + + /// Provide a default file mode. + var fileMode: HTMLFileMode { .foldersAndIndexFiles } } diff --git a/Tests/PublishTests/Infrastructure/PublishTestCase.swift b/Tests/PublishTests/Infrastructure/PublishTestCase.swift index c9f12ef5..2e3d0b02 100644 --- a/Tests/PublishTests/Infrastructure/PublishTestCase.swift +++ b/Tests/PublishTests/Infrastructure/PublishTestCase.swift @@ -14,13 +14,15 @@ class PublishTestCase: XCTestCase { func publishWebsite( in folder: Folder? = nil, using steps: [PublishingStep], - content: [Path : String] = [:] + content: [Path : String] = [:], + fileMode: HTMLFileMode = .foldersAndIndexFiles ) throws -> PublishedWebsite { try performWebsitePublishing( in: folder, using: steps, files: content, - filePathPrefix: "Content/" + filePathPrefix: "Content/", + fileMode: fileMode ) } @@ -33,9 +35,12 @@ class PublishTestCase: XCTestCase { plugins: [Plugin] = [], expectedHTML: [Path : String], allowWhitelistedOutputFiles: Bool = true, + fileMode: HTMLFileMode = .foldersAndIndexFiles, file: StaticString = #file, line: UInt = #line ) throws { + site.fileMode = fileMode + let folder = try folder ?? Folder.createTemporary() let contentFolderName = "Content" @@ -65,6 +70,7 @@ class PublishTestCase: XCTestCase { in folder: Folder? = nil, using steps: [PublishingStep], content: [Path : String] = [:], + fileMode: HTMLFileMode = .foldersAndIndexFiles, file: StaticString = #file, line: UInt = #line ) throws { @@ -72,7 +78,8 @@ class PublishTestCase: XCTestCase { in: folder, using: steps, files: content, - filePathPrefix: "Content/" + filePathPrefix: "Content/", + fileMode: fileMode ) } @@ -136,12 +143,14 @@ class PublishTestCase: XCTestCase { func publishWebsite( withItemMetadataType itemMetadataType: T.Type, using steps: [PublishingStep>], - content: [Path : String] = [:] + content: [Path : String] = [:], + fileMode: HTMLFileMode = .foldersAndIndexFiles ) throws -> PublishedWebsite> { try performWebsitePublishing( using: steps, files: content, - filePathPrefix: "Content/" + filePathPrefix: "Content/", + fileMode: fileMode ) } @@ -197,13 +206,16 @@ private extension PublishTestCase { in folder: Folder? = nil, using steps: [PublishingStep], files: [Path : String], - filePathPrefix: String = "" + filePathPrefix: String = "", + fileMode: HTMLFileMode ) throws -> PublishedWebsite { let folder = try folder ?? Folder.createTemporary() try addFiles(withContent: files, to: folder, pathPrefix: filePathPrefix) - return try T().publish( + let site = T() + site.fileMode = fileMode + return try site.publish( at: Path(folder.path), using: steps ) diff --git a/Tests/PublishTests/Infrastructure/WebsiteStub.swift b/Tests/PublishTests/Infrastructure/WebsiteStub.swift index 09c3638f..c0f7df33 100644 --- a/Tests/PublishTests/Infrastructure/WebsiteStub.swift +++ b/Tests/PublishTests/Infrastructure/WebsiteStub.swift @@ -20,7 +20,8 @@ class WebsiteStub { var imagePath: Path? = nil var faviconPath: Path? = nil var tagHTMLConfig: TagHTMLConfiguration? = .default - + var fileMode: HTMLFileMode = .foldersAndIndexFiles + required init() {} func title(for sectionID: WebsiteStub.SectionID) -> String { diff --git a/Tests/PublishTests/Tests/HTMLGenerationTests.swift b/Tests/PublishTests/Tests/HTMLGenerationTests.swift index 2afca997..42b25ab4 100644 --- a/Tests/PublishTests/Tests/HTMLGenerationTests.swift +++ b/Tests/PublishTests/Tests/HTMLGenerationTests.swift @@ -259,11 +259,13 @@ final class HTMLGenerationTests: PublishTestCase { let folder = try Folder.createTemporary() let theme = Theme(htmlFactory: htmlFactory) - try publishWebsite(in: folder, using: [ - .addItem(Item.stub(withPath: "item").setting(\.tags, to: ["tag"])), - .addItem(Item.stub(withPath: "rawValueItem", sectionID: .customRawValue).setting(\.tags, to: ["tag"])), - .generateHTML(withTheme: theme, fileMode: .standAloneFiles) - ]) + try publishWebsite(in: folder, + using: [ + .addItem(Item.stub(withPath: "item").setting(\.tags, to: ["tag"])), + .addItem(Item.stub(withPath: "rawValueItem", sectionID: .customRawValue).setting(\.tags, to: ["tag"])), + .generateHTML(withTheme: theme) + ], + fileMode: .standAloneFiles) try verifyOutput( in: folder,