Template
- 표준 라이브러리 패키지
- text 템플릿
- HTML 템플릿
- text 템플릿이 수행하는 모든 역할과 HTML 페이지 상에서 활용할 수 있는 추가 기능 제공
- ex:) 보안 기능(웹 공격 및 크로스 사이트 스크립트 방어)
- HTTP
- 네트워크 전송과 같은 작업에 TCP 서버를 사용하는 프로토콜
Primitive Templating
- 문자열 병합하기
- 문자열 변수와 HTML 코드 병합(
+ name +
)
- Command line에 argument 넘겨주기
name := os.Args[1]
- 첫번째 인자는 실행한 프로그램의 경로
- 두번째 인자는 사용자 입력값
- 콘솔 창에서 파일 생성하기
go run 파일명 > 생성될 파일명
- ex:)
go run main.go > index.html
Package Text Template
- 파일 파싱(file parsing)
- 여러 파일을 프로그램으로 가져와 사용 가능
- 절차
- 추상화
- 텍스트를 별도의 파일로 내보내기
- 프로그램으로 가져와서 사용하기
.gohtml
- Go에서 관례적으로 사용하는 확장자
- 확장자 임의로 변경 가능
- 파일 제공 시, RESTful 방식을 사용하므로 확장자가 문제되지 않음
- 템플릿 포인터
- 모든 템플릿을 파싱하고 보관해주는 컨테이너
- 파일 파싱 시에 생성됨
- 파일 파싱하기
.ParseFiles
- 파일 파싱
- 다수의 문자열 인자(파일 명)를 가질 수 있다
- 인자로 넘긴 파일을 파싱하여 포인터와 에러를 반환한다
- 한번 포인터를 생성하면 컨테이너 역할을 한다
.ParseGlob
- 여러 파일 명을 나열하고 싶지 않을 때 사용
- 파일 경로를 인자로 넘긴다
- 특정 확장자를 가진 파일만 넘길 수도 있다(
*.gothml
)
.Execute
- 파일 실행
- 파싱한 내용을 실행할 수단(파일, 콘솔)과 data를 인자로 넘긴다
- writer 인터페이스를 생성한다
os.Stdout
을 넘기면 파싱한 내용을 화면에 출력한다
- 파일을 넘기면 파싱한 내용을 해당 파일에 작성한다
- 포인터에 다수의 템플릿이 있을 경우, 제일 먼저 들어간 템플릿을 실행한다
.ExecuteTemplate
- 특정 파일을 지정해서 실행할 수 있다
- 포인터에 여러 템플릿이 들어 있는 경우에는 이 메소드를 사용한다
Must
- 인자로
ParseGlob
의 결과를 넘길 수 있다
- ParseGlob이 반환하는 template pointer와 error에 대해 유효성 검사를 진행한다
- 데이터와 함께 파싱하기
.
- 실행 시점의 현재 데이터 값
ExecuteTemplate
으로부터 전달된 데이터
- html 파일 내에서는
{{.}}
과 같이 표기
- 데이터는 하나만 입력 가능
- 여러 데이터를 입력하려면 데이터 구조를 넘겨야 함
- 맵, 슬라이스, 구조체, ...
{{$변수명 := .}}
- 합성 데이터 구조와 함께 파싱하기
- 맵, 슬라이스, 구조체, ...
- range로 범위 지정
- range 옆의 점은 데이터 구조를, 그 아래의 점은 해당 데이터 구조의 요소를 의미
- 변수 사용 가능
- struct는 필드의 이름으로 필드에 접근
- struct와 slice를 동시에 사용할 때에는 어떤 필드에 어떻게 접근할지 아는 것이 중요
{{range .}}
<li>{{.}}</li>
{{end}}
{{range $index, $element := .}}
<li>{{$index}} - {{$element}}</li>
{{end}}
<-- access the field of struct -->
<li>{{.Name}} - {{.Color}}</li>
{{range .Food}}
<li>{{.Name}} - {{.Color}}</li>
{{end}}
- 익명 struct
- struct 익명 정의 가능
- 위 괄호에서 변수를 정의하고 아래 괄호에서 값을 할당한다
data := struct {
Food []fruit
Transport []car
}{
fruits,
cars,
}
- 템플릿에서 함수 사용하기
- 함수를 통해 템플릿에 들어있는 데이터 프로세싱
- map
FuncMap
- 텍스트 템플릿 패키지의 타입
- 키: 문자열
- 값: 빈 인터페이스(메서드가 없는 인터페이스)
- 템플릿 안에서 키를 통해 값으로 입력한 메소드 호출 가능
Funcs
FuncMap
을 취하는 메소드
- map 인자를 템플릿의 function map에 추가한다
- Funcs를 먼저 구한 다음, 파싱 진행
- 템플릿과 템플릿에 대한 포인터가 있어야 Parse 호출 가능
- Parse가 텍스트를 취하고 템플릿에 대한 포인터와 오류를 반환
New
- 템플릿에 대한 포인터가 없을 때에는
func New
사용하여 포인터 얻기
- 문자열만 분석 가능
var fm = template.FuncMap {
"uc": strings.ToUpper, // uc -> key
"ft": firstThree,
}
// 템플릿에서의 사용
{{range .Food}}
{{uc .Name}} // use key to access the function
{{end}}
- 템플릿에서 메소드 사용하기
- sturct로 정의된 메소드는 FuncMap 없이 템플릿에서 바로 사용 가능하다
{{.SomeProcessing}}
- 인자가 있는 메소드는 파이프라인을 통해 인자를 받을 수 있다
time
Now
Format
- time 값 서식화 하기
- 인자로 layout string을 받는다
- 특정 상수를 넘기면 정해진 format으로 서식화 가능
- 1부터 7까지 각 숫자에 대응하는 시간 입력 가능
01/02 03:04:05pm '06 -0700
t := time.Now()
fmt.Println(t) // 2022-10-31 23:00:00 ...
tf := t.Format(tiem.Kitchen)
fmt.Println(tf) // 11:00PM
tf := t.Format("01-02-2006")
fmt.Println(tf) // 11-10-2009
go fmt ./...
- 프로젝트 전반에 걸쳐 모든 코드를 서식화 하는 코드
- 파이프라인
- 연산 값의 결과를 넘겨서 다음 연산에 활용할 수 있도록 하는 기능
- 현재 데이터를 다음 함수의 인자로 사용할 수 있다
{{.}} // 3
{{. | fdbl}} // 3 * 2 = 6
{{. | fdbl | fsq}} // (3 * 2) ^ 2 = 36
{{/*(index .Food 3).Name*/}}
- 사전에 정의된 전역 함수
- function map으로 정의하지 않고 템플릿에서 바로 사용 가능
- index
- 인덱스를 통해 슬라이스의 값에 접근
{{index . 2}}
: 두번째 인덱스의 값 가져오기
- and
- and 연산
{{if and .Name .Admin}}
: 값이 있거나 true일 때 유효
- 비교 연산
- 두 인자의 크기 비교
if gt .Score1 .Score2
: Score1이 Score2보다 큰가?
eq
: arg1 == arg2
ne
: arg1 != arg2
lt
: arg1 < arg2
le
: arg1 <= arg2
gt
: arg1 > arg2
ge
: arg1 >= arg2
Nested Templates
- 중첩 템플릿
- 코드 모듈화를 위한 템플릿 중첩
- define keyword로 템플릿을 따로 정의한다
- 파일 이름이 아닌 고유 식별자 사용 가능
- end로 템플릿의 끝을 알린다
template 식별자
로 호출 가능
- 템플릿 내부에서
{{.}}
코드를 통해 현재 데이터 사용 가능
- 템플릿 호출 부분에서도
.
사용
{{template "polarbear" .}}
- 모듈화
- index.html에서 기능이 있는 다른 템플릿을 호출하여 사용
- svg(Scalable Vector Graphics)
- 2차원 벡터 그래픽을 서술하는 XML 기반의 마크업 언어
- btf(Below the Fold)
- 기본 창 크기에서 보이지 않는 화면
- 스크롤을 내려야 볼 수 있는 화면
Passing Data Into Templates & Composition
- 조합(composition)
- 상속이 아닌 임베딩(embedding)을 통해 조합 및 재사용이 가능한 구조체 생성 가능
- 인터페이스나 구조체 안에 타입 임베딩
- 내부 타입에서 선언된 메소드를 외부 타입으로 전달 가능
- 임베드 당시에는 외부 타입의 메소드가 되지만 실행 시의 메소드 리시버는 내부 타입이다
- 특정 구조체를 임베딩함으로써 해당 구조체의 메소드 사용 가능
package composition
...
type Person struct {
Name string
Age int
}
type Lisa struct {
Human
}
func (p *Person) Name() {
fmt.Printf("Hello, I'm %v.", h.Name)
}
import .../composition
func main() {
lisa := composition.Lisa{
Person : composition.Person{
Name: "Lisa",
Age: 22,
},
}
lisa.Name(); // "Hello! I'm Lisa."
}
HTML Template Package
- HTML 템플릿
- 텍스트 템플릿 위에 작성
- 텍스트 템플릿이 가진 모든 기능을 가짐
- 추가로 웹에서 작동하는 기능을 가짐
- HTML 문자를 escape 처리할 때 사용하는 모듈
- escaping
- HTML 템플릿 패키지의 특징 중 하나
- 웹상의 불안전한 문자 이스케이핑
- HTML 코드는 브라우저에 의해 해석되는 약속된 문자들
- HTML 문자를 이스케이프 처리하면 스크립트나 HTML 태그 기능만 사라질 뿐 내용은 그대로 브라우저에서 확인 가능
- 태그를 문자 그대로 출력하고 싶을 때 이스케이핑 활용
- ex:)
<
= <
/ >
= >
(화면에 표시되는 방식)
- HTML 문법에 맞는 코드가 아니므로 해석되지 않는다
- 문맥에 민감
- 템플릿에 입력한 데이터의 문맥에 따라 데이터 이스케이핑
- 크로스 사이트 스크립팅을 막음
- HTML 코드를 텍스트화 하여 악의적인 코드를 방지할 수 있다
- Cross-site scripting(XSS)
- web application의 취약점
- web site 관리자가 아닌 이가 web page에 악성 script를 삽입하는 것
- web application이 사용자로부터 입력 받은 값을 제대로 검사하지 않고 사용할 때 발생
- 사용자의 정보(쿠키, 세션)를 탈취하거나 자동으로 비정상적인 기능 수행을 유도할 수 있다
- 주로 다른 web site와 정보를 교환하는 식으로 작동하여 site 간 scrpiting이라고 한다