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:
@@ -355,6 +355,10 @@ func (s *service) mount(r pact.Router) {
|
||||
constrainFileID(g)
|
||||
g.Get("/{vendor}/{plugin}/{controller}/{id}/files/{field}/{file}/thumb", s.fileThumb)
|
||||
constrainFileID(g)
|
||||
// Uploads of plugin field type elements (D-18): cabana owns the route,
|
||||
// the type's Upload only stores the file. {id} 0 is the create form.
|
||||
g.Post("/{vendor}/{plugin}/{controller}/{id}/fields/{field}/upload", requireAjax(s.fieldUpload))
|
||||
constrainFile(g)
|
||||
})
|
||||
// The SPA shell: public, no guard. ServeMux prefers every API pattern
|
||||
// above over the {path...} wildcard.
|
||||
@@ -1074,6 +1078,13 @@ func (s *service) operationDeclared(w http.ResponseWriter, r *http.Request, cc *
|
||||
}
|
||||
|
||||
func projectRow(row any, controller pact.AdminController, cols []ListColumn) map[string]any {
|
||||
return projectRowCtx(context.Background(), row, controller, cols)
|
||||
}
|
||||
|
||||
// projectRowCtx is one list row: the id and every visible column. A column
|
||||
// whose type is a plugin field type with ListValue shows the type's text for
|
||||
// the stored value.
|
||||
func projectRowCtx(ctx context.Context, row any, controller pact.AdminController, cols []ListColumn) map[string]any {
|
||||
v := reflect.ValueOf(row)
|
||||
for v.Kind() == reflect.Pointer {
|
||||
if v.IsNil() {
|
||||
@@ -1100,6 +1111,10 @@ func projectRow(row any, controller pact.AdminController, cols []ListColumn) map
|
||||
if !field.IsValid() || !field.CanInterface() {
|
||||
continue
|
||||
}
|
||||
if ft := col.fieldType; ft != nil && ft.def.ListValue != nil {
|
||||
out[col.Key] = ft.def.ListValue(ctx, derefValue(field.Interface()))
|
||||
continue
|
||||
}
|
||||
out[col.Key] = field.Interface()
|
||||
}
|
||||
return out
|
||||
|
||||
Reference in New Issue
Block a user