feat(16.2-01): translatable plugin field types, untouched skip, writes, list values and uploads
- translatable types lift, store and hydrate through the ML path
(isMLField); Decode and Load run per locale and notices carry the locale
- on update a value equal to the served value (Load of the stored host
value or exact translation) is neither decoded nor written
- FieldWrite, FieldWritesFromContext and WithFieldWrites expose what a save
writes to the Form hooks
- list columns may use a plugin alias and show the type's ListValue
- POST .../{id}/fields/{field}/upload hands the file to the type's Upload
(guard, X-Requested-With, permissions, field context, record scope, body
cap); OpenAPI, route inventories, README and docs updated
This commit is contained in:
@@ -65,3 +65,56 @@ func VirtualFieldsFromContext(ctx context.Context) (map[string]any, bool) {
|
||||
}
|
||||
return out, true
|
||||
}
|
||||
|
||||
type fieldWritesKey struct{}
|
||||
|
||||
// FieldWrite is one value a save wrote for a plugin field type
|
||||
// (pact.HasFormFieldTypes): Locale is the content locale of a translatable
|
||||
// type's value and empty otherwise, Default is true when the value went to
|
||||
// the host column, and Value is what the type's Decode returned.
|
||||
type FieldWrite struct {
|
||||
Locale string
|
||||
Default bool
|
||||
Value any
|
||||
}
|
||||
|
||||
// withFieldWrites returns ctx carrying the plugin field values a save writes.
|
||||
func withFieldWrites(ctx context.Context, writes map[string][]FieldWrite) context.Context {
|
||||
if writes == nil {
|
||||
writes = map[string][]FieldWrite{}
|
||||
}
|
||||
return context.WithValue(ctx, fieldWritesKey{}, writes)
|
||||
}
|
||||
|
||||
// WithFieldWrites returns ctx carrying writes as a save would, so a test can
|
||||
// call a Form hook that reads FieldWritesFromContext. The map is copied.
|
||||
func WithFieldWrites(ctx context.Context, writes map[string][]FieldWrite) context.Context {
|
||||
return withFieldWrites(ctx, copyFieldWrites(writes))
|
||||
}
|
||||
|
||||
// FieldWritesFromContext returns the values a create or update save
|
||||
// actually writes for the form's plugin field types, keyed by field name, for
|
||||
// the context handed to a Form hook (pact.FormBeforeCreate,
|
||||
// pact.FormAfterCreate, pact.FormBeforeUpdate, pact.FormAfterUpdate). A field
|
||||
// or locale whose submitted value equals the value the form was served is
|
||||
// not written and not listed; a translatable type lists one entry per
|
||||
// written locale. The map is a copy. The second result is false outside a
|
||||
// create or update save.
|
||||
func FieldWritesFromContext(ctx context.Context) (map[string][]FieldWrite, bool) {
|
||||
if ctx == nil {
|
||||
return nil, false
|
||||
}
|
||||
writes, ok := ctx.Value(fieldWritesKey{}).(map[string][]FieldWrite)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
return copyFieldWrites(writes), true
|
||||
}
|
||||
|
||||
func copyFieldWrites(in map[string][]FieldWrite) map[string][]FieldWrite {
|
||||
out := make(map[string][]FieldWrite, len(in))
|
||||
for field, list := range in {
|
||||
out[field] = append([]FieldWrite(nil), list...)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user