[ad_1]
A quick CSS demo project
The very first step is to add Leaf as a dependency to your project. You should note that Leaf 4 is not finished yet and these brand new features are only available from the tau pre-release.
import PackageDescription
let package = Package(
name: "myProject",
platforms: [
.macOS(.v10_15)
],
dependencies: [
.package(url: "https://github.com/vapor/vapor", from: "4.32.0"),
.package(url: "https://github.com/vapor/leaf", .exact("4.0.0-tau.1")),
.package(url: "https://github.com/vapor/leaf-kit", .exact("1.0.0-tau.1.1")),
],
targets: [
.target(name: "App", dependencies: [
.product(name: "Leaf", package: "leaf"),
.product(name: "Vapor", package: "vapor"),
]),
.target(name: "Run", dependencies: ["App"]),
.testTarget(name: "AppTests", dependencies: [
.target(name: "App"),
.product(name: "XCTVapor", package: "vapor"),
])
]
)
We are ready to import Leaf
in your Swift files, since there is a new LeafFileMiddleware
available as part of Leaf we’re going to create some publicly available template files and use this middleware to render them. Create a new Public
directory inside the root folder of the project and place an new index.html
file there. You can also use a .leaf
extension, but for the sake of simplicity (and Xcode syntax highlighting reasons) we’re going to use the .html
extension this time.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>#(title)</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<header>
<h1>#(title)</h1>
</header>
</body>
</html>
Pretty basic HTML5 boilerplate code, except that we’ll print the title using a Leaf tag. We’re going to set a value for this context variable through some Swift code in a moment. In the head section we also import our css/style.css
stylesheet file. Now you should create a css
folder inside the Public directory and place a style.css
file inside of it.
* {
margin: 0;
padding: 0;
}
body {
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Helvetica", "Segoe UI", Roboto, Ubuntu;
font-size: 16px;
line-height: 1.4em;
background: #(background);
}
h1 {
padding: #(padding);
}
@media (max-width: 599px) {}
@media (min-width: 600px) {}
@media (min-width: 900px) {}
@media (min-width: 1200px) {}
@media (min-width: 1800px) {}
Since this file is “secretly” a leaf template file we can use the #(variable)
syntax to print out values. We are going to pass a background
color key and a padding
key with some custom values as context variables.
Now let me show you how to configure this new LeafFileMiddleware, so we can render both our html and css templates.
import Vapor
import Leaf
public func configure(_ app: Application) throws {
if !app.environment.isRelease {
LeafRenderer.Option.caching = .bypass
}
LeafFileMiddleware.defaultMediaType = .html
LeafFileMiddleware.processableExtensions = ["leaf", "html", "css", "js"]
LeafFileMiddleware.contexts = [
.css: [
"background": "#eee",
"padding": "16px",
],
.html: [
"title": "Hello world!"
],
]
if let lfm = LeafFileMiddleware(publicDirectory: app.directory.publicDirectory) {
app.middleware.use(lfm)
}
app.views.use(.leaf)
}
First we disable the cache, but that’s a pretty obvious chunk of code, next we set the default media type to html. This will be used to set the Content-Type
header if the file extension in the request is an unknown type. The processableExtensions
property will tell the LeafFileMiddleware to process and render only these files, everything else with a different extension will be streamed just like when you use a regular FileMiddleware
.
As you can see we can set different context values for specific media types, in our case all the css files can use the background and padding properties and every html file can take advantage of the title context variable. It is also possible to set them through a subscript syntax:
LeafFileMiddleware[.css] = [
"background": "green",
"padding": "16px",
]
LeafFileMiddleware[.html] = [
"title": "Hello world!"
]
The very last step is to create the actual middleware with a publicDirectory
argument. This directory is the location where the system will look for publicly available files and if needed they can be processed as regular Leaf templates. You can also setup directory indexing through the LeafFileMiddleware, but that’s a different topic.
If you navigate to the http://localhost:8080/index.html
address you should see your rendered index.html file with the right stylesheet applied to it. Of course you can register a custom route and render your templates using the usual Resources / Views location if needed, but I just wanted to show you this cool trick, since it enables us to serve public files using a more dynamic approach.
[ad_2]
Source link