-
-
Notifications
You must be signed in to change notification settings - Fork 185
feat: Field reflection #7676
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v6/refact/fields-named-args
Are you sure you want to change the base?
feat: Field reflection #7676
Conversation
d3fa9a5 to
7806dc5
Compare
|
@bastianallgeier do we want to put this in the core and not just getkirby.com? One open todo in regard to the docs I see here is that we have named arguments that are not blueprint options (model, siblings) and how to differentiate them. Is hard coding them ok? Or limited if later field classes have their own arguments that shouldn't be blueprint options? |
|
I still haven't given up on the dream that we can turn this into an editor at some point - and even if it is only for individual field options. I also think that we could heavily benefit from heaving this in the core when it comes to exporting JSON schemas for blueprints. The code that it takes is so small that I would not mind having it in there. About the props. I've mentioned in the description that I'm really not happy about having model and siblings in the constructor. I think it would be really nice if field classes would not have to repeat them all the time. Maybe we could inject them after creation? This would mean though that we cannot rely on them in setters that are called in the constructor, which could be a bit nasty. But if we keep every property "lazy" it should be fine. Then the factory method could do something like this: $field = new BlocksField(...$args);
$field->setModel($model);
$field->setSiblings($model);For other props that should not be public, we could either think about using attributes in their docblocks or a dynamic ignore list. I'd suggest to start with a fixed list and as soon as we get into a dead end with that, we can work on a better solution. |
f9e6fd7 to
14fb5c2
Compare
7ddd9c1 to
258b6b6
Compare
5dd5edd to
48baca2
Compare
258b6b6 to
b9a63f3
Compare
d341043 to
df26bc3
Compare
Merge first
FieldClasswith named props #7608Description
In this PR, I'm trying to explore how well we can reflect the new Field classes with named arguments. Turns out: very well. But we need to define them all in the constructor. I'm torn here. It can be a lot of work and there are arguments that are super annoying to repeat (model, siblings, when, width, translate, etc.) But on the other hand it really gives a fantastic overview of all the capabilities of a field. It's somehow very close to the property table in our docs, which I like a lot. Maybe we can find a way to not have to pass at least Model and Siblings each time and only focus on the props that also turn up in our table?
We can now reflect such classes like this:
Here's the output for the blocks field …
[ "autofocus" => [ "name" => "autofocus", "type" => "bool", "default" => false, "description" => "Sets the focus on this field when the form loads. Only the first field with this label gets", ], "default" => [ "name" => "default", "type" => "array", "default" => [], "description" => "Default value for the field, which will be used when a page/file/user is created", ], "disabled" => [ "name" => "disabled", "type" => "bool", "default" => false, "description" => "If `true`, the field is no longer editable and will not be saved", ], "empty" => [ "name" => "empty", "type" => "array|string|null", "default" => null, "description" => "Sets the text for the empty state box", ], "fieldsets" => [ "name" => "fieldsets", "type" => "array|string|null", "default" => null, "description" => "Defines the allowed block types in the blocks field. See below.", ], "help" => [ "name" => "help", "type" => "array|string|null", "default" => null, "description" => "Optional help text below the field", ], "group" => [ "name" => "group", "type" => "?string", "default" => null, "description" => "Group name to identify all block fields that can share blocks via drag & drop", ], "label" => [ "name" => "label", "type" => "array|string|null", "default" => null, "description" => "The field label can be set as string or associative array with translations", ], "name" => [ "name" => "name", "type" => "?string", "default" => null, "description" => "", ], "max" => [ "name" => "max", "type" => "?int", "default" => null, "description" => "Sets the maximum number of allowed items in the field", ], "min" => [ "name" => "min", "type" => "?int", "default" => null, "description" => "Sets the minimum number of required items in the field", ], "pretty" => [ "name" => "pretty", "type" => "bool", "default" => false, "description" => "Saves pretty printed JSON in text files", ], "required" => [ "name" => "required", "type" => "bool", "default" => false, "description" => "If `true`, the field has to be filled in correctly to be saved.", ], "translate" => [ "name" => "translate", "type" => "bool", "default" => true, "description" => "Should the field be translatable?", ], "when" => [ "name" => "when", "type" => "array", "default" => [], "description" => "Conditions when the field will be shown", ], "width" => [ "name" => "width", "type" => "?string", "default" => "1/1", "description" => "The width of the field in the field grid. Available widths: `1/1`, `1/2`, `1/3`, `1/4`, `2/3`, `3/4`", ], ]