首页 iOS.& Swift Books 服务器端迅速与蒸气

15
美化页面 由Tim Condon撰写

笔记:此更新是开奖结果3d早期访问版本。本章尚未更新到蒸气4。

在上一章中,您开始构建开奖结果3d强大的动态网站,叶子。然而,网页只使用简单的HTML,并且没有风格 - 它们看起来不太好!在本章中,您将学习如何使用Bootstrap Framework将样式添加到您的页面。您还将了解如何嵌入模板,以便您只需在开奖结果3d地方进行更改。最后,您还将看到如何使用蒸气服务文件。

嵌入模板

目前,如果更改索引页面模板以添加样式,则只会影响该页面。您必须在首字母缩略词详细信息页面和任何其他未来页面中复制样式。

叶子允许您将模板嵌入到其他模板中。这使您可以创建开奖结果3d“基本”模板,其中包含对所有页面共用的代码并在您的网站上使用该代码。

资源/观点 创建开奖结果3d新文件, Base.Leaf。复制内容 index.leaf. 进入 Base.Leaf. Remove everything between the <body> and </body> tags. This remaining code looks similar to the following:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>#(title) | Acronyms</title>
</head>
<body>

</body>
</html>

This forms your base template and will be the same for all pages. Between the <body> and </body> tags add:

#get(content)

This uses Leaf’s #get() tag to retrieve the content variable. To create this variable, open index.leaf. 用以下内容替换其内容:

#set("content") {
  <h1>Acronyms</h1>

  #if(acronyms) {
    <table>
      <thead>
        <tr>
          <th>
            Short
          </th>
          <th>
            Long
          </th>
        </tr>
      </thead>
      <tbody>
        #for(acronym in acronyms) {
          <tr>
            <td>
              <a href="/acronyms/#(acronym.id)">
                #(acronym.short)
              </a>
            </td>
            <td>#(acronym.long)</td>
          </tr>
        }
      </tbody>
    </table>
  } else {
    <h2>There aren't any acronyms yet!</h2>
  }
}

所做的更改是:

  • 删除现在生活的HTML Base.Leaf.
  • Wrap the remaining HTML with Leaf’s #set() tag and call the created variable content. You 必须 wrap the variable name in #set() with quotations for Leaf to register it.

最后在底部 index.leaf. add:

#embed("base")

这嵌入了 Base.Leaf 模板进入页面并呈现它。这 Base.Leaf template uses #get() to get the content that’s set above. Save the files, then build and run. Open your browser and enter the URL http:// localhost:8080 /。页面呈现以前:

接下来,开放 缩写.Leaf 并将其更改为通过用以下内容替换其内容来使用基本模板:

#set("content") {
  <h1>#(acronym.short)</h1>
  <h2>#(acronym.long)</h2>

  <p>Created by #(user.name)</p>
}

#embed("base")

再次,所做的变化是:

  • 删除现在在基本模板中生存的所有HTML。
  • Store the remaining HTML in the content variable, using Leaf’s #set() tag.
  • Embed the base template to bring in the common code and render content.

保存文件,并在浏览器中导航到首字母缩写页面。页面呈现新的基本模板:

笔记:在调试模式下,您可以刷新页面以拾取叶片更改。在释放模式下,叶子缓存了性能的页面,因此您必须重新启动应用程序以查看更改。

引导

引导是开奖结果3d开源,最初由Twitter构建的网站的前端框架。它提供了您添加到网页的易于使用的组件。它是开奖结果3d移动式第一库,并使构建适用于所有尺寸的屏幕的网站。

<div class="container mt-3">
  #get(content)
</div>

导航

TIL网站目前由两页组成:主页和首字母缩略词。随着越来越多的页面添加,可能会在网站上找到自己的方式。目前,如果您转到Acronym的详细信息页面,则没有简单的方法可以返回主页!向网站添加导航使该网站更友好的用户。

#// 1
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
  #// 2
  <a class="navbar-brand" href="/">TIL</a>
  #// 3
  <button class="navbar-toggler" type="button"
   data-toggle="collapse" data-target="#navbarSupportedContent"
   aria-controls="navbarSupportedContent" aria-expanded="false"
   aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  #// 4
  <div class="collapse navbar-collapse"
   id="navbarSupportedContent">
    #// 5
    <ul class="navbar-nav mr-auto">
      #// 6
      <li class="nav-item #if(title== "首页 page"){active}">
        <a href="/" class="nav-link">Home</a>
      </li>
    </ul>
  </div>
</nav>

桌子

引导提供了易于轻松的样式表的类。打开 index.leaf. and replace the <table> tag with the following:

<table class="table table-bordered table-hover">
<thead class="thead-light">

服务文件

Almost every website needs to be able to host static files, such as images or stylesheets. Most of the time, you’ll do this using a CDN (Content Delivery Network) or a server such as Nginx or Apache. However, Vapor provides a FileMiddleware to serve files.

