Explicitly activate plugins via site.json

This commit is contained in:
Sami Samhuri 2019-12-11 00:00:05 -08:00
parent 34136951c4
commit 1426b4e75b
12 changed files with 98 additions and 6 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,5 +1,8 @@
{
"author": "Hunter S. Thompson",
"title": "gonzo journalism",
"url": "http://example.net"
"url": "http://example.net",
"plugins": {
"posts": {}
}
}

View file

@ -1,5 +1,8 @@
{
"author": "Linus Torvalds",
"title": "Nvidia, fuck you!",
"url": "http://example.net"
"url": "http://example.net",
"plugins": {
"projects": {}
}
}

View file

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