больше статейСумасшедшая точка ->ISLAND
Предыдущее исследование уже имело предварительное представление и понимание Джина.router
Простое использование Gin также было освоено, поэтому сегодня мы будем использовать Gin для рендеринга нашегоhtml
страница.
Добавить шаблон
Мы все еще вносим изменения в проект из предыдущей главы.
Сначала создайте новыйtemplates
Папка, используемая для хранения наших файлов шаблонов, вновь созданных в папкеindex.tmpl
. И пишем наш шаблон.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Gin Hello</title>
</head>
<body>
<main>{{ .title }}</main>
</body>
</html>
намекатьВ GoLand пока нет подсветки синтаксиса для tmpl, мы можем добавить файл суффикса .tmpl в шаблон шаблона go. Методы, как показано ниже:File-settings-Editor-File Types
. (Или мы можем напрямую использовать *.gohtml в качестве шаблона), как показано на рисунке:
мы можем пройтиLoadHTMLGlob
иLoadHTMLFiles
Два способа загрузить наш шаблон. вLoadHTMLGlob
метод может загружать все шаблоны в каталоге иLoadHTMLFiles
Будет загружен только один файл, и его параметры являются параметрами переменной длины, и нам нужно вручную заполнить файлы шаблона один за другим. Здесь мы используемLoadHTMLGlob
метод.
router.LoadHTMLGlob("templates/*")
На этом этапе нам нужно изменить наш/
Маршрутизация вместо того, чтобы возвращать строку, возвращает шаблон нашей страницы.
существуетhandler
Китайско-СингапурскийindexHandler.go
, используемый для обработки нашего/
маршрутизация.
func Index(context *gin.Context) {
context.HTML(http.StatusOK, "index.tmpl", gin.H{
"title": "hello gin " + strings.ToLower(context.Request.Method) + " method",
})
}
В настоящее время при посещении нашей страницы по-прежнемуhello gin get method
, но это отличается от строки, которую мы вернули ранее.
Открытым浏览器-Network
Вы можете увидеть разницу между этими двумя страницами, одна из нихtextодинhtml
После написания конкретных функций нам нужно преобразовать наши модульные тесты, так как исходные модульные тесты для новой логики интерфейса больше не применимы.
Переработаны модульные тесты.
func TestIndexHtml(t *testing.T) {
router := initRouter.SetupRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, "/", nil)
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
}
При выполнении модульного тестирования я обнаружил, что сообщалось об ошибке, и причина ошибки заключалась в том, что ее не удалось найти.html
.
--- FAIL: TestIndexGetRouter (0.00s)
panic: html/template: pattern matches no files: `templates/*` [recovered]
panic: html/template: pattern matches no files: `templates/*`
В этот момент я чувствую себя очень странно, почему веб-страница доступна очень хорошо, но недоступна в тесте?
Я проверил много информации и не смог найти причину.Многие решения заключаются в том, чтобыtemplates
Написанный как полный путь, это явно не очень хорошее решение. Официальное введение в модульное тестирование оставляет желать лучшего.
Здесь я представляю метод:
Нам нужно изменить метод, оценивая различные режимы (debug
,release
,test
) для загрузки файлов по разным путямtemplates
.
initRouter.go
// 省略部分代码
if mode := gin.Mode(); mode == gin.TestMode {
router.LoadHTMLGlob("./../templates/*")
} else {
router.LoadHTMLGlob("templates/*")
}
При этом необходимо модифицироватьtest
, мы будем писатьinit
метод, здесьinit
метод подобенjava
серединаJunit
середина@Before
package test
import (
"GinHello/initRouter"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)
var router *gin.Engine
func init() {
gin.SetMode(gin.TestMode)
router = initRouter.SetupRouter()
}
func TestIndexHtml(t *testing.T) {
w := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, "/", nil)
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
assert.Contains(t,w.Body.String(),"hello gin get method","返回的HTML页面中应该包含 hello gin get method")
}
Это завершает модульные тесты и облегчает будущие функциональные изменения.
Добавьте статические ресурсы
Когда веб-страница может отображаться нормально, мы можем добавить некоторые статические ресурсы, чтобы сделать нашу страницу более красивой. я выбрал здесьBootstrap 4
Как фреймворк пользовательского интерфейса.Bootstrap 4 скачать
также представитьJqueryиPopper.
мы создаем новыйstatics
папка, мы будемBootstrap
распаковать, будетjs
иcss
скопировать вstatics
Под содержанием.
в нашемinitRouter
, добавьте статические ресурсы.
router.Static("/statics","./statics")
новыйheader.tmpl
{{ define "header" }}
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Gin Hello</a>
<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>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">主页 <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">文章列表</a>
</li>
<li class="nav-item">
<a class="nav-link " href="#" tabindex="-1" aria-disabled="true">关于</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">搜索</button>
</form>
<ul class="navbar-nav ">
<li class="nav-item">
<a class="nav-link" href="#">登录</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">注册</a>
</li>
</ul>
</div>
</nav>
{{end}}
и в нашемindex.tmpl
добавить
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/statics/css/bootstrap.min.css">
<link rel="stylesheet" href="/statics/css/bootstrap-grid.min.css">
<link rel="stylesheet" href="/statics/css/bootstrap-reboot.min.css">
<script src="/statics/js/jquery.min.js" rel="script"></script>
<script src="/statics/js/Popper.js" rel="script"></script>
<script rel="script" src="/statics/js/bootstrap.bundle.js"></script>
<title>Gin Hello</title>
</head>
<body>
<header>
{{template "header"}}
</header>
<main>
{{ .title }}
</main>
</body>
В этот момент запустите наш веб-сайт, и появится следующий стиль.
Добавить фавикон
Все готово, я должен только одинicon
.
В настоящее время на веб-сайте по-прежнему отсутствует значок веб-сайта, и значок веб-сайта также устанавливается функцией, заданной Джином. мы будем.ico
Образ помещается в корневой каталог проекта, а затем вinitRouter
в настройках.
router.StaticFile("/favicon.ico","./favicon.ico")
Запустите наш веб-сайт еще раз, и вы обнаружите, что значок набора появляется в верхнем левом углу веб-сайта.