Il giorno martedì 22 gennaio 2013 14:22:02 UTC+1, Ingo Schommer ha scritto:
I think this is overcomplicating the FieldSet API for an advanced use case.It would go against any usage of $before/$after parameters and the insertBefore()/insertAfter(),
or make them very hard to understand in case it tries to auto-assign its own numerical priorities based on them.
The actual FieldList::addFieldToTab only permit to put a FormField *before* another, so in userspace it's impossible (or at lest counter-intuitive) to put a FormField at the end of the FieldList. In addition I think that the actual ordering method is really complicated, especially when arise lot of inheritance/extension.
A numerical weight is a really simple concept, during getCmsField() or updateCmsField() the developer have just to insert a $field->setWeight(100); if he want the field to be the last, or $field->setWeight(-100); if he want the field to be the first. Default weight can be 0, and in case of same weight the field can be ordered alphabetically, or just in the older way.
If the extension relies on knowing the entire field list,
The extension need to put some FormFields in the correct position, it does not necessarily relies on knowing the entire field list.
a workaround is to make
the updateCMSFields() method fault tolerant enough to be applied multiple times,
and then call updateCMSFields() throughout the subclasses.
I did it for some page, but it's difficult to do with DataObjects, since they don't implement disableCMSFieldsExtensions():
/************************
******** PAGE ********
*************************/
public function getCMSFields() {
// Ottengo l'elenco dei Fields
SiteTree::disableCMSFieldsExtensions();
$fields = parent::getCMSFields();
SiteTree::enableCMSFieldsExtensions();
/* Subtitle */
$field = new TextareaField('Subtitle');
$field->setTitle('Sottotitolo');
$fields->addFieldToTab('Root.Main', $field, 'Content');
// Chiamo l'updateCMSFields che ho soppresso all'inizio della funzione
$this->extend('updateCMSFields', $fields);
return $fields;
}
/************************
**** EXTENSION *****
*************************/
public function updateCMSFields(\FieldList $fields) {
parent::updateCMSFields($fields);
/* SliderImage */
$field = new UploadField('SliderImage');
$field->setTitle('Immagine Slider');
$fields->addFieldToTab('Root.Main', $field, 'Content');
/* PositionInScroller */
$field = new DropdownField('PositionInScroller', 'Posizione nello Scroller', self::$positions);
$field->setTitle('Posizione nello Scroller');
$fields->addFieldToTab('Root.Main', $field, 'SliderImage');
}
It works, but I think that this technique is inefficient and again counter-intuitive as well as impossible to run on DataObjects.
Furthermore I can develop my updateCMSFields() method fault tolerant enough to be applied multiple times, but I don't know how many extension I will apply to my DataObjects, maybe in the future I will want to use a module developed from GitHub and the behavior will be unpredictable.
On the long run, I think we need a wrapper around getCMSFields()
which handles these invocation concerns, rather than leaving it in user space.
This wrapper could then be a bit smarter about prioritizing certain extensions,
e.g. call Translatable->updateCMSFields() *after* all other updateCMSFields().
In a perfect world the FieldList have to be accessible during the updateCMSFields() and not *after* it, so ordering will be possible. But it will still be difficult to put a field at the end of the list :)
My 2 cent
g4b0