Learning go: day 13
All checks were successful
Build and copy to prod / build-and-copy (push) Successful in 2m12s
All checks were successful
Build and copy to prod / build-and-copy (push) Successful in 2m12s
This commit is contained in:
parent
8f30bed874
commit
d410995778
85
src/blog/posts/2024/5/learning-go-day-13.md
Normal file
85
src/blog/posts/2024/5/learning-go-day-13.md
Normal file
@ -0,0 +1,85 @@
|
||||
---
|
||||
title: "Learning Go: Day Thirteen"
|
||||
date: 2024-05-15T08:00:00.0Z
|
||||
tags:
|
||||
- learning
|
||||
- go
|
||||
excerpt: "Creating some basic HTML output, and bundling static files"
|
||||
---
|
||||
|
||||
So now I want to start working on putting together a basic interface. This post won't be about creating the interface itself, but instead just the ground work that will allow me to build it over the next post or two.
|
||||
|
||||
## Creating some HTML output
|
||||
|
||||
Alright, this was actually really straightforward. There's a module called [html/template](https://pkg.go.dev/html/template) that can be used to parse HTML, and includes a templating language.
|
||||
|
||||
So I've created a super-simple HTML template at `templates/index.html`, and then use the `template.ParseFiles` function to parse and display it:
|
||||
|
||||
```html
|
||||
<!-- templates/index.html -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Oopsie</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Oopsie uptime monitoring</h1>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```go
|
||||
// main.go
|
||||
|
||||
http.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) {
|
||||
pings := ping.ListGroupedBySite(db)
|
||||
|
||||
if _, err := json.Marshal(pings); err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
|
||||
t, _ := template.ParseFiles("templates/index.html")
|
||||
t.Execute(w, nil)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
This works! But I can't deploy it, because when I compile the binary and upload it to my server it can't find the template files. Luckily, there's a package that can help me do that.
|
||||
|
||||
## Bundling static files
|
||||
|
||||
This part is basically magic. I have no idea how it works, but there is a package called [embed](https://pkg.go.dev/embed). I can use it to create an instance of `FS` with some bundled static content, and that then gets bundled into my binary, and it takes about 3 lines of code to do it 🤯.
|
||||
|
||||
```go
|
||||
// main.go
|
||||
|
||||
import (
|
||||
"embed"
|
||||
)
|
||||
|
||||
//go:embed templates/*
|
||||
var content embed.FS
|
||||
|
||||
http.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) {
|
||||
pings := ping.ListGroupedBySite(db)
|
||||
|
||||
if _, err := json.Marshal(pings); err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
|
||||
t, _ := template.ParseFS(content, "templates/index.html")
|
||||
t.Execute(w, nil)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
And then when I run `go build`, the resulting binary file has the HTML bundled in it and I can run it on my server. This is a _really_ powerful thing to have built directly into the standard library.
|
||||
|
||||
So that's it for today, like I mentioned earlier, my next one or two posts will mostly be focused on making a UI.
|
Loading…
Reference in New Issue
Block a user