关于golang:Go-语言入门很简单nethttp-包

39次阅读

共计 4258 个字符,预计需要花费 11 分钟才能阅读完成。

引言

之前的文章学过把模板和视图拆散,建设一个 Web 服务器来展示 HTML 模板。咱们将学习如何应用 Go 的模板包创立动静 HTML 和文本文件。

建设 Web 服务器

到目前为止,咱们始终在向终端输入模板,然而当咱们开始深入研究更多 HTML 时,这开始变得不那么有意义了。相同,咱们心愿可视化在 Web 浏览器中生成的 HTML。为此,咱们首先须要设置一个 Web 服务器来出现咱们的 HTML 模板。

package main

import (
    "html/template"
    "net/http"
)

var testTemplate *template.Template

type ViewData struct {Name string}

func main() {

    var err error
    testTemplate, err = template.ParseFiles("hello.gohtml")
    if err != nil {panic(err)
    }

    http.HandleFunc("/", handler)
    http.ListenAndServe(":8000", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {w.Header().Set("Content-Type", "text/html")

    vd := ViewData{"Kyrie Jobs"}

    err := testTemplate.Execute(w, vd)
    if err != nil {http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

创立一个名为 hello.gohtml 的文件并将以下内容增加到其中:

<h1>Hello, {{.Name}}!</h1>

当初通过在终端中输出 go run main.go 来启动服务器。该程序应放弃运行并在端口 8000 上侦听 Web 申请,因而您能够在 localhost:8000 查看出现的 HTML。

if…else 块

咱们以后的模板很无聊,因为它只打印出一个人的名字。然而如果没有提供名字会产生什么?

让咱们试试看。关上你的 main.go 文件并删除你的 handler() 函数中创立 ViewData 实例的代码,而是向 testTemplate.Execute 办法提供 nil。实现后,您的 handler() 函数应如下所示:

func handler(w http.ResponseWriter, r *http.Request) {w.Header().Set("Content-Type", "text/html")

  err := testTemplate.Execute(w, nil)
  if err != nil {http.Error(w, err.Error(), http.StatusInternalServerError)
  }
}

当初重新启动您的服务器(或让新服务器重新启动)并在浏览器中拜访该页面 – localhost:8000。您应该看到一个看起来像这样的页面。

当咱们不提供名称时,模板将应用空字符串代替值出现。相同,咱们心愿咱们的页面显示一个更通用的字符串,例如“Hello, there!”。让咱们持续更新模板以应用咱们的第一个操作,即 if/else 块。像这样更新 hello.gohtml:

<h1>Hello, {{if .Name}} {{.Name}} {{else}} there {{end}}!</h1>

如果您在浏览器中查看该页面,您应该会看到这更新了您的模板以显示“Hello, there !”就像咱们想要的那样,但可怜的是,这在“there”这个词和感叹号之间减少了一个额定的空格。大多数时候这并不重要,然而在解决文本时,这有时会很烦人。在下一节中,咱们将看看两个选项来略微清理一下。

为了解脱额定的空白,咱们有几个抉择:

  1. 从咱们的模板中删除它们。
  2. 应用减号 (-) 通知模板包修剪多余的空白。

第一个选项非常简单。咱们只需将 hello.gohtml 文件更新为并删除多余的空格。

<h1>Hello, {{if .Name}}{{.Name}}{{else}}there{{end}}!</h1>

在这个例子中,这很好用,因为它是一段十分短的文本,然而设想一下咱们正在生成 python 代码,其中间距很重要 – 这很快就会变得十分烦人。侥幸的是,模板包还提供了一种应用减号来修剪不须要的空白的办法。

<h1>
  Hello,
  {{if .Name}}
    {{.Name}}
  {{- else}}
    there
  {{- end}}!
</h1>

在此代码片段中,咱们通过将减号字符放在 else 关键字的后面来通知模板包,咱们不心愿 Name 变量及其前面的任何内容之间的所有空格,并且咱们也对 end 执行雷同操作倒数第二行的关键字。从新加载您的页面,您应该会看到该空格不再存在。

对于本教程的其余部分,我将抉择应用此处的第一个示例作为我的 hello.html 文件。

范畴块

当初让咱们假如您想在您的网站上显示所有小部件以及它们的价格。这是动静 Web 应用程序的工作类型,因为没有人违心为您销售的每件商品手动创立 HTML 并保护它。相同,咱们心愿对每个我的项目应用雷同的 HTML。在 Go 中,您能够应用模板内的范畴块来实现此目标。

{{range .Widgets}}
  <div class="widget">
    <h3 class="name">{{.Name}}</h3>
    <span class="price">${{.Price}}</span>
  </div>
{{end}}

如果你重启你的服务器(或者让新的)并在 localhost:8000 从新加载页面,你当初应该会看到一个 HTML 页面,其中显示了三个小部件,每个小部件都有一个题目和一个价格。如果咱们在数组中增加更多小部件,咱们会在这里看到更多,如果咱们将其保留为空数组,咱们将不会在此处看到任何小部件。

range 操作混同的最常见起源是咱们正在拜访小部件的各个属性,而无需在 .Widgets 值内应用索引或任何其余拜访器。这是因为范畴操作会将汇合中每个对象的值设置为范畴块内的点 (.)。例如,如果您要在范畴块内渲染 {{.}},您将看到与在 Widget 对象上应用 fmt.Println() 雷同的输入。

嵌套模板

随着您的模板开始增长,您会很快发现您须要在不同的中央重用组件。这就是嵌套模板来援救这一天的中央。应用 Go 的模板包,您能够申明多个惟一命名的模板,而后当您须要在代码中应用另一个模板时,您只需应用 template 关键字援用它。例如,假如您想为您的网站申明一个页脚,您能够将其蕴含在多个页面和多个布局中。将以下页脚模板增加到 hello.html 文件中。你把它放在哪里并不重要,但我更喜爱把它放在文件的顶部。

{{define "footer"}}
  <footer>
    <p>
      Copyright 2016 Calhoun.io
    </p>
    <p>
      Contact information: <a href="mailto:jon@calhoun.io">jon@calhoun.io</a>.
    </p>
  </footer>
{{end}}

而后在小部件的范畴块之后插入以下行。

{{template "footer"}}

您的 hello.gohtml 文件应如下所示:

{{define "footer"}}
  <footer>
    <p>
      Copyright 2016 Calhoun.io
    </p>
    <p>
      Contact information: <a href="mailto:jon@calhoun.io">jon@calhoun.io</a>.
    </p>
  </footer>
{{end}}

{{range .Widgets}}
  <div class="widget">
    <h3 class="name">{{.Name}}</h3>
    <span class="price">${{.Price}}</span>
  </div>
{{end}}

{{template "footer"}}

当初,如果您查看 localhost:8000,您将看到该页面正在应用您定义的页脚模板。当您定义一个模板时,您能够在任何其余模板中应用它,甚至能够屡次应用它。尝试蕴含页脚模板两次以理解我的意思。

模板变量

咱们的上一个示例很棒,然而当您须要在嵌套模板中蕴含一些数据时会产生什么?侥幸的是,模板操作容许您传入第二个参数,该参数将调配给模板内的点 (.) 参数。例如,假如咱们想为小部件的名称题目局部编写模板,咱们能够应用以下代码来实现。

{{define "widget-header"}}
  <h3 class="name">{{.}}</h3>
{{end}}

{{range .Widgets}}
  <div class="widget">
    {{template "widget-header" .Name}}
    <span class="price">${{.Price}}</span>
  </div>
{{end}}

在这种状况下,.Name 属性被调配给 widget-header 模板内的点 (.) 属性。

带有模板变量的嵌套模板甚至容许您深刻多层,这意味着能够从模板外部调用模板。

{{define "widget"}}
  <div class="widget">
    {{template "widget-header" .Name}}
    <span class="price">${{.Price}}</span>
  </div>
{{end}}

{{define "widget-header"}}
  <h3 class="name">{{.}}</h3>
{{end}}

{{range .Widgets}}
  {{template "widget" .}}
{{end}}

这段代码的最终后果是雷同的,然而当初咱们有了一个小部件模板,咱们能够轻松地在 Web 应用程序的其余页面上重用它,而无需重写代码。

接下来

凭借您新学到的模板技能,您应该能够创立可重用的动静模板。在下一篇文章中,咱们将介绍如何应用内置的模板函数,如 andeqindex,而后咱们将看看如何增加咱们本人的自定义函数。我本来打算包含那些听到的,但这篇文章有很多要介绍的口头,我不想卖空任何一个。

在对于函数的帖子之后,咱们将介绍如何应用模板来创立 Web 应用程序的视图层。这将包含创立共享布局、定义能够被笼罩的默认模板,以及在不同页面中蕴含雷同的模板,而无需将所有代码放入单个文件中。

如果您感到雄心勃勃或好奇,您还能够查看 text/templatehtml/template 的模板文档。持续本人摸索其余一些常识~

正文完
 0