Config static for field descriptions?

49 views
Skip to first unread message

Jonathon Menz

unread,
Oct 22, 2015, 12:38:36 PM10/22/15
to SilverStripe Core Development
I'm a big fan of the form scaffolding in SilverStripe, but I frequently find myself having to modify getCMSFields() to call setDescription() to set some help text on fields, when the field label doesn't go far enough to explain what a field value will be used for and what it should look like.

I'm wondering if it is worth adding a $field_descriptions static to DataObject so help text can be picked up automatically, just like $field_labels, $singular_name, $plural_name etc.

I find this kind of contextual help is very effective for CMS users but I also think this could be a good reference for developers, documenting what certain fields are for without having to put comments next to each item in their $db static.

What do you guys think?

Sam Minnée

unread,
Oct 22, 2015, 12:52:03 PM10/22/15
to SilverStripe Core Development
I'm not sure that more config statics is the best way to solve this problems. They're kind of a bit bloaty as it is.

But I do agree that that it could be better. A few other options...

FieldList::batchSet($attribute, $valueMap)
We could still use getCMSFields but provide a better mechanism for setting attributes in bulk...

function getCMSFields() {
  $fields = parent::getCMSFields();
  $fields->batchSet('Description', array(
     'Title' => '3-5 words that describe this page without context.',
     'Abstract' => '3 sentence synopsis of content',
  ));
  return $fields;
}

composite $field_labels
Field labels could support more complex values. Solves the problem without growing the number of statics. It's still a form of static bloat, though:

static $field_labels = [
  "Title" => ["Heading", "3-5 words that describe this page without context."]
];

or

static $field_labels = [
  "Title" => ["title" => "Heading", "description" => "3-5 words that describe this page without context."]
];

The choices between these are mostly aesthetic, though. What do others think?


--
You received this message because you are subscribed to the Google Groups "SilverStripe Core Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to silverstripe-d...@googlegroups.com.
To post to this group, send email to silverst...@googlegroups.com.
Visit this group at http://groups.google.com/group/silverstripe-dev.
For more options, visit https://groups.google.com/d/optout.

Jonathon Menz

unread,
Oct 22, 2015, 1:28:51 PM10/22/15
to SilverStripe Core Development
I'm not familiar with the static bloat issue so I can't make a call on priority there, but I think statics have an advantage for a couple of reasons

1. They're easier to define for developers (less typing / knowledge of Form methods required)
2. They're easy for developers to override when working with modules / third-party code

I don't mind the composite idea but I kind of feel like that would make it harder to work with? The first example seems restrictive in that you would have to override the field label if you want to set a description. The second example doesn't sacrifice any flexibility but there's more syntax to remember compared to adding a separate $field_descriptions static.

Patrick Nelson

unread,
Oct 22, 2015, 1:43:47 PM10/22/15
to silverst...@googlegroups.com
To be fair, working at an instance level (i.e. calling/overriding or "updating" the return value from ->getCMSFields()) is easily just as flexible, if not more so, especially considering that allows you to move away from maintaining global state (thereby reducing cross contamination of concerns). 

I'm assuming that these "batch" methods would probably iterate through ALL instances of "FormField" is that correct? If so, I'd suggest you make two changes:
  1. Deep: Works in nested FieldList's. That is, make it easier to fetch ALL FormField's in a FieldList (for which this is repeated frequently throughout the framework), e.g. FieldList->insertBefore(), FieldList->insertAfter() and I'm sure many others.

  2. Setup a helper that then depends on that new method (likely on FieldList itself).
Also optional:

  • Return fields as an array and/or flat FieldList for which I can iterate over (Iterable) or cast via ->toArray() so that I as a developer can use PHP's native foreach() and do whatever I want there

  • Setup a helper method to get all JavaScript'y with it and do something similar to ->each(function($field) { ... });
That'd be nice :)


Loz Calver

unread,
Oct 22, 2015, 1:45:44 PM10/22/15
to SilverStripe Core Development
Could we use i18n to do this without introducing more statics? We currently have entities like Member.db_Password for the field labels (I don’t believe the private static field_labels can be translated?), so we could scan for Member.db_Password_description and if we find a matching entity automatically set the description, if not just leave it empty.

Jonathon Menz

unread,
Oct 22, 2015, 2:55:16 PM10/22/15
to SilverStripe Core Development
@Patrick - yeah I agree working in getCMSFields() is definitely more powerful, but we can already do that. Having some batch actions in Form could definitely be cool but what I'm more interested in is an easier way to provide a default/baseline value, which could then be overridden in a variety of ways. It can be quite difficult to modify form fields some times, like when they are being altered by a DataExtension and then you want to modify it again after that. If we used the config system for field_descriptions and module authors embraced it, it should make them more accessible. You'd still be able to do customise to your heart's content with getCMSFields() on top of that.

Jonathon Menz

unread,
Oct 22, 2015, 3:00:57 PM10/22/15
to SilverStripe Core Development
That's an interesting idea Loz, I always assumed statics could be translated (I know nothing about i18n). The main thing I like about statics is that they're included front and centre in my class definitions. As a developer this means I'm much more likely to pay attention to them and ensure they're valid. If it was moved out in to i18n would these values need to be stored in a separate file? I probably wouldn't make use of it in that case.

off...@netwerkstatt.at

unread,
Oct 23, 2015, 3:35:09 AM10/23/15
to silverst...@googlegroups.com

Hi Jono, hi Loz,

 

