From 1426b4e75b3800e9f7780c5882f2f4ce03757942 Mon Sep 17 00:00:00 2001 From: Sami Samhuri Date: Wed, 11 Dec 2019 00:00:05 -0800 Subject: [PATCH] Explicitly activate plugins via site.json --- .../SiteGenerator/Feeds/JSONFeedPlugin.swift | 9 ++++++++ .../SiteGenerator/Feeds/RSSFeedPlugin.swift | 9 ++++++++ .../SiteGenerator/Generator/Generator.swift | 21 ++++++++++++++++--- .../SiteGenerator/Generator/HumanSite.swift | 11 +++++++++- .../SiteGenerator/Generator/Plugin.swift | 2 ++ .../SiteGenerator/Generator/Site.swift | 2 ++ .../SiteGenerator/Generator/SitePlugin.swift | 15 +++++++++++++ .../SiteGenerator/Posts/PostsPlugin.swift | 9 ++++++++ .../Projects/ProjectsPlugin.swift | 9 ++++++++ Tests/test-posts/in/site.json | 5 ++++- Tests/test-projects/in/site.json | 5 ++++- site.json | 7 +++++++ 12 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 SiteGenerator/Sources/SiteGenerator/Generator/SitePlugin.swift diff --git a/SiteGenerator/Sources/SiteGenerator/Feeds/JSONFeedPlugin.swift b/SiteGenerator/Sources/SiteGenerator/Feeds/JSONFeedPlugin.swift index fd9497a..2976c7c 100644 --- a/SiteGenerator/Sources/SiteGenerator/Feeds/JSONFeedPlugin.swift +++ b/SiteGenerator/Sources/SiteGenerator/Feeds/JSONFeedPlugin.swift @@ -21,6 +21,15 @@ final class JSONFeedPlugin: Plugin { // MARK: - Plugin methods + convenience init(options: [String: Any]) { + if let feedPath = options["feed_path"] as? String { + self.init(jsonFeedWriter: JSONFeedWriter(feedPath: feedPath)) + } + else { + self.init() + } + } + func setUp(site: Site, sourceURL: URL) throws { guard postRepo.postDataExists(at: sourceURL) else { return diff --git a/SiteGenerator/Sources/SiteGenerator/Feeds/RSSFeedPlugin.swift b/SiteGenerator/Sources/SiteGenerator/Feeds/RSSFeedPlugin.swift index 46758d7..2665ef5 100644 --- a/SiteGenerator/Sources/SiteGenerator/Feeds/RSSFeedPlugin.swift +++ b/SiteGenerator/Sources/SiteGenerator/Feeds/RSSFeedPlugin.swift @@ -21,6 +21,15 @@ final class RSSFeedPlugin: Plugin { // MARK: - Plugin methods + convenience init(options: [String: Any]) { + if let feedPath = options["feed_path"] as? String { + self.init(rssFeedWriter: RSSFeedWriter(feedPath: feedPath)) + } + else { + self.init() + } + } + func setUp(site: Site, sourceURL: URL) throws { guard postRepo.postDataExists(at: sourceURL) else { return diff --git a/SiteGenerator/Sources/SiteGenerator/Generator/Generator.swift b/SiteGenerator/Sources/SiteGenerator/Generator/Generator.swift index 82a44c3..be6647b 100644 --- a/SiteGenerator/Sources/SiteGenerator/Generator/Generator.swift +++ b/SiteGenerator/Sources/SiteGenerator/Generator/Generator.swift @@ -15,12 +15,12 @@ public final class Generator { // Site properties let site: Site let sourceURL: URL - let plugins: [Plugin] + var plugins: [Plugin] = [] let renderers: [Renderer] let ignoredFilenames = [".DS_Store", ".gitkeep"] - public init(sourceURL: URL, plugins: [Plugin], renderers: [Renderer]) throws { + public init(sourceURL: URL, renderers: [Renderer]) throws { let siteURL = sourceURL.appendingPathComponent("site.json") let site = try Site.decode(from: siteURL) @@ -29,9 +29,24 @@ public final class Generator { self.site = site self.sourceURL = sourceURL - self.plugins = plugins self.renderers = renderers + try initializePlugins() + } + + private func initializePlugins() throws { + plugins = site.plugins.map { (sitePlugin, options) in + switch sitePlugin { + case .projects: + return ProjectsPlugin(options: options) + case .posts: + return PostsPlugin(options: options) + case .jsonFeed: + return JSONFeedPlugin(options: options) + case .rssFeed: + return RSSFeedPlugin(options: options) + } + } for plugin in plugins { try plugin.setUp(site: site, sourceURL: sourceURL) } diff --git a/SiteGenerator/Sources/SiteGenerator/Generator/HumanSite.swift b/SiteGenerator/Sources/SiteGenerator/Generator/HumanSite.swift index f53306c..b98778e 100644 --- a/SiteGenerator/Sources/SiteGenerator/Generator/HumanSite.swift +++ b/SiteGenerator/Sources/SiteGenerator/Generator/HumanSite.swift @@ -20,6 +20,7 @@ struct HumanSite: Codable { let avatar: String? let icon: String? let favicon: String? + let plugins: [String: [String: String]]? } extension Site { @@ -35,7 +36,15 @@ extension Site { scripts: humanSite.scripts ?? [], avatarPath: humanSite.avatar, iconPath: humanSite.icon, - faviconPath: humanSite.favicon + faviconPath: humanSite.favicon, + plugins: (humanSite.plugins ?? [:]).reduce(into: [:], { dict, pair in + let (name, options) = pair + guard let sitePlugin = SitePlugin(rawValue: name) else { + print("warning: unknown site plugin \"\(name)\"") + return + } + dict[sitePlugin] = options + }) ) } } diff --git a/SiteGenerator/Sources/SiteGenerator/Generator/Plugin.swift b/SiteGenerator/Sources/SiteGenerator/Generator/Plugin.swift index 785527b..6cc5e18 100644 --- a/SiteGenerator/Sources/SiteGenerator/Generator/Plugin.swift +++ b/SiteGenerator/Sources/SiteGenerator/Generator/Plugin.swift @@ -8,6 +8,8 @@ import Foundation public protocol Plugin { + init(options: [String: Any]) + func setUp(site: Site, sourceURL: URL) throws func render(site: Site, targetURL: URL, templateRenderer: TemplateRenderer) throws diff --git a/SiteGenerator/Sources/SiteGenerator/Generator/Site.swift b/SiteGenerator/Sources/SiteGenerator/Generator/Site.swift index 307fdd1..a66426c 100644 --- a/SiteGenerator/Sources/SiteGenerator/Generator/Site.swift +++ b/SiteGenerator/Sources/SiteGenerator/Generator/Site.swift @@ -21,6 +21,8 @@ public struct Site { public let avatarPath: String? public let iconPath: String? public let faviconPath: String? + + public let plugins: [SitePlugin: [String: Any]] } extension Site { diff --git a/SiteGenerator/Sources/SiteGenerator/Generator/SitePlugin.swift b/SiteGenerator/Sources/SiteGenerator/Generator/SitePlugin.swift new file mode 100644 index 0000000..b2089bb --- /dev/null +++ b/SiteGenerator/Sources/SiteGenerator/Generator/SitePlugin.swift @@ -0,0 +1,15 @@ +// +// SitePlugin.swift +// SiteGenerator +// +// Created by Sami Samhuri on 2019-12-10. +// + +import Foundation + +public enum SitePlugin: String, Codable { + case posts + case projects + case jsonFeed = "json_feed" + case rssFeed = "rss_feed" +} diff --git a/SiteGenerator/Sources/SiteGenerator/Posts/PostsPlugin.swift b/SiteGenerator/Sources/SiteGenerator/Posts/PostsPlugin.swift index 8d40250..cbfd997 100644 --- a/SiteGenerator/Sources/SiteGenerator/Posts/PostsPlugin.swift +++ b/SiteGenerator/Sources/SiteGenerator/Posts/PostsPlugin.swift @@ -21,6 +21,15 @@ final class PostsPlugin: Plugin { // MARK: - Plugin methods + convenience init(options: [String: Any]) { + if let outputPath = options["path"] as? String { + self.init(postWriter: PostWriter(outputPath: outputPath)) + } + else { + self.init() + } + } + func setUp(site: Site, sourceURL: URL) throws { guard postRepo.postDataExists(at: sourceURL) else { return diff --git a/SiteGenerator/Sources/SiteGenerator/Projects/ProjectsPlugin.swift b/SiteGenerator/Sources/SiteGenerator/Projects/ProjectsPlugin.swift index ce74912..0fe76b9 100644 --- a/SiteGenerator/Sources/SiteGenerator/Projects/ProjectsPlugin.swift +++ b/SiteGenerator/Sources/SiteGenerator/Projects/ProjectsPlugin.swift @@ -28,6 +28,15 @@ final class ProjectsPlugin: Plugin { self.outputPath = outputPath } + convenience init(options: [String: Any]) { + if let outputPath = options["path"] as? String { + self.init(outputPath: outputPath) + } + else { + self.init() + } + } + func setUp(site: Site, sourceURL: URL) throws { self.sourceURL = sourceURL let projectsURL = sourceURL.appendingPathComponent("projects.json") diff --git a/Tests/test-posts/in/site.json b/Tests/test-posts/in/site.json index 7d0ae63..cbcdfab 100644 --- a/Tests/test-posts/in/site.json +++ b/Tests/test-posts/in/site.json @@ -1,5 +1,8 @@ { "author": "Hunter S. Thompson", "title": "gonzo journalism", - "url": "http://example.net" + "url": "http://example.net", + "plugins": { + "posts": {} + } } diff --git a/Tests/test-projects/in/site.json b/Tests/test-projects/in/site.json index 1aca942..3767499 100644 --- a/Tests/test-projects/in/site.json +++ b/Tests/test-projects/in/site.json @@ -1,5 +1,8 @@ { "author": "Linus Torvalds", "title": "Nvidia, fuck you!", - "url": "http://example.net" + "url": "http://example.net", + "plugins": { + "projects": {} + } } diff --git a/site.json b/site.json index 514caf6..cc58a7d 100644 --- a/site.json +++ b/site.json @@ -12,4 +12,11 @@ "icon": "images/apple-touch-icon-300.png", "favicon": "images/apple-touch-icon-80.png", "avatar": "images/me.jpg", + "plugins": { + "projects": {}, + "posts": { + "json_feed": "feed.json", + "rss_feed": "feed.xml" + } + } }