# towel 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.