Last active
October 20, 2023 22:12
-
-
Save mitranim/1e358e51b75812d25f4fcba7262df1ac to your computer and use it in GitHub Desktop.
Watches templates and reinitializes them on changes without fully restarting the app (excerpt from real app)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"html/template" | |
"time" | |
"github.com/pkg/errors" | |
"github.com/rjeczalik/notify" | |
) | |
var templateFuncs = map[string]interface{}{} | |
func initTemplating() error { | |
err = reinitHtmlTemplates() | |
if err != nil { | |
return err | |
} | |
if DEVELOPMENT_MODE { | |
htmlEvents, err := watchHtmlTemplates() | |
if err != nil { | |
return err | |
} | |
go reinitHtmlTemplatesOnChange(htmlEvents) | |
} | |
return nil | |
} | |
func reinitHtmlTemplates() error { | |
templates := template.New("") | |
templates.Funcs(template.FuncMap(templateFuncs)) | |
_, err := templates.ParseGlob("templates/html/*") | |
env.htmlTemplates = templates // Writing a pointer is atomic. | |
return errors.WithStack(err) | |
} | |
func reinitHtmlTemplatesOnChange(events chan notify.EventInfo) { | |
for range events { | |
t0 := time.Now() | |
err := reinitHtmlTemplates() | |
if err != nil { | |
fmt.Printf("HTML template error: %+v\n", err) | |
} else { | |
t1 := time.Now() | |
fmt.Printf("reinited HTML templates in %v\n", t1.Sub(t0)) | |
notifyInternalSubscriptions(InternalNotification{Type: InternalNotificationTypeReload}) | |
} | |
} | |
} | |
func watchHtmlTemplates() (chan notify.EventInfo, error) { | |
events := make(chan notify.EventInfo, 1) | |
err := notify.Watch("templates/html", events, notify.All) | |
return events, errors.WithStack(err) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
{ | |
function reinit() { | |
const url = 'ws://' + window.location.host + '/ws' | |
const ws = new WebSocket(url) | |
ws.onmessage = onmessage | |
ws.onclose = onclose | |
} | |
reinit() | |
function onmessage({data}) { | |
let message | |
try {message = JSON.parse(data)} | |
catch (__) {return} | |
if (message && message.type === 'reload') { | |
window.location.reload() | |
} | |
} | |
function onclose() {setTimeout(reinit, 1000)} | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Notes
env.htmlTemplates
is a global which is used to render templates by name.The subscription notification (
notifyInternalSubscriptions
) broadcasts a message to websocket clients. The HTML pages include a snippet which connects to the server via a websocket, and reloads the page when receiving the appropriate message.