From 4a03060c8cbf6820b47f4481d3f909501cecbbf4 Mon Sep 17 00:00:00 2001 From: Sami Samhuri Date: Wed, 4 Dec 2019 17:19:08 -0800 Subject: [PATCH] =?UTF-8?q?Make=20it=20work=20by=20using=20dictionaries=20?= =?UTF-8?q?in=20template=20context=20=F0=9F=91=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a work-around but it works. --- .../Sources/SiteGenerator/Posts/Month.swift | 38 ++++++++++++++++++- .../SiteGenerator/Posts/PostsByYear.swift | 8 ++-- .../SiteGenerator/Posts/PostsPlugin.swift | 34 +++++++++++------ .../SiteGenerator/Posts/RenderedPost.swift | 26 ++++++------- templates/post-text.html | 2 +- templates/posts-year.html | 22 +++++------ 6 files changed, 87 insertions(+), 43 deletions(-) diff --git a/SiteGenerator/Sources/SiteGenerator/Posts/Month.swift b/SiteGenerator/Sources/SiteGenerator/Posts/Month.swift index 9dbf1c8..0f1fd16 100644 --- a/SiteGenerator/Sources/SiteGenerator/Posts/Month.swift +++ b/SiteGenerator/Sources/SiteGenerator/Posts/Month.swift @@ -7,7 +7,7 @@ import Foundation -struct Month { +struct Month: Equatable { static let names = [ "January", "Februrary", "March", "April", "May", "June", "July", "August", @@ -16,15 +16,49 @@ struct Month { let number: Int + init(_ number: Int) { + precondition((1 ... 12).contains(number), "Month number must be from 1 to 12, got \(number)") + self.number = number + } + + init(_ name: String) { + precondition(Month.names.contains(name), "Month name is unknown: \(name)") + self.number = 1 + Month.names.firstIndex(of: name)! + } + var padded: String { String(format: "%02d", number) } var name: String { - Month.names[number] + Month.names[number - 1] } var abbreviatedName: String { String(name.prefix(3)) } } + +extension Month: Hashable { + func hash(into hasher: inout Hasher) { + hasher.combine(number) + } +} + +extension Month: Comparable { + static func <(lhs: Month, rhs: Month) -> Bool { + lhs.number < rhs.number + } +} + +extension Month: ExpressibleByIntegerLiteral { + init(integerLiteral value: Int) { + self.init(value) + } +} + +extension Month: ExpressibleByStringLiteral { + init(stringLiteral value: String) { + self.init(value) + } +} diff --git a/SiteGenerator/Sources/SiteGenerator/Posts/PostsByYear.swift b/SiteGenerator/Sources/SiteGenerator/Posts/PostsByYear.swift index 5bb1653..ce06227 100644 --- a/SiteGenerator/Sources/SiteGenerator/Posts/PostsByYear.swift +++ b/SiteGenerator/Sources/SiteGenerator/Posts/PostsByYear.swift @@ -8,7 +8,7 @@ import Foundation struct MonthPosts { - let month: Int + let month: Month var posts: [Post] var isEmpty: Bool { @@ -18,9 +18,9 @@ struct MonthPosts { struct YearPosts { let year: Int - var byMonth: [Int: MonthPosts] + var byMonth: [Month: MonthPosts] - subscript(month: Int) -> MonthPosts { + subscript(month: Month) -> MonthPosts { get { byMonth[month, default: MonthPosts(month: month, posts: [])] } @@ -56,7 +56,7 @@ struct PostsByYear { } mutating func add(post: Post) { - let (year, month) = (post.date.year, post.date.month) + let (year, month) = (post.date.year, Month(post.date.month)) self[year][month].posts.append(post) } diff --git a/SiteGenerator/Sources/SiteGenerator/Posts/PostsPlugin.swift b/SiteGenerator/Sources/SiteGenerator/Posts/PostsPlugin.swift index cc9c8e7..415b670 100644 --- a/SiteGenerator/Sources/SiteGenerator/Posts/PostsPlugin.swift +++ b/SiteGenerator/Sources/SiteGenerator/Posts/PostsPlugin.swift @@ -29,18 +29,16 @@ final class PostsPlugin: Plugin { let posts = try enumerateMarkdownFiles(directory: postsURL) .compactMap { (url: URL) -> Post? in - guard let result = (try? String(contentsOf: url)).map(markdownParser.parse) else { - return nil - } do { - return try Post(bodyMarkdown: "(TEST)", metadata: result.metadata) + let markdown = try String(contentsOf: url) + let result = markdownParser.parse(markdown) + return try Post(bodyMarkdown: result.html, metadata: result.metadata) } catch { print("Cannot create post from markdown file \(url): \(error)") return nil } } - print("posts: \(posts)") self.posts = PostsByYear(posts: posts) } @@ -76,12 +74,12 @@ final class PostsPlugin: Plugin { func renderYearsAndMonths(postsDir: URL, templateRenderer: TemplateRenderer) throws { print("renderYearsAndMonths(postsDir: \(postsDir), templateRenderer: \(templateRenderer)") - let allMonths = (1 ... 12).reversed().map(Month.init) + let allMonths = (1 ... 12).map(Month.init(_:)) for (year, monthPosts) in posts.byYear.sorted(by: { $1.key < $0.key }) { let yearDir = postsDir.appendingPathComponent("\(year)") - var sortedPostsByMonth: [Int: [RenderedPost]] = [:] + var sortedPostsByMonth: [Month: [RenderedPost]] = [:] for month in allMonths { - let sortedPosts = monthPosts[month.number].posts.sorted(by: { $1.date < $0.date }) + let sortedPosts = monthPosts[month].posts.sorted(by: { $1.date < $0.date }) guard !sortedPosts.isEmpty else { continue } @@ -90,7 +88,7 @@ final class PostsPlugin: Plugin { let bodyHTML = markdownParser.html(from: post.bodyMarkdown) return RenderedPost(post: post, body: bodyHTML) } - sortedPostsByMonth[month.number] = renderedPosts + sortedPostsByMonth[month] = renderedPosts let monthDir = yearDir.appendingPathComponent(month.padded) try fileManager.createDirectory(at: monthDir, withIntermediateDirectories: true, attributes: nil) @@ -101,11 +99,23 @@ final class PostsPlugin: Plugin { } try fileManager.createDirectory(at: yearDir, withIntermediateDirectories: true, attributes: nil) + let months = Array(sortedPostsByMonth.keys.sorted().reversed()) + let postsByMonthForContext: [String: [[String: Any]]] = sortedPostsByMonth.reduce(into: [:]) { dict, pair in + let (month, renderedPosts) = pair + dict[month.padded] = renderedPosts.map { $0.dictionary } + } + let monthsPadded = months.map { $0.padded } let context: [String: Any] = [ "path": path, "year": year, - "months": sortedPostsByMonth.keys.sorted().reversed().map(Month.init), - "postsByMonth": sortedPostsByMonth, + "months": monthsPadded, + "monthNames": months.reduce(into: [String: String](), { dict, month in + dict[month.padded] = month.name + }), + "monthAbbreviations": months.reduce(into: [String: String](), { dict, month in + dict[month.padded] = month.abbreviatedName + }), + "postsByMonth": postsByMonthForContext, ] let yearHTML = try templateRenderer.renderTemplate(name: "posts-year", context: context) let yearURL = yearDir.appendingPathComponent("index.html") @@ -121,7 +131,7 @@ final class PostsPlugin: Plugin { let templateName = self.templateName(for: post) let bodyHTML = markdownParser.html(from: post.bodyMarkdown) let renderedPost = RenderedPost(post: post, body: bodyHTML) - let postHTML = try templateRenderer.renderTemplate(name: templateName, context: ["post": renderedPost]) + let postHTML = try templateRenderer.renderTemplate(name: templateName, context: ["post": renderedPost.dictionary]) try postHTML.write(to: postURL, atomically: true, encoding: .utf8) } diff --git a/SiteGenerator/Sources/SiteGenerator/Posts/RenderedPost.swift b/SiteGenerator/Sources/SiteGenerator/Posts/RenderedPost.swift index 2e5711a..dbdae27 100644 --- a/SiteGenerator/Sources/SiteGenerator/Posts/RenderedPost.swift +++ b/SiteGenerator/Sources/SiteGenerator/Posts/RenderedPost.swift @@ -11,17 +11,17 @@ struct RenderedPost { let post: Post let body: String - var author: String { post.author } - - var title: String { post.title } - - var date: Date { post.date } - - var formattedDate: String { post.formattedDate } - - var isLink: Bool { post.isLink } - - var link: URL? { post.link } - - var path: String { post.path } + var dictionary: [String: Any] { + [ + "author": post.author, + "title": post.title, + "date": post.date, + "day": post.date.day, + "formattedDate": post.formattedDate, + "isLink": post.isLink, + "link": post.link as Any, + "path": post.path, + "body": body, + ] + } } diff --git a/templates/post-text.html b/templates/post-text.html index e98ac06..712c671 100644 --- a/templates/post-text.html +++ b/templates/post-text.html @@ -3,7 +3,7 @@ {% block body %}
-

{{ post.title }}

+

{{ post.title }}

{{ post.body }} diff --git a/templates/posts-year.html b/templates/posts-year.html index 126f52c..86e3b94 100644 --- a/templates/posts-year.html +++ b/templates/posts-year.html @@ -4,24 +4,24 @@

{{ year }}

- {% for month in months %} +{% for month in months %}

- {{ month.name }} + {{ monthNames[month] }}

    - {% for post in postsByMonth[month.number] %} + {% for post in postsByMonth[month] %}
  • - {% if post.isLink %} - → {{ post.title }} - {% else %} - {{ post.title }} - {% endif %} - + {% if post.isLink %} + → {{ post.title }} + {% else %} + {{ post.title }} + {% endif %} +
  • - {% endfor %} + {% endfor %}
- {% endfor %} +{% endfor %}
{% endblock %}