We recently adopted a new standard way to document "callback functions" -- see http://drupal.org/coding-standards/docs#callback-def for the standard and #1250500: [policy adopted; patch done] Find a (standard) way to document callback signatures for the issue where this was adopted.
The FormAPI #element_validate callback should be documented as part of this.
This involves the following tasks:
- add a definition of the callback to an api.php file
- rewrite the docblock of all #element_validate callback functions & methods:
-- state this is an implementation of the callback
-- remove any parameters
-- preserve description of what the callback accomplishes in the 2nd paragraph of the docblock
This would also require the form API docs at http://api.drupal.org/api/drupal/developer%21topics%21forms_api_referenc... to be changed to refer to the new callback documentation.
| Task | Novice task? | Contributor instructions | Complete? |
|---|---|---|---|
| Reroll the patch if it no longer applies. | Instructions | ||
| Update the issue summary | Instructions |
| Comment | File | Size | Author |
|---|---|---|---|
| #59 | 1985838-59.patch | 13.72 KB | gaurav-mathur |
| #58 | 1985838-58.patch | 13.72 KB | Ankit.Gupta |
| #57 | interdiff-1985838-56_57.txt | 1.22 KB | anchal_gupta |
| #57 | 1985838-57.patch | 13.72 KB | anchal_gupta |
| #56 | 1985838-56.patch | 13.59 KB | pradhumanjain2311 |
Comments
Comment #1
samhassell commentedI'll have a shot at this one. Patch soon.
Comment #2
samhassell commentedHere's a first run at it. I've added callback_form_element_validate() in a new file, form.api.php.
What to improve?
Cheers,
Sam.
Comment #3
joachim commentedThanks! It's looking pretty good.
The usual pattern AFAIK is that api.php files for hooks match a module, so this should probably go in system.api.php, as with other hooks and callbacks that are used by files in /includes.
> Really not sure what this is a callback for, though I've put hook_form().
I'd say it's for drupal_get_form().
> If the first line on a doc had some value, I've kept it as the first line of the second docblock. I figure its better to keep detail instead of removing it. Most instances I've simply replaced the first line.
Agreed. I'd maybe keep a bit more though:
It might be nice to keep the information in these, on a second line of docs?
Comment #5
samhassell commentedThanks, updated with the suggested changes.
I added back in most of the original first rows as the second rows.
Cheers,
Sam.
Comment #7
samhassell commentedFix for missing paren.
Comment #8
jhodgdonThanks for the patches!
A few things to address before this is ready for commit:
a) When I look at this patch, I see a nice standardization of the first line of these callback implementing functions. But maybe we can make it even better? What if the first line instead said:
Implements callback_form_element_validate() for a foo_bar element.
or maybe just
Implements callback_form_element_validate() for a foo_bar.
(especially if the first form wouldn't fit all in one line).
Then we could eliminate the second line (which isn't at all standard), and also the first line (which is what appears in function lists and the like) would give us more information. We use standards like that in some hook implementations, such as "Implements hook_form_FORM_ID_alter for the user login form".
Thoughts?
b) If for some reason you think (a) is a bad idea, then when you do something like this:
you either need to make this into two separate paragraphs, or wrap the two sentences together as a single paragraph.
c) In the callback definition itself, do not use @addtogroup callbacks. You have @ingroup callbacks already in the function. And please check to verify that this is not inside the @addtogroup hooks that is in system.api.php.
d) Do not indent the entire callback definition function two spaces inside system.api.php. It should be over to the left.
e) This line in the callback definition:
has an extra space of indentation between the * and the @param
f) The documentation for this parameter:
It should not say "the table element", but just "the element".
g) At the end of that doc block:
Remove the blank line.
h) Add an explanation in the documentation of the example callback like "The example function body is for validating a ..." (I am actually not sure what it is?).
i) This implementation did not get the standard first line:
Comment #9
samhassell commentedHey, thanks for the detailed review!
I've taken all these comments on board in the attached patch. A couple of questions/comments:
1. Is this the way to use @see in a class?
2. There are several of these validate functions that mention they are 'Render API callbacks'. Should we keep these lines even though they effectively duplicate the content of the first line?
3. I switched the example in the api.php file to the password compare code from form.inc.
Cheers,
Sam.
Comment #10
jhodgdonRegarding your questions:
1. Yes, that usage of @see is fine. You can also just do @see DataFieldRow::buildOptionsForm(). The rule is that if you use a namespace, it must start with a \, but you don't have to use a namespace if it's already referenced by the file in a namespace/use statement.
2. I don't think we need to include the "Render API callback" information. Also, we don't need the @param/@return if you say "Implements callback_foo()" (it's like implements hook_foo() -- we reference the definition already given in the callback definition). The only reason to have @param/@return is if it gives some information specific to that particular callback, but in that case it can probably be put in a separate paragraph anyway, like you could say about some validate callback "Verifies that the email address conforms to RFC ### and that the domain name is not in a list of spammers this module maintains.".
3. Good idea. :)
So, regarding the current patch... Besides removing param/return as noted in 2. above, I think it would also be nice if all of the "Implements ... for ..." statements were a little more consistent. Some say "for a foo_bar element", some say "for a #foo_bar element" [this is actually wrong, we don't put # before element names!], some say "for a foo bar element", some say "for #type 'foo_bar'", etc.
So let's standardize on one of these... My preference would be either:
- Implements callback_form_element_validate() for a foo_bar element.
- Implements callback_form_element_validate() for #type 'foo_bar'.
Your choice... or you can come up with something better, but let's try to keep them all the same?
Hm... I see that some of them are "elements" and some are "widgets". In the case of widgets, possibly they are not really being used as #element_validate callbacks? Check on that -- it's possible they are a different callback from the field API? If so we should file a separate issue and document that callback.
I also think that anything that's a class member is probably not really a callback_form_element_validate(), but again it's probably something else? But maybe I'm wrong... The idea here is that something should only be documented as "Implements callback_form_element_validate()" if it is being put into a form array as a #element_validate property. Right?
Oh, and one more thing. The callback function doc says it is a callback for drupal_get_form(). But unless drupal_get_form() or the Form API reference is going to mention callback_form_element_validate(), I think we need to say more than "Callback for drupal_get_form()" here. How about something like:
Provided as the #element_validate property for an element of a form array for drupal_get_form().
or something like that?
Comment #11
samhassell commentedAll good points, but before i roll the next patch I want to clarify a bit.
There are several types of #element_validate functions in core:
1. Generic form elements as defined by Form API.
2. Field API callbacks that are defined in the #element_validate (these are widget forms and element forms)
3. Validate callbacks for various admin forms.
4. Validate elements applied to a whole form.
5. Class based callbacks.
Type 1 are obvious inclusions for this patch and fit the "Implements callback_form_element_validate() for #type 'foo_bar'." doc perfectly.
Type 2 are out of scope for this patch as they are not defined in forms, they are defined in hook_element_info() or hook_field_instance_settings_form(). However hook_field_instance_settings_form() is actually a form so perhaps our doc does apply here. Hook_element_info element validate functions should be in 'callback_element_info_validate()'.
Type 3 should be in scope, however the docs will be "Implements callback_form_element_validate() for #type 'textfield'.", which may be confusing as it is actually for a specific implementation of a textfield. Do we need some way to indicate this?
Type 4 has a similar problem to type 3 - it isn't for a specific #type.
Type 5 class methods should probably be documented in the class i guess.
All of these apart from the hook_element_info() ones are using the #element_validate key from a form definition.
What do you think?
Comment #12
samhassell commentedComment #13
jhodgdonThis issue is supposed to be about documenting the callbacks for the Form API's #element_validate.... I think only (1) from the list in comment #11 falls into the scope of this issue, but I'm not sure... Can you provide some examples of each one so we can decide? And please do not change the status to "needs review" until we have another patch to review. Thanks!
Comment #14
joachim commentedYup, examples would be good. I'm confused as to how 2 & 3 are different from 1. If it's set in a form build array as '#element_validate' = 'foo', then it's in scope, surely?
> 4. Validate elements applied to a whole form.
If these are set on the '#validate' property, then they're not covered by this.
Comment #15
samhassell commented@joachim, I believe all the included functions are actually #element_validate related: thats how i found them in the first place.
Examples of each type:
1. Initial element level fields, such as url, number, color, machine_name. These are definitely in scope, and are all quite similar in their execution. Here is an example using the email element.
2. Field API Callbacks - These don't exist anymore as Fields are now Plugins! These are now type 5.
3. Validate callbacks for forms. With this example, the #type of the element is actually textfield, but putting that in the comment isn't accurate because it's not for generic textfield elements, it really relates to a specific instance of the textfield element, 'bgcolor'. The documentation may be more useful if it makes this clear. From image_rotate_form():
4. Validate callbacks applied to whole forms. Disregard this, I must have been drinking. This isn't even legal according to the FAPI docs.
5. Class Based Callbacks - this example is found inside the LinkWidget field plugin class. Callback docs may not make sense here, perhaps it should be referencing the parent class's method? There's a bunch of the in various plugin definitions and I'm sure there are more coming.
Comment #16
joachim commented> $element['#element_validate'] = array(array($this, 'validateTitle'));
That means it's still a callback -- just that instead of using a string for the callback, it's a PHP callable array that references the method.
> 4. Validate callbacks applied to whole forms. Disregard this, I must have been drinking. This isn't even legal according to the FAPI docs.
:D
> 3. Validate callbacks for forms.
> 1. Initial element level fields, such as url, number, color, machine_name
It's interesting how these two cases are in some ways identical, but at a conceptual level they are quite different. The element ones are generic and work with a form element no matter where it's used; the form ones may make assumptions regarding specifics of the element they validate and its place within the form.
Comment #17
jhodgdonI don't see a problem in defining all of the examples in #15 as "Implements callback_form_element_validate() for ...". Here is what I would suggest for the first line in each case:
1) Implements callback_form_element_validate() for #type 'color' elements.
3) Implements callback_form_element_validate() for background color elements.
5) Implements callback_form_element_validate() for the widget's title element.
Does that make sense? I think it gets across in each case what type of data is being validated. Also, somewhere in the function doc, probably there should be an @see to the form generating function or system_element_info() or wherever the validate callback is used. Except I don't think it's necessary in case 5 since this is inside the LinkWidget class. (Also, as a note: I don't think there should be * @see link_field_widget_form() in that last example??)
Comment #18
joachim commented#17 sounds good to me. The docblock following that can explain more, eg:
"This element validate callback is applied to all 'color' type form elements."
I'm not sure what happens if you specify your own in the form builder. Going by form_process_weight() it looks like yours gets zapped.
Comment #19
samhassell commentedCool sounds good. Only thing I am concerned about is the 80 char limit. I was trying to do something similar in one of the earlier patches and needed to deviate from the pattern to fit into 80. Is there any leeway here or should I definitely keep the first line under 80 chars. The docs seem to say it is a hard rule.
Comment #20
jhodgdonThe 80 character limit is a hard rule for any documentation line except an @link...@endlink or within @code...@endcode. I think you'll be OK though.
Comment #21
mile23Just a question about this kind of construct:
What can I substitute for
$this? If it's the name of a class, does it have to be static or does FAPI instantiate one? Do I have to instantiate one, store it on$thisand then sayarray($this->validatorobject, 'validate'),?Sure would be nice for this patch to see the light of day... :-)
Comment #22
heddnI still feel this a novice task, but some issue summary work is needed to pull together a lot of conversations and get a fresh patch rolled.
Comment #23
heddnUn-assigning so others feel like they can work on this.
Comment #24
alvar0hurtad0Working on this
Comment #25
marabak commentedHello
Unassigning alvar0hurtad0 as seen in IRC.
I'll work on it today
Comment #26
JulienD commentedI'm working with Marabak on this issue.
At the moment, the patch in #9 does not apply anymore and most of documentations in the patch doesn't not seem to be relevant anymore. Comments are related to hooks, hooks_alters, callbacks... Now everything have moved to classes, the documentation should be rewritten.
Comment #27
JulienD commentedHere is a patch in order to update validate methods to several form elements.
This patch needs to be continued. It seems there are functions that doesn't exist anymore but I'm not capable to says if it's because I haven't found them or if they have really been removed
Comment #28
joachim commentedThanks for looking at this. As you say, a lot will have changed since the last patch, and I can see it's not been obvious picking this up again!
This I'm afraid is going in the wrong direction:
The point of documenting these as a callback implementation is that we *don't* need to repeat these parameters over and over again. Sorry -- I hope you didn't spend too long copy-pasting these out :(
I'm not sure what the standard is -- or whether there is one -- for callbacks that are methods rather than functions. I suppose in theory we can just document them the same way: the method is still implementing a standard expected parameter signature.
I've updated the summary with the tasks required.
Comment #29
jhodgdonWe don't have a standard for methods vs. functions for callbacks, but I would think we could still document the method signature as a callback function in an api.php file. After all, a method *is* a function.
Comment #30
opdaviesComment #31
mile23Setting to needs review to test the patch in #27.
Comment #32
joachim commentedSee my comment in 28 about the patch in 27.
Comment #33
metzlerd commentedFor me the difference between the methods and functions is the ability to use @inheritdoc? That would suggest that if we're trying to propogate documentation then we would use @inheritdoc to do so for methods where the inheritance chain suggests good docs.
From my perspective the choices should be either an @see for relavent centralized documentation or @inheritdoc when it makes sense or repeat the documentation when there is no good documentaition. Am I missing something here?
Comment #34
joachim commentedThese are implementations of a callback, and so should be marked as 'Implements yadayada'. They're unlikely to inherit from methods in parent classes. In the case that they do, I think they should still be marked as 'implements'.
Comment #35
jhodgdonOK... Here is what I think we should do:
a) If a base class or interface has the callback method on it, I think we should document that method on the base class/interface using our standards for how to document callbacks in api.php files shown here:
https://www.drupal.org/node/1354#callback-def
And then in the extending class, we would just use @inheritdoc for that method.
b) If the base class or interface does not have the callback method on it, then we should document the function in a *.api.php file following the standards on
https://www.drupal.org/node/1354#callback-def
and then the method would be documented using the "Implements callback_foo()" line shown there.
Does that make sense?
Comment #37
colanFor cross-referencing purposes, the change record is Form API now allows for object methods as callbacks.
Comment #39
joachim commented#35 sounds like a good approach.
Comment #40
mradcliffeAdding tag for sprints.
Comment #47
quietone commentedTagging. The patch is adding missing @param documentation for this callback throughout core.
Comment #48
quietone commentedThe patch in #27 needs a reroll. I think this is suitable for a novice, leaving the tag.
When making the reroll remember to help reviewers add an interdiff, or a diff, whichever is appropriate. There are instructions for creating an interdiff .
Comment #49
karishmaamin commentedWorking on it
Comment #50
karishmaamin commentedRe-rolled patch against 9.4.x. Please review
Comment #51
karishmaamin commentedFixed custom command failure
Comment #52
joachim commentedThe patch in #27 didn't need a reroll, it needs work as detailed in #35.
Comment #54
shubham chandra commentedRe-rolled patch against #51 in 9.5.x
Comment #56
pradhumanjain2311 commentedRe-rolled patch against #54 in 10.0.x.
Please review.
Comment #57
anchal_gupta commentedI have fixed CS error. Please review it
Comment #58
Ankit.Gupta commentedReroll the patch #57 with Drupal 10.1.x
Comment #59
gaurav-mathur commentedRe-rolled patch against #57 in 10.1.x-dev
Please review it.
Thank you
Comment #60
imclean commentedThe patches in #57 and #58 are the exact same file. #59 is a reroll with no changes.
Use the "Add test / retest" link to see if it needs a reroll.
Comment #61
smustgrave commentedSeems the issue summary update has not happened yet.
and in #52 it was noted this needs work also
Just FYI to help get the message out there.
Starting March 2023, simple rerolls, rebases, or merges will no longer receive issue credit. Only rerolls that address a merge conflict will be credited, and the merge conflict that was resolved must be documented in the text of an issue comment.
To receive credit for contributing to this issue, assist with other outstanding tasks or unaddressed feedback.
See the issue credit guidelines for more information.