본문 바로가기

Language/Go

[Go] - web programming : 액션

액션

 

- Go 템플릿 내부의 삽입된 명령어. 이중 중괄호 내에 위치

- 아래와 같은 action의 사항을 공부해보자.

  1. 조건부 액션 - conditional actions

  2. 반복자 액션 - interator actions

  3. 집합 액션 - set actions

  4. 액션 포함 - include actions

 

1. conditional actions

- 인자로 들어온 값을 평가해 여러 데이터중 하나를 선택

- 아래와 같은 형태를 html에 쓰자

{{ if args }}

content1

{{ else }}

content1

{{ end }}

- args는 어떤 액션을 취할지에 대한 인자(인자에 대해서는 추후에..)

 

example - 랜덤 난수를 생성하고 5보다 큰지 작은지 확인 

 

 main.go - math/rand 패키지속 rand를 사용하여 랜덤 난수 생성

package main

import (
	"html/template"
	"net/http"
	"math/rand"
	"time"
)

func process(w http.ResponseWriter, r *http.Request) {
	t, _ := template.ParseFiles("index.html")
	rand.Seed(time.Now().Unix())
	t.Execute(w, rand.Intn(10) > 5)
}

func main() {
	server := http.Server {
		Addr: "127.0.0.1:8080",
	}
	http.HandleFunc("/process", process)
	server.ListenAndServe()
}

 index.html - html에 조건 액션을 작성

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Go Web Programming</title>
</head>
<body>
{{if .}}
    Number is greater than 5!
{{else}}
    Number is 5 or less!
{{end}}
</body>
</html>

 

2. iterator actions

- array, slice, map 또는 channel에 대해 iterate

- 반복문 내에서 점(.)은 iteratable의 요소를 받아 값으로 설정

- 아래와 같은 형태

 {{ range array }}

    test {{ . }}

 {{ end }}

 

example - 월화수목금 출력

 

 

main.go - handler function

func process(w http.ResponseWriter, r *http.Request) {
	t, _ := template.ParseFiles("index.html")
	daysOfWeek := []string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}
	t.Execute(w, daysOfWeek)
}

 

index.html - iterator action 예제

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Go Web Programming</title>
</head>
<body>
    <ul>
        {{range array}}
            <li>{{ . }}</li>
        {{end}}
    </ul>
</body>
</html>

 

표시할 값이 없을 때, {{else}}를 추가하여 처리할 수 있다.

    <ul>
        {{range .}}
            <li>{{ . }}</li>
        {{else}}
        	<li>Noting to show</li>
        {{end}}
    </ul>

 

3. set actions

- 닫기 영역 내에 위치한 점(.)에 값을 설정

- 아래와 같이 동작

{{ with arg }}

   내부 점(.)을 arg로 가리킴  

{{ end }}

 

example - 3개의 점(.) 위치의 값의 변화를 보자

 

main.go - 점(.)에 Hello 값을 전달

package main

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

func process(w http.ResponseWriter, r *http.Request) {
	t, _ := template.ParseFiles("index.html")
	t.Execute(w, "Hello")
}

func main() {
	server := http.Server {
		Addr: "127.0.0.1:8080",
	}
	http.HandleFunc("/process", process)
	server.ListenAndServe()
}

 

index.html -  중간의 div내에만 with로 점(.)의 값을 world로 전달한다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Go Web Programming</title>
</head>
<body>
<div>The dot is {{.}}</div>
<div>
    {{with "world"}}
        Now the dot is set to {{.}}
    {{end}}
</div>
<div>The dot is {{.}} again</div>

</body>
</html>

2번쨰 점(.) 위치에만 world가 할당되었다.

 

 

4. include actions

- 템플릿에 액션을 포함할 수 있다. 하나의 템플릿 내에 또다른 템플릿을 포함할 수 있다.

- 중첩 템플릿이라 하며, 아래와 같이 사용한다.

{{ template "name"}} -> "name"은 포함할 템플릿의 이름

 

example - 중첩 템플릿 만들기

 

main.go - ParseFiles에 2개의 template을 인자로 넘긴다.

package main

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

func process(w http.ResponseWriter, r *http.Request) {
	t, _ := template.ParseFiles("index.html", "include.html")
	t.Execute(w, "Hello World!")
}

func main() {
	server := http.Server {
		Addr: "127.0.0.1:8080",
	}
	http.HandleFunc("/process", process)
	server.ListenAndServe()
}

 

index.html - 중첩 template을 포함시킬 action을 추가 한다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Go Web Programming</title>
</head>
<body>
    <div>This is index.html before</div>
    <div>This is the value of the dot in t1.html -- [{{.}}]</div>
    <hr/>
    {{template "include.html"}}
    <hr/>
    <div>This is include.html after</div>
</body>
</html>

include.html - html 스니펫으로 작성한다.

<div style="background-color: yellow;">
    This is include.html<br/>
    This is the value of dot in include.html - [{{.}}]
</div>

 

중첩된 include.template에는 점(.)에 값이 전달이 안된 것을 확인할 수 있다.

 

 

인자, 변수, 파이프라인

 

1. 인자(argument)

- 템플릿에서 사용하지 않으며 인자는 Boolean, interger, string과 기타형 뿐만 아니라 struct, struct의 필드, arry, function 형태를 가질 수 있다. 인자는 변수로 템플릿에 점(.)으로 나타내고 그 값은 템플릿 엔진에 전달된다.

 

2. 변수(variable)

- $로 시작되는 단어

example - 점(.) 에 map을 고려해 $key, $value로 초기화 하여 iterate

{{ range $key, $value := . }}
 key is {{ $key }}, value is {{ $value }}.
{{ end }}

 

3. 파이프라인(pipline)

- 인자, 함수, 메소드가 연결된 형태로 유닉스 파이프라인이 동작

example - 소수 2번째 자리수 까지 출력

{{ 12.3456 | printf "%.2f" }}

 

함수

 

- 인자로 Go 함수를 받을 수 있다.

- 매개변수가 1개만 취할 수 있다. (but 예외로 두 번째 값이 에러일 경우 두 번째 값만 허용)

- 커스텀 함수를 정의하기위해서는

1. FuncMap을 생성해 함수의 이름을 키, 실제 함수를 값으로 설정

2. FuncMap을 템플릿에 추가

 

example - 현재 시간을 받고, layout 형태로 출력

 

main.go - formatData 함수를 FuncMap을 통해 fdate라는 key로 넘겨준다.

package main

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

func formatData(t time.Time) string {
	layout := "2006/01/02"
	return t.Format(layout)
}

func process(w http.ResponseWriter, r *http.Request) {
	funcMap := template.FuncMap{"fdate": formatData}
	t := template.New("index.html").Funcs(funcMap)
	t, _ = t.ParseFiles("index.html")
	t.Execute(w, time.Now())
}

func main() {
	server := http.Server{
		Addr : "127.0.0.1:8080",
	}
	http.HandleFunc("/process", process)
	server.ListenAndServe()
}

 

index.html - 인자를 받고, 그 인자를 fdate로 처리한다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Go Web Programming</title>
</head>
<body>
    <div>The data/time is {{ . | fdate }}</div>
</body>
</html>

 

해당 형태로 시간이 출력된다.