mirror of
https://github.com/samsonjs/samhuri.net.git
synced 2026-04-27 14:57:40 +00:00
Add specific types for scripts and stylesheets
This commit is contained in:
parent
9dfd5080ef
commit
96b249a21c
10 changed files with 100 additions and 33 deletions
37
samhuri.net/Sources/samhuri.net/Posts/Model/HTMLRef.swift
Normal file
37
samhuri.net/Sources/samhuri.net/Posts/Model/HTMLRef.swift
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
//
|
||||||
|
// HTMLRef.swift
|
||||||
|
// samhuri.net
|
||||||
|
//
|
||||||
|
// Created by Sami Samhuri on 2020-01-02.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
protocol HTMLRef: ExpressibleByStringLiteral {
|
||||||
|
// Concrete requirements, must be implemented
|
||||||
|
|
||||||
|
var ref: String { get }
|
||||||
|
|
||||||
|
// These all have default implementations
|
||||||
|
|
||||||
|
init(ref: String)
|
||||||
|
|
||||||
|
func url(dir: URL) -> URL
|
||||||
|
}
|
||||||
|
|
||||||
|
extension HTMLRef {
|
||||||
|
init(stringLiteral value: String) {
|
||||||
|
self.init(ref: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func url(dir: URL) -> URL {
|
||||||
|
// ref is either an absolute HTTP URL or path relative to the given directory.
|
||||||
|
isHTTPURL ? URL(string: ref)! : dir.appendingPathComponent(ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension HTMLRef {
|
||||||
|
var isHTTPURL: Bool {
|
||||||
|
ref.hasPrefix("http:") || ref.hasPrefix("https:")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,8 +15,8 @@ struct Post {
|
||||||
let formattedDate: String
|
let formattedDate: String
|
||||||
let link: URL?
|
let link: URL?
|
||||||
let tags: [String]
|
let tags: [String]
|
||||||
let scripts: [String]
|
let scripts: [Script]
|
||||||
let styles: [String]
|
let styles: [Stylesheet]
|
||||||
let body: String
|
let body: String
|
||||||
let path: String
|
let path: String
|
||||||
|
|
||||||
|
|
|
||||||
12
samhuri.net/Sources/samhuri.net/Posts/Model/Script.swift
Normal file
12
samhuri.net/Sources/samhuri.net/Posts/Model/Script.swift
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
//
|
||||||
|
// Script.swift
|
||||||
|
// samhuri.net
|
||||||
|
//
|
||||||
|
// Created by Sami Samhuri on 2020-01-02.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct Script: HTMLRef, Equatable {
|
||||||
|
let ref: String
|
||||||
|
}
|
||||||
12
samhuri.net/Sources/samhuri.net/Posts/Model/Stylesheet.swift
Normal file
12
samhuri.net/Sources/samhuri.net/Posts/Model/Stylesheet.swift
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
//
|
||||||
|
// Stylesheet.swift
|
||||||
|
// samhuri.net
|
||||||
|
//
|
||||||
|
// Created by Sami Samhuri on 2020-01-02.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct Stylesheet: HTMLRef, Equatable {
|
||||||
|
let ref: String
|
||||||
|
}
|
||||||
|
|
@ -14,8 +14,8 @@ struct PostMetadata {
|
||||||
let formattedDate: String
|
let formattedDate: String
|
||||||
let link: URL?
|
let link: URL?
|
||||||
let tags: [String]
|
let tags: [String]
|
||||||
let scripts: [String]
|
let scripts: [Script]
|
||||||
let styles: [String]
|
let styles: [Stylesheet]
|
||||||
}
|
}
|
||||||
|
|
||||||
extension PostMetadata {
|
extension PostMetadata {
|
||||||
|
|
@ -41,8 +41,8 @@ extension PostMetadata {
|
||||||
formattedDate: dictionary["Date"]!,
|
formattedDate: dictionary["Date"]!,
|
||||||
link: dictionary["Link"].flatMap { URL(string: $0) },
|
link: dictionary["Link"].flatMap { URL(string: $0) },
|
||||||
tags: dictionary.commaSeparatedList(key: "Tags"),
|
tags: dictionary.commaSeparatedList(key: "Tags"),
|
||||||
scripts: dictionary.commaSeparatedList(key: "Scripts"),
|
scripts: dictionary.commaSeparatedList(key: "Scripts").map(Script.init(ref:)),
|
||||||
styles: dictionary.commaSeparatedList(key: "Styles")
|
styles: dictionary.commaSeparatedList(key: "Styles").map(Stylesheet.init(ref:))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ extension Site {
|
||||||
private let email: String
|
private let email: String
|
||||||
private let url: URL
|
private let url: URL
|
||||||
|
|
||||||
private var styles: [String] = []
|
private var scripts: [Script] = []
|
||||||
private var scripts: [String] = []
|
private var styles: [Stylesheet] = []
|
||||||
|
|
||||||
private var plugins: [Plugin] = []
|
private var plugins: [Plugin] = []
|
||||||
private var renderers: [Renderer] = []
|
private var renderers: [Renderer] = []
|
||||||
|
|
@ -35,13 +35,13 @@ extension Site {
|
||||||
self.url = url
|
self.url = url
|
||||||
}
|
}
|
||||||
|
|
||||||
func styles(_ styles: String...) -> Self {
|
func scripts(_ scripts: String...) -> Self {
|
||||||
self.styles.append(contentsOf: styles)
|
self.scripts.append(contentsOf: scripts.map(Script.init(ref:)))
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func scripts(_ scripts: String...) -> Self {
|
func styles(_ styles: String...) -> Self {
|
||||||
self.scripts.append(contentsOf: scripts)
|
self.styles.append(contentsOf: styles.map(Stylesheet.init(ref:)))
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,8 +62,8 @@ extension Site {
|
||||||
title: title,
|
title: title,
|
||||||
description: description,
|
description: description,
|
||||||
url: url,
|
url: url,
|
||||||
styles: styles,
|
|
||||||
scripts: scripts,
|
scripts: scripts,
|
||||||
|
styles: styles,
|
||||||
renderers: renderers,
|
renderers: renderers,
|
||||||
plugins: plugins
|
plugins: plugins
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ struct Site {
|
||||||
let title: String
|
let title: String
|
||||||
let description: String
|
let description: String
|
||||||
let url: URL
|
let url: URL
|
||||||
let styles: [String]
|
let scripts: [Script]
|
||||||
let scripts: [String]
|
let styles: [Stylesheet]
|
||||||
let renderers: [Renderer]
|
let renderers: [Renderer]
|
||||||
let plugins: [Plugin]
|
let plugins: [Plugin]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@ final class PageRenderer {
|
||||||
extension PageRenderer: PageRendering {
|
extension PageRenderer: PageRendering {
|
||||||
func renderPage(site: Site, bodyHTML: String, metadata: [String: String]) throws -> String {
|
func renderPage(site: Site, bodyHTML: String, metadata: [String: String]) throws -> String {
|
||||||
let pageTitle = metadata["Title"]
|
let pageTitle = metadata["Title"]
|
||||||
let scripts = metadata.commaSeparatedList(key: "Scripts")
|
let scripts = metadata.commaSeparatedList(key: "Scripts").map(Script.init(ref:))
|
||||||
let styles = metadata.commaSeparatedList(key: "Styles")
|
let styles = metadata.commaSeparatedList(key: "Styles").map(Stylesheet.init(ref:))
|
||||||
let assets = TemplateAssets(scripts: scripts, styles: styles)
|
let assets = TemplateAssets(scripts: scripts, styles: styles)
|
||||||
let context = SiteContext(site: site, subtitle: pageTitle, templateAssets: assets)
|
let context = SiteContext(site: site, subtitle: pageTitle, templateAssets: assets)
|
||||||
return render(.page(title: pageTitle ?? "", bodyHTML: bodyHTML), context: context)
|
return render(.page(title: pageTitle ?? "", bodyHTML: bodyHTML), context: context)
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct TemplateAssets {
|
struct TemplateAssets {
|
||||||
var scripts: [String]
|
var scripts: [Script]
|
||||||
var styles: [String]
|
var styles: [Stylesheet]
|
||||||
|
|
||||||
static func empty() -> TemplateAssets {
|
static func empty() -> TemplateAssets {
|
||||||
TemplateAssets(scripts: [], styles: [])
|
TemplateAssets(scripts: [], styles: [])
|
||||||
|
|
|
||||||
|
|
@ -28,17 +28,17 @@ protocol TemplateContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TemplateContext {
|
extension TemplateContext {
|
||||||
var styles: [URL] {
|
|
||||||
let allStyles = site.styles + templateAssets.styles
|
|
||||||
return allStyles.map { style in
|
|
||||||
style.hasPrefix("http") ? URL(string: style)! : styleURL(style)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var scripts: [URL] {
|
var scripts: [URL] {
|
||||||
let allScripts = site.scripts + templateAssets.scripts
|
let allScripts = site.scripts + templateAssets.scripts
|
||||||
return allScripts.map { script in
|
return allScripts.map { script in
|
||||||
script.hasPrefix("http") ? URL(string: script)! : scriptURL(script)
|
script.url(dir: scriptDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var styles: [URL] {
|
||||||
|
let allStyles = site.styles + templateAssets.styles
|
||||||
|
return allStyles.map { style in
|
||||||
|
style.url(dir: styleDir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,14 +57,20 @@ extension TemplateContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
func scriptURL(_ filename: String) -> URL {
|
func scriptURL(_ filename: String) -> URL {
|
||||||
site.url
|
scriptDir.appendingPathComponent(filename)
|
||||||
.appendingPathComponent("js")
|
|
||||||
.appendingPathComponent(filename)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func styleURL(_ filename: String) -> URL {
|
func styleURL(_ filename: String) -> URL {
|
||||||
site.url
|
styleDir.appendingPathComponent(filename)
|
||||||
.appendingPathComponent("css")
|
}
|
||||||
.appendingPathComponent(filename)
|
}
|
||||||
|
|
||||||
|
private extension TemplateContext {
|
||||||
|
var scriptDir: URL {
|
||||||
|
site.url.appendingPathComponent("js")
|
||||||
|
}
|
||||||
|
|
||||||
|
var styleDir: URL {
|
||||||
|
site.url.appendingPathComponent("css")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue