Remove duplicated code for building URL paths

This commit is contained in:
Sami Samhuri 2019-12-10 23:54:02 -08:00
parent f9055f82c2
commit 170c44f4fb
8 changed files with 36 additions and 62 deletions

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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] {

View file

@ -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)

View file

@ -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

View file

@ -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 {