상세 컨텐츠

본문 제목

[Nomad Coin] Explorer - #5.3 Using Partials

Go/Blockchain

by Gopythor 2022. 7. 18. 00:02

본문

728x90
반응형

#5.3 Using Partials

  • 분할 정복을 해야한다.
    <header>
        <nav>
            <a href="/"><h1>노마드 코인</h1></a>
            <ul>
                <li>
                    <a href="/">Home</a>
                </li>
                <li>
                    <a href="/add">Add</a>
                </li>
            </ul>
        </nav>
        <h1>{{.PageTitle}}</h1>
    </header>
  • route를 상기와 같이 변경했다.
  • header와 navigation을 만들었고 ul도 넣고 h1으로 끝냈다.
  • mvp.css를 사용하기 때문에 기본 tag만 써도 더 예쁘게 꾸며진다.

  • header나 Block을 재사용하고 싶다.
  • 아니면 나중에 footer를 재사용 할 수도 있다.
    <main>
        {{range .Blocks}} 
        <section>
         <ul>
          <li>{{.Data}}</li>
          <li>{{.Hash}}</li>
          {{if .PrevHash}}
            <li>{{.PrevHash}}</li>
          {{end}}
         </ul>
        </section>
         {{end}}
    </main>
  • prevHash가 없는 li들은 표시되지 않도록 할 것이다. prevHash가 있을 때에만 보이게 할 것이다.
{{define "head"}}
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://unpkg.com/mvp.css">
    <title>노마드 코인</title>
</head>
{{end}}
  • 재사용하고 싶은 모든 것들을 한번 잘라내보자
  • partials의 head.gohtml에 먼저 {{define "head"}}라고 쓰고 head를 붙여넣은 다음 {{end}}를 써준다.
{{define "header"}}
 <header>
        <nav>
            <a href="/"><h1>노마드 코인</h1></a>
            <ul>
                <li>
                    <a href="/">Home</a>
                </li>
                <li>
                    <a href="/add">Add</a>
                </li>
            </ul>
        </nav>
    <h1>{{.PageTitle}}</h1>
</header>
{{end}}
  • {{define "header"}}를 쓰고 header를 붙여 넣고 {{end}}을 잊지말고 써준다.
{{define "footer"}}
<footer>&copy; 2022</footer>
{{end}}
  • footer에서도 똑같이 한다. {{define "footer"}}
  • ⓒ2022라고 적는다.
  • {{end}}잊지말아야 한다.
{{define "block"}}
<div>
    <ul>
        <li>{{.Data}}</li>
        <li>{{.Hash}}</li>
        {{if .PrevHash}}
            <li>{{.PrevHash}}</li>
        {{end}}
         </ul>
        </div>
    <hr />
{{end}}
  • 이제 Block을 어떻게 재사용하는지 알아보자.
  • 필요한 경우를 대비하자.
  • block.gohtml을 만들고 {{define "block"}}을 쓰고 붙여넣기 하고 {{end}}를 작성한다.
  • 당장 제대로 동작은 하지 않는다.
  • 재사용될 조각들을 include해야 한다.
  • 지금은 전혀 load되고 있지 않다.
<!DOCTYPE html>
<html lang="en">
    {{template "head"}}
<body>
    {{template "header"}}
    <main>
        {{range .Blocks}} 
            {{template "block"}}
        {{end}}
    </main>
    {{template "footer"}}
</body>
</html>
  • 재사용할 조각들을 include하기 위해서는 home.gohtml에 {{template}}라고 쓰기만 하면 된다.
  • head라는 template이라면 {{template "head"}}라고 쓴다.
  • header template를 불러온다.
  • block template를 불러온다.
  • footer template를 불러온다.
{{define "home"}}
<!DOCTYPE html>
<html lang="en">
    {{template "head"}}
<body>
    {{template "header"}}
    <main>
        {{range .Blocks}} 
            {{template "block"}}
        {{end}}
    </main>
    {{template "footer"}}
</body>
</html>
{{end}}
  • 그리고 이제 이것 또한 하나의 template로 만들 것이다. 
  • {{define "home"}}이라고 쓴다. 그리고 {{end}}까지
{{define "add"}}
<!DOCTYPE html>
<html lang="en">
    {{template "head"}}
<body>
    {{template "header"}}
    <main>
        <form>
            <input type="text" placeholder="Data for your block" required />
        </form>
    </main>
    {{template "footer"}}
