mirror of
https://github.com/samsonjs/samhuri.net.git
synced 2026-04-27 14:57:40 +00:00
Explicitly activate plugins via site.json
This commit is contained in:
parent
34136951c4
commit
1426b4e75b
12 changed files with 98 additions and 6 deletions
|
|
@ -21,6 +21,15 @@ final class JSONFeedPlugin: Plugin {
|
||||||
|
|
||||||
// MARK: - Plugin methods
|
// 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 {
|
func setUp(site: Site, sourceURL: URL) throws {
|
||||||
guard postRepo.postDataExists(at: sourceURL) else {
|
guard postRepo.postDataExists(at: sourceURL) else {
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,15 @@ final class RSSFeedPlugin: Plugin {
|
||||||
|
|
||||||
// MARK: - Plugin methods
|
// 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 {
|
func setUp(site: Site, sourceURL: URL) throws {
|
||||||
guard postRepo.postDataExists(at: sourceURL) else {
|
guard postRepo.postDataExists(at: sourceURL) else {
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@ public final class Generator {
|
||||||
// Site properties
|
// Site properties
|
||||||
let site: Site
|
let site: Site
|
||||||
let sourceURL: URL
|
let sourceURL: URL
|
||||||
let plugins: [Plugin]
|
var plugins: [Plugin] = []
|
||||||
let renderers: [Renderer]
|
let renderers: [Renderer]
|
||||||
|
|
||||||
let ignoredFilenames = [".DS_Store", ".gitkeep"]
|
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 siteURL = sourceURL.appendingPathComponent("site.json")
|
||||||
let site = try Site.decode(from: siteURL)
|
let site = try Site.decode(from: siteURL)
|
||||||
|
|
||||||
|
|
@ -29,9 +29,24 @@ public final class Generator {
|
||||||
|
|
||||||
self.site = site
|
self.site = site
|
||||||
self.sourceURL = sourceURL
|
self.sourceURL = sourceURL
|
||||||
self.plugins = plugins
|
|
||||||
self.renderers = renderers
|
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 {
|
for plugin in plugins {
|
||||||
try plugin.setUp(site: site, sourceURL: sourceURL)
|
try plugin.setUp(site: site, sourceURL: sourceURL)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ struct HumanSite: Codable {
|
||||||
let avatar: String?
|
let avatar: String?
|
||||||
let icon: String?
|
let icon: String?
|
||||||
let favicon: String?
|
let favicon: String?
|
||||||
|
let plugins: [String: [String: String]]?
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Site {
|
extension Site {
|
||||||
|
|
@ -35,7 +36,15 @@ extension Site {
|
||||||
scripts: humanSite.scripts ?? [],
|
scripts: humanSite.scripts ?? [],
|
||||||
avatarPath: humanSite.avatar,
|
avatarPath: humanSite.avatar,
|
||||||
iconPath: humanSite.icon,
|
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
|
||||||
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ public struct Site {
|
||||||
public let avatarPath: String?
|
public let avatarPath: String?
|
||||||
public let iconPath: String?
|
public let iconPath: String?
|
||||||
public let faviconPath: String?
|
public let faviconPath: String?
|
||||||
|
|
||||||
|
public let plugins: [SitePlugin: [String: Any]]
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Site {
|
extension Site {
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,15 @@ final class PostsPlugin: Plugin {
|
||||||
|
|
||||||
// MARK: - Plugin methods
|
// 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 {
|
func setUp(site: Site, sourceURL: URL) throws {
|
||||||
guard postRepo.postDataExists(at: sourceURL) else {
|
guard postRepo.postDataExists(at: sourceURL) else {
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,15 @@ final class ProjectsPlugin: Plugin {
|
||||||
self.outputPath = outputPath
|
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 {
|
func setUp(site: Site, sourceURL: URL) throws {
|
||||||
self.sourceURL = sourceURL
|
self.sourceURL = sourceURL
|
||||||
let projectsURL = sourceURL.appendingPathComponent("projects.json")
|
let projectsURL = sourceURL.appendingPathComponent("projects.json")
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
{
|
{
|
||||||
"author": "Hunter S. Thompson",
|
"author": "Hunter S. Thompson",
|
||||||
"title": "gonzo journalism",
|
"title": "gonzo journalism",
|
||||||
"url": "http://example.net"
|
"url": "http://example.net",
|
||||||
|
"plugins": {
|
||||||
|
"posts": {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
{
|
{
|
||||||
"author": "Linus Torvalds",
|
"author": "Linus Torvalds",
|
||||||
"title": "Nvidia, fuck you!",
|
"title": "Nvidia, fuck you!",
|
||||||
"url": "http://example.net"
|
"url": "http://example.net",
|
||||||
|
"plugins": {
|
||||||
|
"projects": {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,11 @@
|
||||||
"icon": "images/apple-touch-icon-300.png",
|
"icon": "images/apple-touch-icon-300.png",
|
||||||
"favicon": "images/apple-touch-icon-80.png",
|
"favicon": "images/apple-touch-icon-80.png",
|
||||||
"avatar": "images/me.jpg",
|
"avatar": "images/me.jpg",
|
||||||
|
"plugins": {
|
||||||
|
"projects": {},
|
||||||
|
"posts": {
|
||||||
|
"json_feed": "feed.json",
|
||||||
|
"rss_feed": "feed.xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue