Swift5.3-Vapor4-Leaf4教程(三)
在本章中,我们将使用Leaf模板引擎构建我们的第一个网站。我们将编写一些基本的HTML和CSS代码,并学习如何使用上下文将Swift对象与模板引擎连接。Leaf是一个轻量级但功能强大的模板引擎,具有Swift启发式语法。您可以使用它为前端网站生成动态HTML页面。使用模板引擎有其自身的优势,首先,您不必将Swift代码与HTML,CSS甚至JavaScript代码混合使用。分离视图层总是一件好事,但这也意味着您可以实现同一事物的多个视图。您可以为您的网站提供主题支持。通过创建Leaf模板,您还必须编写许多HTML代码。如果您已经熟悉HTML,那么您会发现Leaf非常易于学习和使用。首先,如果尚未使用,请使用Vapor工具箱生成一个新项目。接下来,我们需要将Leaf包作为依赖项添加到Package.swift文件中:
import PackageDescription
let package = Package(
name: "leafvapor",
platforms: [
.macOS(.v10_15)
],
dependencies: [
// 💧 A server-side Swift web framework.
.package(url: "https://github.com/vapor/vapor.git", from: "4.0.0"),
.package(url: "https://github.com/vapor/leaf.git", from: "4.0.0-rc")
],
targets: [
.target(
name: "App",
dependencies: [
.product(name: "Vapor", package: "vapor"),
.product(name: "Leaf", package: "leaf")
],
swiftSettings: [
// Enable better optimizations when building in Release configuration. Despite the use of
// the `.unsafeFlags` construct required by SwiftPM, this flag is recommended for Release
// builds. See <https://github.com/swift-server/guides#building-for-production> for details.
.unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
]
),
.target(name: "Run", dependencies: [.target(name: "App")]),
.testTarget(name: "AppTests", dependencies: [
.target(name: "App"),
.product(name: "XCTVapor", package: "vapor"),
])
]
)
现在,我们应该再次运行swift软件包更新命令,或者等到Xcode获取新的软件包依赖项。 该过程完成后,我们应该使用configure.swift文件中的以下行来配置Leaf:
import Vapor
import Leaf
// configures your application
public func configure(_ app: Application) throws {
// uncomment to serve files from /Public folder
app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
app.views.use(.leaf)
app.leaf.cache.isEnabled = app.environment.isRelease
// register routes
try routes(app)
}
configure方法的第一行启用了一个中间件,该中间件可以为名为Public的目录中的文件提供服务。 中间件基本上是一种功能,它将在每次请求处理程序之前执行。 因此,在我们的情况下,如果浏览器要求提供文件,例如样式表,脚本或图像,则FileMiddleware可以在公共目录中查找该文件。 如果文件存在,内容将作为响应返回。 这非常适合提供静态资产,但是请注意,配置目录中的所有内容都可以通过服务器公开获得,因此请不要在其中放置敏感数据。在下一行中,我们告诉我们的应用程序应使用Leaf模板引擎 呈现我们的观点。 模板文件默认位于Resources / Views目录下。 您也可以通过配置渲染器来更改此路径,但是现在我们可以。
最后,我们将更改Leaf的默认缓存行为。这对于调试和测试目的非常有用,因为如果没有高速缓存,如果您修改模板文件,则只需重新加载浏览器窗口即可立即查看更改。否则,如果启用了缓存,则必须重新启动整个Vapor应用程序服务器以反映更改。您应该知道存在三种类型的环境。在尝试编写应用程序代码时,开发环境很有用,因为在开发人员模式下运行时会打开许多调试功能。在发布应用程序时应使用生产环境,可以通过isRelease属性检查生产环境。在释放模式下,日志记录减少,调试和其他警告信息被禁用,因此您的服务器可以更快地响应传入的请求。第三个是测试,用于单元测试,您可以通过检测环境来设置伪造的服务和数据。仅需几行代码,即可使用Leaf。在项目文件夹中,创建一个新的Resources / Views目录和一个名为index.leaf的文件,其中包含以下内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"href="/css/frontend.css">
<title>#(title)</title>
</head>
<body>
<main>
<section class="wrapper">
<h1>#(body)</h1>
</section>
</main>
</body>
</html>
该文件是我们的索引HTML模板。 Leaf使您能够将特定标签放入HTML代码。 这些标记始终以#符号开头。 您可以将它们视为预处理器宏。 Leaf渲染器将处理模板文件,并用实际值替换#(variable)占位符以打印出来。Xcode无法为Leaf文件选择正确的语法突出显示,但是您可以为它们使用HTML语法着色。 只需单击Editor▸Syntax Coloring▸HTML菜单项。 不幸的是,如果关闭IDE,则必须为每个模板文件再次执行此操作。在项目目录中,创建一个包含frontend.css文件的Public / css文件夹结构。 CSS是描述HTML文档的视觉样式的样式表。 您可以使用W3Schools网站了解有关此格式的更多信息。 随便写一个样式作为实例。
* {margin: 0;padding: 0;}
body {font-family: -apple-system, system-ui, BlinkMacSystemFont, "Helvetica", "Segoe UI", Roboto, Ubuntu;font-size: 16px;line-height: 1.5em;}
屏幕的简易自适应(在上述代码下面继续写)
@media (max-width: 599px) {}
@media (min-width: 600px) {}
@media (min-width: 900px) {}
@media (min-width: 1200px) {}
@media (min-width: 1800px) {}
最后一步是稍微改变我们的路由器并返回渲染的视图。 Leaf只是Vapor框架的抽象View层的实现。 您可以使用req.view.render方法呈现任何内容。 这将使用先前配置的Leaf引擎读取模板文件,然后使用上下文对象对其进行呈现。 也可以创建自己的视图渲染引擎。言归正传,直接上代码(修改routes.swift文件)
import Vapor
func routes(_ app: Application) throws {
app.get { req -> EventLoopFuture<View> in
struct Context: Encodable {
let title: String
let body: String
}
let context = Context(title: "Juanshu - Leaf", body: "Hello Leaf")
return req.view.render("index", context)
}
app.get("hello") { req -> String in
return "Hello, world!"
}
}
好了我们来看一下最终成果