middlewares.use(FileMiddleware.self)
<img src="/images/logo.png"
 class="mx-auto d-block" alt="直到徽标" />

用户

该网站现在有开奖结果3d页面,显示显示缩略语的所有首字母缩略词和页面。接下来,您将添加页面以查看所有用户和特定用户的信息。

#// 1
#set("content") {
  #// 2
  <h1>#(user.name)</h1>
  #// 3
  <h2>#(user.username)</h2>

  #// 4
  #if(count(acronyms) > 0) {
    <table class="table table-bordered table-hover">
      <thead class="thead-light">
        <tr>
          <th>
            Short
          </th>
          <th>
            Long
          </th>
        </tr>
      </thead>
      <tbody>
        #// 5
        #for(acronym in acronyms) {
          <tr>
            <td>
              <a href="/acronyms/#(acronym.id)">
                #(acronym.short)</a>
            </td>
            <td>#(acronym.long)</td>
          </tr>
        }
      </tbody>
    </table>
  } else {
    <h2>There aren't any acronyms yet!</h2>
  }
}

#// 6
#embed("base")
struct UserContext: Encodable {
  let title: String
  let user: User
  let acronyms: [Acronym]
}
// 1
func userHandler(_ req: Request) throws -> Future<View> {
  // 2
  return try req.parameters.next(User.self)
    .flatMap(to: View.self) { user in
      // 3
      return try user.acronyms
        .query(on: req)
        .all()
        .flatMap(to: View.self) { acronyms in
          // 4
          let context = UserContext(
            title: user.name,
            user: user,
            acronyms: acronyms)
          return try req.view().render("user", context)
     }
  }
}
router.get("users", User.parameter, use: userHandler)
<p>Created by <a href="/users/#(user.id)/">#(user.name)</a></p>

#// 1
#set("content") {

  #// 2
  <h1>All Users</h1>

  #// 3
  #if(count(users) > 0) {
    <table class="table table-bordered table-hover">
      <thead class="thead-light">
        <tr>
          <th>
            Username
          </th>
          <th>
            Name
          </th>
        </tr>
      </thead>
      <tbody>
        #for(user in users) {
          <tr>
            <td>
              <a href="/users/#(user.id)">
                #(user.username)
              </a>
            </td>
            <td>#(user.name)</td>
          </tr>
        }
      </tbody>
    </table>
  } else {
    <h2>There aren't any users yet!</h2>
  }
}

#embed("base")
struct AllUsersContext: Encodable {
  let title: String
  let users: [User]
}
// 1
func allUsersHandler(_ req: Request) throws -> Future<View> {
  // 2
  return User.query(on: req)
    .all()
    .flatMap(to: View.self) { users in
      // 3
      let context = AllUsersContext(
        title: "All Users",
        users: users)
      return try req.view().render("allUsers", context)
  }
}
router.get("users", use: allUsersHandler)
<li class="nav-item #if(title== "All Users"){active}">
  <a href="/users" class="nav-link">All Users</a>
</li>

共享模板

本章的最后一件事是重构我们的首字母缩略词表。目前索引页面和用户的信息页面都使用首字母缩略词表。但是,您已将代码重复为表格。如果要对首字母缩略词表进行更改,则必须在两个地方进行更改。这是开奖结果3d问题模板应该解决!

#if(count(acronyms) > 0) {
  <table class="table table-bordered table-hover">
    <thead class="thead-light">
      <tr>
        <th>Short</th>
        <th>Long</th>
      </tr>
    </thead>
    <tbody>
      #for(acronym in acronyms) {
        <tr>
          <td>
            <a href="/acronyms/#(acronym.id)">
              #(acronym.short)
            </a>
          </td>
          <td>#(acronym.long)</td>
        </tr>
      }
    </tbody>
  </table>
} else {
  <h2>There aren’t any acronyms yet!</h2>
}
#embed("acronymsTable")
#embed("acronymsTable")
let acronyms: [Acronym]
let context = IndexContext(title: "首页 page", acronyms: acronyms)

然后去哪儿?

现在您已完成本章,TIL应用程序的网站看起来更好!使用Bootstrap Framework允许您轻松拟合网站。这对访问您的申请的用户来说是更好的印象。

有开奖结果3d技术问题?想报告开奖结果3d错误吗? 您可以向官方书籍论坛中的书籍作者提出问题和报告错误 这里.

有反馈分享在线阅读体验吗? 如果您有关于UI,UX,突出显示或我们在线阅读器的其他功能的反馈,您可以将其发送到设计团队,其中表格如下所示:

© 2021 Razeware LLC

您可以免费读取,本章的部分显示为 混淆了 文本。解锁这本书,以及我们整个书籍和视频目录,带有Raywenderlich.com的专业订阅。

现在解锁

要突出或记笔记,您需要在订阅中拥有这本书或自行购买。