Custom Field Authors!
A recent bug in my Location Field plugin subverted my notions about how options were passed to custom fields, from the Blueprint.
The Problem
When a field is initialized, it seems like the extra params are not available in any easily accessible way.
A Blueprint containing the following field…
fields:
location:
label: Location
type: place
center:
lat: 45.5230622
lng: -122.67648159999999
zoom: 9
help: >
Move the pin wherever you'd like, or search for a location!
…will accept the standard label
, type
and help
keys, but not expose the custom center
key to the constructor. To be more specific, when inspecting the Field class, the center
property has not been set, and that portion of the decoded YAML is, as far as I can tell, never actually is persisted as a property (or properties) on the class.
The authors of the Selector plugin has a clever way of capturing these additional keys by overriding the low-level “magic method” __set
, as seen here.
I’m going to posit that this is the wrong approach (to no one’s fault), in that it could easily compromise other functionality that depends on the __set
method (any assignment of properties on PHP object), and that we ought not have to hook into low-level PHP functionality to handle custom options assignment— that should be automatic, but I accept that defaults handling can be done on a plugin-by-plugin basis.
Furthermore, when I used the magic method strategy, it seemed like forms built inside a structure field were not receiving the options at all. I ended that line of inquiry for the reason above.
What We Need
In order to make custom field development safe and accessible, it seems as though we need the complete map of options passed in to the constructor function.
What We Have
- It would appear as though the Form class provides the behind-the-scenes setting behavior that the Selector plugin takes advantage of.
- When the Fields collection is created, the entire
$params
array is passed in, but it isn’t stored. A couple of keys are re-set, and then theObj
constructor is called, which, according to the source, already maps key/value pairs into properties. What gives? I don’t see any of those keys when inspecting my class. Perhaps the chain of inheritance doesn’t go back this far? Maybe I have more flawed notions about the inheritance and sequence of initialization.
Any ideas? I’m fine using a reliable solution that exists, or authoring a Pull Request to the Panel core to make this a reality. I just don’t know (conceptually, technically) where the best place to start would be.
Thanks for your time!