본문 바로가기

GO lang/Toy - booking

[GO] Booking - HTML rendering

HTML에서 중복되는 부분은 base.layout.tmpl 로 처리하고 페이지 재조립하는 방법에 대해서 알아보자.

 

프로젝트 기본 구조

 

 

main.go

 

package main

import (
	"GO/trevor/bookings-31/pkg/handlers"
	"fmt"
	"net/http"
)

const portNumber = ":3000"

// main is the main function
func main() {

	http.HandleFunc("/", handlers.Home)
	http.HandleFunc("/about", handlers.About)
	tmp := fmt.Sprintf("Staring application on port %s", portNumber)
	fmt.Println(tmp)
	_ = http.ListenAndServe(portNumber, nil)
}

 

handlers.go

 

package handlers

import (
	"GO/trevor/bookings-31/pkg/render"
	"net/http"
)

// Home is the handler for the home page
func Home(w http.ResponseWriter, r *http.Request) {
	render.RenderTemplate(w, "home.page.tmpl")
}

// About is the handler for the about page
func About(w http.ResponseWriter, r *http.Request) {
	render.RenderTemplate(w, "about.page.tmpl")
}

 

render.go

 

package render

import (
	"bytes"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"path/filepath"
)

var functions = template.FuncMap{}

// RenderTemplate renders a template
func RenderTemplate(w http.ResponseWriter, tmpl string) {

	tc, err := CreateTemplateCache()
	if err != nil {
		log.Fatal("RenderTemplate>", err)
	}

	// map에 원하는 페이지가 있는지 확인
	t, ok := tc[tmpl]
	if !ok {
		log.Fatal("Could not get template from template cache")
	}

	buf := new(bytes.Buffer) // buf 생성
	_ = t.Execute(buf, nil)  // 해당 페이지를 buf 에 저장
	_, err = buf.WriteTo(w)  // client 에게 전송
	if err != nil {
		fmt.Println("error writing template to browser", err)
	}

}

// CreateTemplateCache creates a template cache as a map, page + base
func CreateTemplateCache() (map[string]*template.Template, error) {

	myCache := map[string]*template.Template{}

	// 폴더이름+파일명 저장
	pages, err := filepath.Glob("./templates/*.page.tmpl")
	if err != nil {
		return myCache, err
	}

	for _, page := range pages {
		// 폴더정보를 제거하고 파일 이름만 저장
		name := filepath.Base(page)

		// 페이지 정보 로딩
		ts, err := template.New(name).Funcs(functions).ParseFiles(page)
		if err != nil {
			return myCache, err
		}

		layouts, err := filepath.Glob("./templates/*.layout.tmpl")
		if err != nil {
			return myCache, err
		}

		if len(layouts) > 0 {
			// 페이지 정보에 base 정보 결함.
			ts, err = ts.ParseGlob("./templates/*.layout.tmpl")
			if err != nil {
				return myCache, err
			}

		}
		myCache[name] = ts

	}

	return myCache, nil
}

 

base.layout.tmpl

 

{{define "base"}}  <<== 현재의 템플릿을 base 라고 명명함
    <!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>Document 000</title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
              integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l"
              crossorigin="anonymous">

        {{block "css" .}}  <<== css 를 추가할 위치, 없으면 스킵함

        {{end}}
    </head>
    <body>

    {{block "content" .}}  <<== content 를 추가할 위치, 없으면 스킵함

    {{end}}


    {{block "js" .}}  <<== js 를 추가할 위치, 없으면 스킵함

    {{end}}

    </body>
    </html>
{{end}}

 

home.page.tmpl

 

{{template "base" .}}  <<== base 로 정의된 페이지를 템플릿으로 사용

{{define "content"}}   <<== base 템플릿에서 conetnt 부분을 변경함
    <div class="container">
        <div class="row">
            <div class="col">
                <h1>This is the home page</h1>
                <p>This is some text</p>
            </div>
        </div>
    </div>
{{end}}

 

 

[github 소스코드]

 

 

'GO lang > Toy - booking' 카테고리의 다른 글

[GO] Booking - routing, middleware, session packages  (0) 2021.12.05