docs(modules): rewrite cabana, wire, towel, festival, compass, backpack READMEs

This commit is contained in:
Jakub Zych
2026-09-28 15:43:23 +02:00
parent cc584e906e
commit 1bd34948a9
6 changed files with 574 additions and 6 deletions

View File

@@ -1,3 +1,70 @@
# towel
`towel` carries request-scoped actor, organization, collection, and locale values through `context.Context`. Admin schema and controller code import it while processing scoped requests; set an actor with `towel.WithActor` in `context.go`.
Request-scoped actor, organization, collection and locale values carried through `context.Context`.
`import "git.golem15.com/golem15/summercms/modules/towel"`
## Overview
`towel` replaces the request-global state that WinterCMS reads through facades (the current locale, the acting user) with explicit values on the request context. Middleware stores a value once, and any code further down the call chain that receives the context reads it back without a global lookup. [surf](../surf/README.md) sets the locale from `Accept-Language` (or the signed-in user's preferred locale) and the organization for every request, [phrasebook](../phrasebook/README.md) reads the locale when it translates, and [cabana](../cabana/README.md) sets it while localizing admin schemas.
## Features
- Four independent string values, each with a setter and a getter: actor (`towel.WithActor`, `towel.Actor`), organization (`towel.WithOrganization`, `towel.Organization`), collection (`towel.WithCollection`, `towel.Collection`) and locale (`towel.WithLocale`, `towel.Locale`).
- Unexported context key types, so no other package can read or overwrite the values by accident.
- Getters return `(value, ok)`: a value that was set to an empty string is distinguishable from one that was never set.
- Nil-safe: a setter given a nil context starts from `context.Background()`, and a getter given a nil context reports `false`.
## Usage
```go
package blog
import (
"fmt"
"net/http"
"git.golem15.com/golem15/summercms/modules/towel"
)
// withAcmeScope tags every request with the organization and collection it serves.
func withAcmeScope(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := towel.WithOrganization(r.Context(), "acme")
ctx = towel.WithCollection(ctx, "blog")
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func listPosts(w http.ResponseWriter, r *http.Request) {
org, _ := towel.Organization(r.Context())
locale, ok := towel.Locale(r.Context())
if !ok {
locale = "en"
}
fmt.Fprintf(w, "posts for %s in %s\n", org, locale)
}
```
## API reference
| Identifier | Description |
|------------|-------------|
| `towel.WithActor` / `towel.Actor` | Store and read the acting user or client identifier. |
| `towel.WithOrganization` / `towel.Organization` | Store and read the organization (tenant) the request belongs to. |
| `towel.WithCollection` / `towel.Collection` | Store and read the collection the request operates on. |
| `towel.WithLocale` / `towel.Locale` | Store and read the locale used for translations and localized responses. |
## Dependencies
- SummerCMS modules: none.
- Third-party: none.
- Standard library: `context`.
## Testing
```sh
go test ./modules/towel/...
```
The tests exercise plain contexts and need no external services.