# Development post-it notes. Things/Snippets of code I should not forget. Made as a quick cheatsheet for me and contributors to check if they're in doubt. ## Using context to retrieve important values. Certain middlewares will store a couple of values on the context to make your developer life easier. Here's a couple examples: ```go user, ok := r.Context().Value(lib.UserKey).(*types.User) session, ok := r.Context().Value(lib.SessionKey).(string) loggedIn, ok := r.Context().Value(lib.LoggedInKey).(bool) // this should be fine to be used anywhere. repo, ok := r.Context().Value(md.RepoKey).(types.Repo) // provided by the repo middleware ``` **IMPORTANT** *AND* **TODO**: use `val, ok := ctx.Value(key).(Type); if !ok { ... }` to check if the value is set. ## Form validation. Use the md.ValidateForm such as ```go type LoginForm struct { Email string `form:"email" validate:"required,email"` Password string `form:"password" validate:"required,min=8"` } md.ValidateForm[LoginForm](http.HandlerFunc(a.login)) // Use handle, not handleFunc. ``` and retrieve the form using ```go form, ok := md.Form[LoginForm](r) // r being the request ``` Bear in mind forms have that special property because of `contextKey`. Forms are CSRF-protected. `{{ .csrfField }}` must be added inside each form. ## Mux routing. I use `gorilla/mux` as a router: - Use a blank space `""` for indexes. - Use `{path:.+}` for those recursive paths. - Define all routers in app.go since it's be easier to manage. ## Rendering templates. Use the following code: ```go a.Render(w, r, "base", "repo/view", map[string]any{"Repo": repo}) ``` Where `a` is your *App, `base` the layout, `repo/view` is the template, and `map[string]any{"Repo": repo}` is the data, accessible as `.Repo` Use `{{.sshDomain}}` and `{{.sshPort}}` to get the domain and port the SSH server will be listening at. Useful variables: ```go {{.loggedIn}} // bool, is user logged in? self-explanatory. {{.user}} // types.User (if loggedIn is true) {{.sshDomain}} // domain of the SSH server. {{.sshPort}} // port which the SSH server is listening from. ``` When you need to access the root "." while (e.g) ranging, use "$" to access it. Example: ```go {{range .Files}} {{$.DirectoryName}}/{{.Name}} {{end}} ``` ### Template rendering utils. I made a couple utils to be used on the templates. For instance: ```go {{if IsText .Blob.Type}}
{{.Blob.Content}}
{{else if IsImage .Blob.Mime}} {{end}} ``` ALWAYS USE `{{RepoRoot .Meta}}` instead of "/~(user)/(repo-name)/". It's easier to change later. It has a leading slash and no trailing slash. ```go {{RepoRoot .DBRepo}} -> "/~poyo/banana" {{TruncateStr "hello world" 5}} // -> "hello" {{Mime .Blob}} // -> "image/png" ``` You can check the full list at the templating function itself. ### Time. When rendering a date, pass in a UTC date into any element with a class `local-time`, and `time.js` will convert it to the user's local time. Example: ```html ``` ### CSS Styling: `.inline` for inlined and gapped containers. ## Message and Error displaying. `?msg=AuthSuccess` and `?err=RequireAuth` are examples of query params that will show a banner on the page. Keep in mind, validation errors are Base64 encoded (urlencoded) and are passed as `?err=ValidationErr-(base64)`. The messages and validation middleware handle it, so don't worry about it much. CSS for errors and messages is on the main stylesheet (`styles.css`). `.message`, `.warning` and `.error` have a slight vertical margin. If you use the same class names as HTML attributes, they will have no margin. ## Lib/Submodules. Please, separate stuff into lib submodules to avoid circular imports. I had to suffer an hour of debugging because I implemented git handling on a db function. I scrapped everything and rewrote it separately, and it worked. That's proof separating is better! ## Hackatime. Users can login using Hack Club's Hackatime. Why? To get stats on their projects. ## Git. When opening a repo with `git.Repo()`, make sure to add `defer repo.Close()` after it. ## Resources - [https://github.com/firecracker-microvm/firecracker/blob/main/docs/prod-host-setup.md](Firecracker production guide)