</body>
</html>
{{end}}
  • Add페이지에 대해서도 똑같이 해볼 것이다. 
  • {{define "add"}}라고 쓴다.
  • Add는 Block이 필요없고 대신 form이 필요하다.
  • placeholder는 user가 뭘 써야할지 알려주는 기능이다.
  • "Data for your block"이라고 하자.
  • required까지 써주면 끝이다.
  • 이게 나중에 보게 될 Add 페이지가 된 것이다.
  • 보이는 것 처럼 template를 define했다.
  • 이 변화들에 대해 Go가 어떻게 반응할 것인가?
  • 아직 이 template들을 load하지 않았다.
  • 그저 home.gohtml을 template로 load 한것이다.
  • main.go를 실행하면 아무것도 없다. 아무것도 렌더링 되지 않는다.

 

  • https://pkg.go.dev/text/template
  • template package가 있다.
  • 'text/template'는 HTML template가 구현하는 package이다.
  • 예를 들면 comment가 있고, if나 range, range가 비었을 때 실행될 else 등 유용하다.
  • 위의 사이트의 documentation을 참조하라.
  • function이 호출되기 전에 파일을 parsing하는 대신 template들을 load해보자.
  • home 페이지로 오기도 전에 template는 이미 load가 끝나있을 것이다.
  • templates라 함은 partials랑 pages이다.
  • 일일이 각 template를 load하지는 않을 것이다.
  • home function이 호출될 때마다 home template을 parsing할 것이다.
  • 그리고 main에 load 시킬 것이다.
var templates *template.Template
  • 이를 위해서 variable 하나 생성할건데, 전체 template들을 관리할 것이다.
  • template Object 하나에 모든 template들을 load할 것이다.
  • 파일로써가 아니라 define한 이름을 통해서 접근한다.
  • "home"이라는 이름은 home template을 보여준다.
  • var templates라고 해야하는데 template는 이미 import되어있다(html/template).
  • type은 *template.Template이다. template Object같은 것이다.
const (
	port        string = ":4000"
	templateDir string = "templates/"
)
  • 그 전에 const 두 개를 만든다.
  • 하나는 port 나머지 하나는 string인 templateDir이다. 그 템플릿 경로는 "templates/"가 된다.
func main() {
	templates = template.Must(template.ParseGlob(templateDir + "pages/*.gohtml"))
	http.HandleFunc("/", home)
	fmt.Printf("Listening on http://localhost%s\n", port)
	log.Fatal(http.ListenAndServe(port, nil))
}
  • 파일을 function안에서 load하고 parsing하는 대신에 route안에서 호출될 것이다.
  • templates를 초기화 시킬 것이다. pages에 있는 모든 파일들을 load한 결과물로 말이다.
  • pages폴더, add 와 home.
  • 오래 걸리니 파일명을 전달해서 구현하진 않는다. 대신 pattern을 사용한다.
  • template.Must()를 쓰고 template.parseGlob()
  • 이름을 넘기는게 아니라 pattern을 쓴다.
  • templateDir내부에 pages 폴더 안에서 .gothml로 끝나는 모든 파일을 가져오도록 한다.
  • 여전히 partials을 load하진 않았다.
  • 그 이유는 "**/*.gohtml"은 Go에서 지원되지 않는다.
  • 모든 폴더의 모든 파일에 접근할 수는 없다.
  • templates variable은 이제 모든 load된 template들을 가지고 있다.
  • 해야할 건 variable을 업데이트해주는 것이다.
	templates = template.Must(template.ParseGlob(templateDir + "pages/*.gohtml"))
	templates = template.Must(templates.ParseGlob())
  • 이번엔 templates.ParseGlob()를 써서 말이다.
  • 첫 번째 줄에서 template를 썼다. standard library에 있는 template이다.
  • 첫 번째 line이 실행되고 나면 이제 templates variable은 template Object이다.
  • template object는 다른 templates을 load할 수 있다.
	templates = template.Must(template.ParseGlob(templateDir + "pages/*.gohtml"))
	templates = template.Must(templates.ParseGlob(templateDir + "partials/*.gohtml"))
  • partials 폴더 내부에 있는 확장자가 gohtml인 모든 파일을 load하도록 하는 것이다.

 

  • variable을 만들었다. initialize하진 않았지만 type은 지정했다.
  • 그리고 main에서 initialize했고 variable을 update했다. 새로 생성한 것이 아니다.
  • templates을 load했고, 이제 templates는 template object가 됐다.
  • template object가 partials까지 load하게 했다.
  • 모든 page와 paritials를 load 하고 있는 template object를 가지고 있다.
func home(rw http.ResponseWriter, r *http.Request) {
	data := homeData{"Home", blockchain.GetBlockchain().AllBlocks()}
	templates.ExecuteTemplate(rw, "home", data)
}
  •  home을 정리해준다. 이젠 templates Object를 사용한다.
  • templates.ExecuteTemplate()
  • argument는 Writer이고 두번째는 template의 이름이다.
  • 그리고 data를 넘겨주면 된다.

 

  • 어느 정도 동작을 한다.
  • template home을 렌더링하고 있다.
  • footer가 있어서 Add로 갈 수 있다.
  • 문제는 variable들이 어디로 갔는가

 

출처 : 노마드코더 노마드코인

 

728x90
반응형

관련글 더보기

댓글 영역