Well, using i18n (and zauberfisch’s betterI18N task for automatic yml generation, see https://github.com/Zauberfisch/silverstripe-better-i18n) clears up your code a lot. No need to define all the field lables in your DataObject class, no need to create extra _t() statementes for them, that’s a very nice way to get your form scaffolded and the field labels translated.

 

The static field lables cannot be translated, so you need to define a fieldLabels() method in your class. Unfortunaltely static $fieldLabels also overrules I18N’s db_Foo, which is in return a major pain when I try to make good modules I18N ready…

 

By default the name of the db field is used as field label, e.g. “FirstName” will become “First Name”, you can of course overwrite it in your lang/en.yml

 

This of course requires some “international” thinking I do every day, cause 95% of my projects are multi language projects (and on some days I really think you guys US, NZ or UK building English only sites must be really lucky!)

 

Cheers, Werner (wmk)

Nicolaas Thiemen Francken - Sunny Side Up

unread,
Oct 25, 2015, 9:51:13 AM10/25/15
to silverstripe-dev
Great discussion.

I am working on a front-end editor at the moment (front-end editor is a sort of CMS for front-end where businesses can maintain their listing on the website) and I can see great value in Sam's idea (see Sam's mail for more details): 

FieldList::batchSet($attribute, $valueMap)


I have always thought it would be great to also have a way to set icons for data objects (and SiteTree Objects) to make the CMS more visual (e.g. you could show a relevant icon with a gridfield).

Nicolaas

Marijn Kampf

unread,
Oct 25, 2015, 10:15:27 AM10/25/15
to silverst...@googlegroups.com
Hi Nicolaas,


> I have always thought it would be great to also have a way to set icons for data objects (and SiteTree Objects) to make the CMS more visual (e.g. you could show a relevant icon with a gridfield).


For one of my recent clients I created an extension to GridField to allows colour coding of rows and adding alerts including a fontawesome icon to a row. If there is interest I can see whether I can roll it into a quick module.



Best wishes,

Marijn Kampf
Exadium - Online Marketing & Web Development
mar...@exadium.com / www.exadium.com
uk mobile: 07 525 49 9234 / uk landline: 01446 620 436 / nl telefoon: 0357 110 379
international mobile: 0044 7525 49 9234 / phone uk: 0044 1446 620 436 / phone nl: 0031 35 71 10 379

Colin Burns

unread,
Oct 25, 2015, 12:56:29 PM10/25/15
to silverst...@googlegroups.com
Hi Marjin,

I'd love to see this as a module or even an example of how you are doing it.

Cheers,
_____________________________
From: Marijn Kampf <mar...@exadium.com>
Sent: Monday, October 26, 2015 12:15 AM
Subject: Re: [silverstripe-dev] Config static for field descriptions?
To: <silverst...@googlegroups.com>

Marijn Kampf

unread,
Oct 26, 2015, 12:16:14 PM10/26/15
to silverst...@googlegroups.com
Hi Colin,

Module to add icons to GridField can be found at: https://github.com/marijnkampf/gridfield-icon-row-class



Unfortunately, I can only get the row colours/classes to work in combination with FrontEndGridField and not on the backend.

Best wishes,

Marijn Kampf
Exadium - Online Marketing & Web Development
mar...@exadium.com / www.exadium.com
uk mobile: 07 525 49 9234 / uk landline: 01446 620 436 / nl telefoon: 0357 110 379
international mobile: 0044 7525 49 9234 / phone uk: 0044 1446 620 436 / phone nl: 0031 35 71 10 379

Jonathon Menz

unread,
Oct 26, 2015, 2:14:49 PM10/26/15
to SilverStripe Core Development
Hi Warner, thanks for your input. So it sounds like there's a consensus that introducing another config static isn't a good solution, because:

1. We already have a bit of a static bloat problem
2. PHP statics can't be translated

If so item 2 sounds like a significant existing issue so addressing that seems important to me, and could provide a path towards Loz's suggested solution. Going by DataObject::providei18Entities() and looking at some translation files it appears that of the statics only $singular_name and $plural_name support translation currently, and it seems kind of tacked on rather than baked in (there are separate singular_name( ) and i18n_singular_name( ) methods for instance). We'd need to support $field_labels and $field_descriptions to get proper translatable form scaffolding happening and ideally this would be more deeply integrated.

Going back and adding a twist to one of Sam's ideas, maybe instead of adding a $field_descriptions static, we should deprecate the $singular_name, $plural_name and $field_labels statics, and combine them in to a single composite 'lang' static. This would hold all the information that may be subject to translation, but must not affect any behaviour. It could be overridden through config yml files, but language yml files would have the highest priority (apart from procedural code) and this is what you should use to override the values. Example of config structure:

  Member:
    lang
:
      singular_name
: 'Member'
      plural_name
: 'Members'
      cms_fields
:
       
LockedOutUntil:
          label
: 'Locked out until'
       
PasswordExpiry:
          label
: 'Password Expiry Date'
          description
: 'The last day this password can be used'

I'm assuming language yml files would omit the 'lang' level. Could something like this be a good compromise? It would reduce the number of statics in use (in a way...) while improving form scaffolding and translation capabilities at the same time.

As an aside, just reiterating that FieldList::batchSet() sounds like a really useful tool as well but serves a different purpose - it's something you would use to customise an existing form rather than create one automatically. I'd like to keep this thread focused on improving automatic form scaffolding if possible. (although, maybe the form scaffolder itself could make use of batchSet?).
Reply all
Reply to author
Forward
0 new messages