Middleware ir nav antraštė
Keturi failai kaip skirtukai, priklausomybių tvarka: middleware.go → nav.go → layout.templ → home.templ (užklausos vamzdynas, antraštės duomenų modelis, tada du šablonai, kurie jį naudoja). Paskutiniai du — pakeitimai.
1. internal/handlers/middleware.go (naujas) — trys dalys:
func (h *Handlers) LoadUser(next http.Handler) http.Handler { /* slapukas → kontekstas, neblokuoja */ }
func (h *Handlers) RequireAuth(next http.Handler) http.Handler { /* nėra vartotojo → nukreipia /login */ }
func UserFrom(ctx context.Context) (db.User, bool) { /* išima vartotoją atgal */ }
Vartotojas keliauja užklausoje tipizuotu konteksto raktu (userCtxKey), privačiu ctxKey tipu, tad niekas kitas su juo nesusidurs. LoadUser užloguoja tikrą DB klaidą, bet vis tiek aptarnauja užklausą kaip anoniminę — viena netvarkinga užklausa neturėtų nugriauti viso puslapio.
2. internal/web/nav.go (naujas) — mažas modelis, kurio reikia antraštei:
type Nav struct {
LoggedIn bool
Email string
}
(CSRFToken laukas prisijungs 6 pamokoje.)
3. internal/web/layout.templ (modify) — statinį antraštės šūkį pakeičia tikra navigacija, besišakojanti pagal nav.LoggedIn:
if nav.LoggedIn {
<a href="/dashboard">Dashboard</a>
<span class="who">{ nav.Email }</span>
<form method="post" action="/logout"><button>Log out</button></form>
} else {
<a href="/login">Log in</a>
<a href="/register">Register</a>
}
Layout dabar ima antrą parametrą, nav Nav — tad kiekvienas puslapis jį perduoda.
4. internal/web/home.templ (modify) — vienintelė maketo pakeitimo pasekmė: Home(userCount int64) tampa Home(nav Nav, userCount int64) ir paduoda nav į @Layout("Home", nav). Puslapio kūnas nepaliestas.
Kol kas niekas naujo neatvaizduojama — joks apdorotojas nesukuria nav ir nekviečia LoadUser. Tai — kito žingsnio darbas, kur ateina prisijungimas bei atsijungimas ir antraštė atgyja.