جاسازی قالبهای HTML
بعد بیایید برنامه خود را بهروزرسانی کنیم تا cache template از فایلهای template HTML جاسازی شده استفاده کند، به جای خواندن آنها از هارد دیسک در زمان اجرا.
به فایل ui/efs.go برگردید و آن را بهروزرسانی کنید تا ui.Files محتویات دایرکتوری ui/html (که شامل templateهای ما است) را نیز جاسازی کند. به این صورت:
package ui import ( "embed" ) //go:embed "html" "static" var Files embed.FS
سپس باید تابع newTemplateCache() در cmd/web/templates.go را بهروزرسانی کنیم تا templateها را از ui.Files بخواند. برای انجام این کار، باید از چند ویژگی خاص که Go برای کار با سیستمهای فایل جاسازی شده دارد استفاده کنیم:
- تابع
fs.Glob()یک slice از مسیرهای فایل مطابق با الگوی glob برمیگرداند. این اساساً همان تابعfilepath.Glob()است که قبلاً در کتاب استفاده کردیم، با این تفاوت که روی سیستمهای فایل جاسازی شده کار میکند. - متد
Template.ParseFS()میتواند برای تجزیه templateهای HTML از یک سیستم فایل جاسازی شده به یک مجموعه template استفاده شود. این اساساً جایگزینی برای هر دو متدTemplate.ParseFiles()وTemplate.ParseGlob()است که قبلاً استفاده کردیم.Template.ParseFS()همچنین یک تابع variadic است که به شما امکان میدهد چندین template را در یک فراخوانی بهParseFS()تجزیه کنید.
بیایید اینها را در فایل cmd/web/templates.go خود استفاده کنیم:
package main import ( "html/template" "io/fs" // New import "path/filepath" "time" "snippetbox.alexedwards.net/internal/models" "snippetbox.alexedwards.net/ui" // New import ) ... func newTemplateCache() (map[string]*template.Template, error) { cache := map[string]*template.Template{} // Use fs.Glob() to get a slice of all filepaths in the ui.Files embedded // filesystem which match the pattern 'html/pages/*.tmpl'. This essentially // gives us a slice of all the 'page' templates for the application, just // like before. pages, err := fs.Glob(ui.Files, "html/pages/*.tmpl") if err != nil { return nil, err } for _, page := range pages { name := filepath.Base(page) // Create a slice containing the filepath patterns for the templates we // want to parse. patterns := []string{ "html/base.tmpl", "html/partials/*.tmpl", page, } // Use ParseFS() instead of ParseFiles() to parse the template files // from the ui.Files embedded filesystem. ts, err := template.New(name).Funcs(functions).ParseFS(ui.Files, patterns...) if err != nil { return nil, err } cache[name] = ts } return cache, nil }
حالا که این کار انجام شد، وقتی برنامه ما به یک باینری ساخته میشود، شامل تمام فایلهای UI مورد نیاز برای اجرا خواهد بود.
میتوانید این را به سرعت با ساخت یک باینری اجرایی در دایرکتوری /tmp خود، کپی کردن گواهینامههای TLS، و اجرای باینری امتحان کنید. به این صورت:
$ go build -o /tmp/web ./cmd/web/ $ cp -r ./tls /tmp/ $ cd /tmp/ $ ./web time=2024-03-18T11:29:23.000+00:00 level=INFO msg="starting server" addr=:4000
و دوباره، باید بتوانید در مرورگر خود به https://localhost:4000 مراجعه کنید و همه چیز باید به درستی کار کند — علیرغم اینکه باینری در مکانی است که به فایلهای UI اصلی روی دیسک دسترسی ندارد.