Expose adding plugins as a public API on SiteGenerator

This commit is contained in:
Sami Samhuri 2019-12-14 13:15:18 -08:00
parent 1f3be38c5c
commit 487875098a
4 changed files with 55 additions and 16 deletions

View file

@ -0,0 +1,30 @@
//
// AnyPlugin.swift
// SiteGenerator
//
// Created by Sami Samhuri on 2019-12-14.
//
import Foundation
struct AnyPlugin: Plugin {
private let _setUp: (Site, URL) throws -> Void
private let _render: (Site, URL, TemplateRenderer) throws -> Void
init<PluginType: Plugin>(_ plugin: PluginType) {
self._setUp = { site, sourceURL in
try plugin.setUp(site: site, sourceURL: sourceURL)
}
self._render = { site, targetURL, templateRenderer in
try plugin.render(site: site, targetURL: targetURL, templateRenderer: templateRenderer)
}
}
func setUp(site: Site, sourceURL: URL) throws {
try _setUp(site, sourceURL)
}
func render(site: Site, targetURL: URL, templateRenderer: TemplateRenderer) throws {
try _render(site, targetURL, templateRenderer)
}
}

View file

@ -8,8 +8,6 @@
import Foundation import Foundation
public protocol Plugin { public protocol Plugin {
init(options: [String: Any])
func setUp(site: Site, sourceURL: URL) throws func setUp(site: Site, sourceURL: URL) throws
func render(site: Site, targetURL: URL, templateRenderer: TemplateRenderer) throws func render(site: Site, targetURL: URL, templateRenderer: TemplateRenderer) throws

View file

@ -10,4 +10,16 @@ import Foundation
public enum SitePlugin: String, Codable { public enum SitePlugin: String, Codable {
case posts case posts
case projects case projects
func construct(options: [String: Any]) -> AnyPlugin {
switch self {
case .posts:
let plugin = PostsPlugin(options: options)
return AnyPlugin(plugin)
case .projects:
let plugin = ProjectsPlugin(options: options)
return AnyPlugin(plugin)
}
}
} }

View file

@ -13,10 +13,10 @@ public final class SiteGenerator {
let templateRenderer: TemplateRenderer let templateRenderer: TemplateRenderer
// Site properties // Site properties
let site: Site public let site: Site
let sourceURL: URL public let sourceURL: URL
var plugins: [Plugin] = [] public private(set) var plugins: [Plugin] = []
let renderers: [Renderer] public let renderers: [Renderer]
let ignoredFilenames = [".DS_Store", ".gitkeep"] let ignoredFilenames = [".DS_Store", ".gitkeep"]
@ -39,17 +39,16 @@ public final class SiteGenerator {
} }
private func initializePlugins() throws { private func initializePlugins() throws {
plugins = site.plugins.map { (sitePlugin, options) in plugins = site.plugins.map { pair in
switch sitePlugin { let (sitePlugin, options) = pair
case .projects: return sitePlugin.construct(options: options)
return ProjectsPlugin(options: options)
case .posts:
return PostsPlugin(options: options)
}
}
for plugin in plugins {
try plugin.setUp(site: site, sourceURL: sourceURL)
} }
try plugins.forEach(addPlugin)
}
public func addPlugin(_ plugin: Plugin) throws {
try plugin.setUp(site: site, sourceURL: sourceURL)
plugins.append(plugin)
} }
public func generate(targetURL: URL) throws { public func generate(targetURL: URL) throws {