Skip to content

Commit

Permalink
Merge pull request #158 from vapor/tn-userinfo
Browse files Browse the repository at this point in the history
Tags config, files protocol, and context passing
  • Loading branch information
tanner0101 authored Mar 6, 2020
2 parents 45791d3 + 935e3c2 commit c3941cf
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 58 deletions.
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ let package = Package(
.library(name: "Leaf", targets: ["Leaf"]),
],
dependencies: [
.package(url: "https://github.com/vapor/leaf-kit.git", from: "1.0.0-rc.1"),
.package(url: "https://github.com/vapor/leaf-kit.git", from: "1.0.0-rc.1.2"),
.package(url: "https://github.com/vapor/vapor.git", from: "4.0.0-rc.1"),
],
targets: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,62 @@
import Vapor

extension Application.Views.Provider {
public static var leaf: Self {
.init {
$0.views.use {
$0.leaf.renderer
}
}
}
}

extension Application {
public var leaf: Leaf {
.init(application: self)
}

public struct Leaf {
final class Storage {
var cache: LeafCache
public let application: Application

init() {
self.cache = DefaultLeafCache()
public var renderer: LeafRenderer {
.init(
configuration: self.configuration,
cache: self.cache,
files: self.files,
eventLoop: self.application.eventLoopGroup.next(),
userInfo: [
"application": self
]
)
}

public var configuration: LeafConfiguration {
get {
self.storage.configuration ?? LeafConfiguration(
rootDirectory: self.application.directory.viewsDirectory
)
}
nonmutating set {
self.storage.configuration = newValue
}
}

struct Key: StorageKey {
typealias Value = Storage
public var tags: [String: LeafTag] {
get {
self.storage.tags
}
nonmutating set {
self.storage.tags = newValue
}
}

public var renderer: LeafRenderer {
.init(
configuration: .init(
rootDirectory: self.application.directory.viewsDirectory
),
cache: self.cache,
fileio: self.application.fileio,
eventLoop: self.application.eventLoopGroup.next()
)
public var files: LeafFiles {
get {
self.storage.files ?? NIOLeafFiles(fileio: self.application.fileio)
}
nonmutating set {
self.storage.files = newValue
}
}

public var cache: LeafCache {
Expand All @@ -48,53 +78,27 @@ extension Application {
}
}

public let application: Application
}
}

struct Key: StorageKey {
typealias Value = Storage
}

extension Request {
var leaf: LeafRenderer {
.init(
configuration: .init(rootDirectory: self.application.directory.viewsDirectory),
cache: self.application.leaf.cache,
fileio: self.application.fileio,
eventLoop: self.eventLoop
)
}
}
final class Storage {
var cache: LeafCache
var configuration: LeafConfiguration?
var files: LeafFiles?
var tags: [String: LeafTag]

extension LeafRenderer: ViewRenderer {
public func `for`(_ request: Request) -> ViewRenderer {
LeafRenderer(
configuration: self.configuration,
cache: self.cache,
fileio: self.fileio,
eventLoop: request.eventLoop
)
}

public func render<E>(_ name: String, _ context: E) -> EventLoopFuture<View>
where E: Encodable
{
let data: [String: LeafData]
do {
data = try LeafEncoder().encode(context)
} catch {
return self.eventLoop.makeFailedFuture(error)
}
return self.render(path: name, context: data).map { buffer in
return View(data: buffer)
init() {
self.cache = DefaultLeafCache()
self.tags = LeafKit.defaultTags
}
}
}
}

extension Application.Views.Provider {
public static var leaf: Self {
.init {
$0.views.use {
$0.leaf.renderer
}
}

extension LeafContext {
public var application: Application? {
self.userInfo["application"] as? Application
}
}
21 changes: 21 additions & 0 deletions Sources/Leaf/LeafRenderer+ViewRenderer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Vapor

extension LeafRenderer: ViewRenderer {
public func `for`(_ request: Request) -> ViewRenderer {
request.leaf
}

public func render<E>(_ name: String, _ context: E) -> EventLoopFuture<View>
where E: Encodable
{
let data: [String: LeafData]
do {
data = try LeafEncoder().encode(context)
} catch {
return self.eventLoop.makeFailedFuture(error)
}
return self.render(path: name, context: data).map { buffer in
return View(data: buffer)
}
}
}
23 changes: 23 additions & 0 deletions Sources/Leaf/Request+Leaf.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Vapor

extension Request {
var leaf: LeafRenderer {
.init(
configuration: self.application.leaf.configuration,
tags: self.application.leaf.tags,
cache: self.application.leaf.cache,
files: self.application.leaf.files,
eventLoop: self.eventLoop,
userInfo: [
"request": self,
"application": self.application
]
)
}
}

extension LeafContext {
public var request: Request? {
self.userInfo["request"] as? Request
}
}
52 changes: 52 additions & 0 deletions Tests/LeafTests/LeafTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,56 @@ class LeafTests: XCTestCase {
XCTAssertContains(res.body.string, "test: bar")
}
}

func testContextRequest() throws {
var test = TestFiles()
test.files["/foo.leaf"] = """
Hello #(name) @ #path()
"""

struct RequestPathTag: LeafTag {
func render(_ ctx: LeafContext) throws -> LeafData {
.string(ctx.request?.url.path ?? "")
}
}

let app = Application(.testing)
defer { app.shutdown() }

app.views.use(.leaf)
app.leaf.configuration.rootDirectory = "/"
app.leaf.cache.isEnabled = false
app.leaf.tags["path"] = RequestPathTag()
app.leaf.files = test

app.get("test-file") { req in
req.view.render("foo", [
"name": "vapor"
])
}

try app.test(.GET, "test-file") { res in
XCTAssertEqual(res.status, .ok)
XCTAssertEqual(res.headers.contentType, .html)
XCTAssertEqual(res.body.string, "Hello vapor @ /test-file")
}
}
}

struct TestFiles: LeafFiles {
var files: [String: String]

init() {
files = [:]
}

func file(path: String, on eventLoop: EventLoop) -> EventLoopFuture<ByteBuffer> {
if let file = self.files[path] {
var buffer = ByteBufferAllocator().buffer(capacity: 0)
buffer.writeString(file)
return eventLoop.makeSucceededFuture(buffer)
} else {
return eventLoop.makeFailedFuture("no test file: \(path)")
}
}
}

0 comments on commit c3941cf

Please sign in to comment.