diff --git a/SiteGenerator/Sources/SiteGenerator/Feeds/JSONFeedPlugin.swift b/SiteGenerator/Sources/SiteGenerator/Feeds/JSONFeedPlugin.swift index 8fd8881..fd9497a 100644 --- a/SiteGenerator/Sources/SiteGenerator/Feeds/JSONFeedPlugin.swift +++ b/SiteGenerator/Sources/SiteGenerator/Feeds/JSONFeedPlugin.swift @@ -26,7 +26,7 @@ final class JSONFeedPlugin: Plugin { return } - try postRepo.readPosts(sourceURL: sourceURL, makePath: jsonFeedWriter.urlPathForPost) + try postRepo.readPosts(sourceURL: sourceURL) } func render(site: Site, targetURL: URL, templateRenderer: TemplateRenderer) throws { diff --git a/SiteGenerator/Sources/SiteGenerator/Feeds/JSONFeedWriter.swift b/SiteGenerator/Sources/SiteGenerator/Feeds/JSONFeedWriter.swift index 7bd29b0..0ace428 100644 --- a/SiteGenerator/Sources/SiteGenerator/Feeds/JSONFeedWriter.swift +++ b/SiteGenerator/Sources/SiteGenerator/Feeds/JSONFeedWriter.swift @@ -38,26 +38,10 @@ private struct FeedItem: Codable { final class JSONFeedWriter { let fileManager: FileManager let feedPath: String - let postsPath: String - init(fileManager: FileManager = .default, feedPath: String = "feed.json", postsPath: String = "posts") { + init(fileManager: FileManager = .default, feedPath: String = "feed.json") { self.fileManager = fileManager self.feedPath = feedPath - self.postsPath = postsPath - } - - #warning("These urlPath methods were copied from PostsPlugin and should possibly be moved somewhere else") - - func urlPath(year: Int) -> String { - "/\(postsPath)/\(year)" - } - - func urlPath(year: Int, month: Month) -> String { - urlPath(year: year).appending("/\(month.padded)") - } - - func urlPathForPost(date: Date, slug: String) -> String { - urlPath(year: date.year, month: Month(date.month)).appending("/\(slug)") } func writeFeed(_ posts: [Post], site: Site, to targetURL: URL, with templateRenderer: TemplateRenderer) throws { diff --git a/SiteGenerator/Sources/SiteGenerator/Feeds/RSSFeedPlugin.swift b/SiteGenerator/Sources/SiteGenerator/Feeds/RSSFeedPlugin.swift index 11702c8..46758d7 100644 --- a/SiteGenerator/Sources/SiteGenerator/Feeds/RSSFeedPlugin.swift +++ b/SiteGenerator/Sources/SiteGenerator/Feeds/RSSFeedPlugin.swift @@ -26,7 +26,7 @@ final class RSSFeedPlugin: Plugin { return } - try postRepo.readPosts(sourceURL: sourceURL, makePath: rssFeedWriter.urlPathForPost) + try postRepo.readPosts(sourceURL: sourceURL) } func render(site: Site, targetURL: URL, templateRenderer: TemplateRenderer) throws { diff --git a/SiteGenerator/Sources/SiteGenerator/Feeds/RSSFeedWriter.swift b/SiteGenerator/Sources/SiteGenerator/Feeds/RSSFeedWriter.swift index 01487c1..f9ac971 100644 --- a/SiteGenerator/Sources/SiteGenerator/Feeds/RSSFeedWriter.swift +++ b/SiteGenerator/Sources/SiteGenerator/Feeds/RSSFeedWriter.swift @@ -39,26 +39,10 @@ private extension Date { final class RSSFeedWriter { let fileManager: FileManager let feedPath: String - let postsPath: String - init(fileManager: FileManager = .default, feedPath: String = "feed.xml", postsPath: String = "posts") { + init(fileManager: FileManager = .default, feedPath: String = "feed.xml") { self.fileManager = fileManager self.feedPath = feedPath - self.postsPath = postsPath - } - - #warning("These urlPath methods were copied from PostsPlugin and should possibly be moved somewhere else") - - func urlPath(year: Int) -> String { - "/\(postsPath)/\(year)" - } - - func urlPath(year: Int, month: Month) -> String { - urlPath(year: year).appending("/\(month.padded)") - } - - func urlPathForPost(date: Date, slug: String) -> String { - urlPath(year: date.year, month: Month(date.month)).appending("/\(slug)") } func writeFeed(_ posts: [Post], site: Site, to targetURL: URL, with templateRenderer: TemplateRenderer) throws { diff --git a/SiteGenerator/Sources/SiteGenerator/Posts/PostRepo.swift b/SiteGenerator/Sources/SiteGenerator/Posts/PostRepo.swift index 29d0193..2b42af7 100644 --- a/SiteGenerator/Sources/SiteGenerator/Posts/PostRepo.swift +++ b/SiteGenerator/Sources/SiteGenerator/Posts/PostRepo.swift @@ -18,12 +18,14 @@ final class PostRepo { let fileManager: FileManager let postTransformer: PostTransformer + let outputPath: String private(set) var posts: PostsByYear! - init(fileManager: FileManager = .default, postTransformer: PostTransformer = PostTransformer()) { + init(fileManager: FileManager = .default, postTransformer: PostTransformer = PostTransformer(), outputPath: String = "posts") { self.fileManager = fileManager self.postTransformer = postTransformer + self.outputPath = outputPath } var isEmpty: Bool { @@ -43,10 +45,21 @@ final class PostRepo { return fileManager.fileExists(atPath: postsURL.path) } - func readPosts(sourceURL: URL, makePath: (Date, _ slug: String) -> String) throws { + func readPosts(sourceURL: URL) throws { let posts = try readRawPosts(sourceURL: sourceURL) - .map { try postTransformer.makePost(from: $0, makePath: makePath) } - self.posts = PostsByYear(posts: posts) + .map { try postTransformer.makePost(from: $0, makePath: urlPathForPost) } + self.posts = PostsByYear(posts: posts, path: "/\(outputPath)") + } + + func urlPathForPost(date: Date, slug: String) -> String { + // format: /posts/2019/12/first-post + [ + "", + outputPath, + "\(date.year)", + Month(date.month).padded, + slug, + ].joined(separator: "/") } private func readRawPosts(sourceURL: URL) throws -> [RawPost] { diff --git a/SiteGenerator/Sources/SiteGenerator/Posts/PostWriter.swift b/SiteGenerator/Sources/SiteGenerator/Posts/PostWriter.swift index e2d42aa..7203262 100644 --- a/SiteGenerator/Sources/SiteGenerator/Posts/PostWriter.swift +++ b/SiteGenerator/Sources/SiteGenerator/Posts/PostWriter.swift @@ -15,18 +15,6 @@ final class PostWriter { self.fileManager = fileManager self.outputPath = outputPath } - - func urlPath(year: Int) -> String { - "/\(outputPath)/\(year)" - } - - func urlPath(year: Int, month: Month) -> String { - urlPath(year: year).appending("/\(month.padded)") - } - - func urlPathForPost(date: Date, slug: String) -> String { - urlPath(year: date.year, month: Month(date.month)).appending("/\(slug)") - } } // MARK: - Post pages @@ -80,7 +68,7 @@ extension PostWriter { private func contextDictionaryForYearPosts(_ posts: YearPosts) -> [String: Any] { [ - "path": urlPath(year: posts.year), + "path": posts.path, "title": posts.title, "months": posts.months.sorted(by: >).map { month in contextDictionaryForMonthPosts(posts[month], year: posts.year) @@ -90,7 +78,7 @@ extension PostWriter { private func contextDictionaryForMonthPosts(_ posts: MonthPosts, year: Int) -> [String: Any] { [ - "path": urlPath(year: year, month: posts.month), + "path": posts.path, "name": posts.month.name, "abbreviation": posts.month.abbreviation, "posts": posts.posts.sorted(by: >), @@ -104,10 +92,10 @@ extension PostWriter { func writeYearIndexes(posts: PostsByYear, to targetURL: URL, with templateRenderer: TemplateRenderer) throws { for (year, yearPosts) in posts.byYear { let months = yearPosts.months.sorted(by: >) - let yearDir = targetURL.appendingPathComponent(urlPath(year: year)) + let yearDir = targetURL.appendingPathComponent(yearPosts.path) let context: [String: Any] = [ "title": yearPosts.title, - "path": urlPath(year: year), + "path": yearPosts.path, "year": year, "months": months.map { contextDictionaryForMonthPosts(posts[year][$0], year: year) }, ] @@ -125,10 +113,11 @@ extension PostWriter { func writeMonthRollups(posts: PostsByYear, to targetURL: URL, with templateRenderer: TemplateRenderer) throws { for (year, yearPosts) in posts.byYear { for month in yearPosts.months { - let monthDir = targetURL.appendingPathComponent(urlPath(year: year, month: month)) + let monthPosts = yearPosts[month] + let monthDir = targetURL.appendingPathComponent(monthPosts.path) let monthHTML = try templateRenderer.renderTemplate(name: "posts-month.html", context: [ "title": "\(month.name) \(year)", - "posts": yearPosts[month].posts.sorted(by: >), + "posts": monthPosts.posts.sorted(by: >), ]) let monthURL = monthDir.appendingPathComponent("index.html") try fileManager.createDirectory(at: monthDir, withIntermediateDirectories: true, attributes: nil) diff --git a/SiteGenerator/Sources/SiteGenerator/Posts/PostsByYear.swift b/SiteGenerator/Sources/SiteGenerator/Posts/PostsByYear.swift index f4fb5b0..9ec1ba1 100644 --- a/SiteGenerator/Sources/SiteGenerator/Posts/PostsByYear.swift +++ b/SiteGenerator/Sources/SiteGenerator/Posts/PostsByYear.swift @@ -10,6 +10,7 @@ import Foundation struct MonthPosts { let month: Month var posts: [Post] + let path: String var title: String { month.padded @@ -25,6 +26,7 @@ struct MonthPosts { struct YearPosts { let year: Int var byMonth: [Month: MonthPosts] + let path: String var title: String { "\(year)" @@ -40,7 +42,7 @@ struct YearPosts { subscript(month: Month) -> MonthPosts { get { - byMonth[month, default: MonthPosts(month: month, posts: [])] + byMonth[month, default: MonthPosts(month: month, posts: [], path: "\(path)/\(month.padded)")] } set { byMonth[month] = newValue @@ -52,15 +54,17 @@ struct YearPosts { struct PostsByYear { private(set) var byYear: [Int: YearPosts] + let path: String - init(posts: [Post]) { + init(posts: [Post], path: String) { byYear = [:] + self.path = path posts.forEach { add(post: $0) } } subscript(year: Int) -> YearPosts { get { - byYear[year, default: YearPosts(year: year, byMonth: [:])] + byYear[year, default: YearPosts(year: year, byMonth: [:], path: "\(path)/\(year)")] } set { byYear[year] = newValue diff --git a/SiteGenerator/Sources/SiteGenerator/Posts/PostsPlugin.swift b/SiteGenerator/Sources/SiteGenerator/Posts/PostsPlugin.swift index d8d1948..8d40250 100644 --- a/SiteGenerator/Sources/SiteGenerator/Posts/PostsPlugin.swift +++ b/SiteGenerator/Sources/SiteGenerator/Posts/PostsPlugin.swift @@ -26,7 +26,7 @@ final class PostsPlugin: Plugin { return } - try postRepo.readPosts(sourceURL: sourceURL, makePath: postWriter.urlPathForPost) + try postRepo.readPosts(sourceURL: sourceURL) } func render(site: Site, targetURL: URL, templateRenderer: TemplateRenderer) throws {