um, 2-3 issues in one here:

  1. Since comment_form() now supports fields, the comment form is effectively different per node type. Therefore, just like node_form(), the comment form has to be type-specific, but sharing the same form_id.
  2. Since comment forms can be different per node type, themers should be able to style them differently. Quick fix for #theme properties.
  3. Users with 'post comments' permission, but without 'access comments' permission, cannot post comments.
  4. 1) revealed that - for whatever reason - we do not try to add #validate and #submit form handlers for the base form_id of shared form constructors. We also do not invoke hook_form_BASE_FORM_ID_alter().

    Weird enough, this missing piece led to the addition of $form['#node_edit_form'] in node_form(), so that hook_form_alter() implementations can identify more easily whether a form is based on node_form. Yuck! Yes, we really love workarounds for home-grown problems ;)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

sun’s picture

#448132: Comment ACL inconsistency has been marked as duplicate of this issue.

Status: Needs review » Needs work

The last submitted patch, drupal.base-form-id.0.patch, failed testing.

sun’s picture

Status: Needs work » Needs review

drupal.base-form-id.0.patch queued for re-testing.

sun’s picture

FileSize
9.94 KB

Got it. Fixed those failures.

sun’s picture

FileSize
33.21 KB

Cleaned up that weird $form['#node_edit_form'] condition construct used throughout core. Only the indentation of those functions changed, nothing else.

Status: Needs review » Needs work

The last submitted patch, drupal.base-form-id.5.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
33.73 KB

Alrighty, finally figured it out. This #builder_function weirdness will drive me insane one day, likely to happen before we release.

Status: Needs review » Needs work

The last submitted patch, drupal.base-form-id.7.patch, failed testing.

yched’s picture

This #builder_function weirdness will drive me insane one day

:-/.
Note, though, that those lines in node_form_submit_build_node() :

  unset($form_state['submit_handlers']);
  form_execute_handlers('submit', $form, $form_state);

were there in D6 (the function was used for the preview workflow), and were just left as is when Field API introduced the infamous #builder_function. I can't say I ever really understood their purpose...

sun’s picture

Status: Needs work » Needs review
FileSize
34.65 KB

I'd never blame you or anyone else who worked on Fields in core! I just wanted to repeat my doubt that we can release D7 with that weirdness ;)

Let's see what the bot thinks of this one. Not touching the logic in node_form() at all.

Status: Needs review » Needs work

The last submitted patch, drupal.base-form-id.10.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
35.57 KB

VERY interesting findings for node_form_submit_build_node(). Documented in-code.

sun’s picture

Issue tags: +D7 Form API challenge

This kick-started off simple, but should be in the critical task list now.

yched’s picture

re sun #10 - yeah sorry if I sounded defensive, I wasn't ;-).

effulgentsia’s picture

Subscribing.

andypost’s picture

MYMODULE_node_form_submit() is not documented so why this code invoke it?


+  // This form uses button-level submit handlers only, which manually invoke
+  // node_form_submit_build_node(), which in turn executes any form-level submit
+  // handlers prior to invoking node_submit(). For programmatically defined node
+  // types, a TYPE_node_form_submit() handler is therefore expected to be
+  // invoked, if it exists.
+  $form['#validate'][] = 'node_form_validate';
+  $form['#submit'] = array();
+  if (function_exists($node->type . '_node_form_submit')) {
+    $form['#submit'][] = $node->type . '_node_form_submit';
+  }

sun’s picture

It's not MYMODULE_node_form_submit(), but TYPE_node_form_submit().

That is, because the requested $form_id is 'poll_node_form'. Therefore, Form API automatically looks up poll_node_form_validate() and poll_node_form_submit(). This behavior is not changed in this patch and exists at least since D5. But, yes, I was equally not totally aware of that. :)

This patch just automates what had to be done manually before: A shared form constructor had to explicitly define a shared SHAREDFORMID_validate() and SHAREDFORMID_submit() handler, as Form API only looks for handlers explicitly matching the $form_id.

To work around a similar "problem", some genius people thought that it would be a neat idea to introduce a $form['#node_edit_form'] for node_form()'s case, to allow hook_form_alter() implementations of other modules to identify whether a form is a node_form(). In reality, this problem exists for each and every form that uses a shared form constructor callback.

Note that #735800: node form triggers form level submit functions on button level submits, without validation also deals with node_form() and should go in first, as it likely simplifies this patch.

andypost’s picture

@sun I just cares about node-types with names like 'image-gallery' and modules probably could have name TYPE but not define a node type so it lead to unpredictable results.

sun’s picture

@andypost: TYPE in TYPE_node_form refers to the internal machine name of a node type. Those machine names can only contain [a-z0-9_]. This part of Node API is not changed or touched in any way by this patch, and it works that way since D4.7.x.

sun’s picture

FileSize
35.66 KB

Re-rolled against HEAD.

andypost’s picture

Issue tags: -D7 Form API challenge

#20: drupal.base-form-id.20.patch queued for re-testing.

Status: Needs review » Needs work
Issue tags: +D7 Form API challenge

The last submitted patch, drupal.base-form-id.20.patch, failed testing.

effulgentsia’s picture

Status: Needs work » Postponed

As per #17:

Note that #735800: node form triggers form level submit functions on button level submits, without validation also deals with node_form() and should go in first, as it likely simplifies this patch.

effulgentsia’s picture

Status: Postponed » Needs work
sun’s picture

Status: Needs work » Needs review
FileSize
33.48 KB

Let's see.

Status: Needs review » Needs work
Issue tags: -D7 Form API challenge

The last submitted patch, drupal.base-form-id.25.patch, failed testing.

TyraelTLK’s picture

Status: Needs work » Needs review

#25: drupal.base-form-id.25.patch queued for re-testing.

What have I... I'm sorry. Delete this post.

Status: Needs review » Needs work
Issue tags: +D7 Form API challenge

The last submitted patch, drupal.base-form-id.25.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
33.42 KB
sun’s picture

#29: drupal.base-form-id.29.patch queued for re-testing.

sun’s picture

Previous result: PASSED: [[SimpleTest]]: [MySQL] 0 pass(es).

Don't let it fool you.

sun’s picture

Issue tags: -D7 Form API challenge

#29: drupal.base-form-id.29.patch queued for re-testing.

Status: Needs review » Needs work
Issue tags: +D7 Form API challenge

The last submitted patch, drupal.base-form-id.29.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
33.99 KB

Back into business.

Status: Needs review » Needs work

The last submitted patch, drupal.base-form-id.34.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
38.52 KB

I'm a bit stuck here. Only the tests are failing, manual testing (with + without JS) works flawlessly. Don't have a clue why that is.

Also, two rather unrelated issues incorporated now (perhaps ideally 2 split out):

1) Poll choice weights are not taken into account in the poll node form.

2) Poll choices in node form contain a table column "Vote count" (empty), even if the current user is not allowed to enter any.

Status: Needs review » Needs work

The last submitted patch, drupal.base-form-id.36.patch, failed testing.

philbar’s picture

Issue tags: +beta blocker

tag

sun’s picture

Priority: Normal » Major

Absolutely major.

Poll module fixes have been extracted into #445736: Poll does not respect weight in Preview or More button

sun’s picture

Status: Needs work » Needs review
FileSize
39.82 KB

Gotcha.

As identified in the @todo in this patch, node_form() requires some more adjustments for D7. :-|

Regardless of that, this looks quite ready to me.

sun’s picture

FileSize
34.74 KB

De-derailing this issue.

Removed changes covered in #445736: Poll does not respect weight in Preview or More button

sun’s picture

sun’s picture

+++ modules/node/node.pages.inc	23 Jul 2010 10:42:25 -0000
@@ -282,7 +284,16 @@ function node_form($form, &$form_state, 
+  // Unlike others, this form uses a button-level submit handler for the main
+  // action, too. We therefore explicitly define #validate and #submit handlers
+  // to skip any handlers automatically assigned by Form API by default.
+  // Note: hook_form() implementations may have set #submit already.
+  // @todo hook_form() implementations are *unable* to add #validate or #submit
+  //   handlers to the main form buttons above.
   $form['#validate'][] = 'node_form_validate';
+  if (!isset($form['#submit'])) {
+    $form['#submit'] = array();
+  }

+++ modules/poll/poll.module	23 Jul 2010 10:42:25 -0000
@@ -247,7 +247,13 @@ function poll_form($node, &$form_state) 
+  // node_form() uses button-level submit handlers for the main form actions,
+  // which invoke form-level submit handlers, if any are defined. Upon preview
+  // and final submission, we need to renumber poll choices.
+  $form['#submit'] = array('poll_node_form_submit');

The only remaining issue with this patch - which I'd like to move into a separate issue though - is the @todo outlined here: hook_form() implementations of Node API are unable to add #validate and #submit handlers to the main actions/buttons of the node form. Technically, the Node API is invalid - hook_form() would have to get $form + $form_state passed, and the default form elements defined in node_form() should already be contained in $form when hook_form() is invoked.

40 critical left. Go review some!

sun’s picture

sun’s picture

This patch looks RTBC to me.

sun’s picture

#42: drupal.base-form-id.42.patch queued for re-testing.

Status: Needs review » Needs work
Issue tags: +D7 Form API challenge, +beta blocker

The last submitted patch, drupal.base-form-id.42.patch, failed testing.

philbar’s picture

Priority: Major » Critical

Shouldn't this be priority "Critical" since it is a beta blocker?

sun’s picture

I don't care about the priority. This patch needs technical code reviews and has to be committed either way.

webchick’s picture

Priority: Critical » Major
Issue tags: -beta blocker

This looks like a nice code clean-up, but don't see why it should hold up beta. Removing tag.

sun’s picture

Issue tags: +API change

Well, problem space rather being: This is an API change. A required one, as I have at least one contributed module that isn't really able to map its data to now node type specific comment forms. I'm sure there are other modules facing this problem, too.

But anyway, this merely needs final reviews.

@effulgentsia, @fago, @frando, @chx, any chance?

fago’s picture

Generally, a really nice clean-up + fix!

$type . '_comment_form'

I know we use that already for node forms, but this is a dumb way of prefixing. It should be comment_form_$type, only that way we can preserve name clashes. Ideally we should fix that for node forms too. mymodule_node_form is reserved for mymodule, not for the node module.

+  // node_form() uses button-level submit handlers for the main form actions,
+  // which invoke form-level submit handlers, if any are defined. Upon preview
+  // and final submission, we need to renumber poll choices.
+  $form['#submit'] = array('poll_node_form_submit');

Sounds good, but shouldn't we better use $form['#submit'][] instead? Perhaps someone managed to already set that.

Then, if we fix #validate and #submit to take the base form id into account, we also need to fix #theme.

effulgentsia’s picture

Status: Needs work » Needs review
FileSize
34.17 KB

This is a re-roll only. Trying to get a passing patch, then will review.

sun’s picture

FileSize
34.53 KB

re fago #52:

1) Totally agreed on the node form's module namespace violation. That should have been fixed a long time ago already. For D7, I don't know if it's possible to rename Node type form IDs from $type_node_form to node_form_$type, so as to be able to make Comment form IDs consistent, i.e., comment_form_$type. IMHO, we (finally) should. Not even sure whether that actually breaks anything (except of custom modules or themes, perhaps, which should be rare at this stage anyway). I hope that webchick can enlighten us with a yay or nay.

2) Sure thing, no-brainer.

3) I somehow thought that #theme would already take care for it, but it's perfectly possible that I may be mistaken.

Thanks for re-rolling, effulgentsia!

Incorporated 2) + 3).

effulgentsia’s picture

Does this have any dependencies it's waiting on, or can it be reviewed on its own at this point?

ohnobinki’s picture

+1

sun’s picture

Except for the additional node form id namespace clean-up discussed in #52 and #54, this patch is completely self-contained. I.e., the only optional change at this point is the renaming of sub-form ids, so we don't introduce the same namespace violation from Node module in Comment module.

effulgentsia’s picture

Ok, I'll try to review this soon. I would be absolutely +1 for trying to do #798062: Rename TYPE_node_form to node_form_TYPE in D7, but I think that'll be a tough sell to webchick. Regardless, I think we should do comment_TYPE_form and not TYPE_comment_form. TYPE_node_form is wrong. We may have to live with it for one more Drupal version, but we should not feel pressured to propagate the wrongness.

effulgentsia’s picture

Also, I just happened to find #317424: Dynamic form ids for hook_forms, and moved it to D8, but wanted to link to it from here, to hopefully get that one onto people's radar for when D8 work begins.

sun’s picture

FileSize
35.07 KB

webchick bumped #798062: Rename TYPE_node_form to node_form_TYPE to D8.

Therefore, all we can do is to at least don't make Comment module introduce yet another namespace violation.

Status: Needs review » Needs work

The last submitted patch, drupal.base-form-id.60.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
35.21 KB

D'oh, now I get it. Added docs for the default #theme assignment in drupal_build_form().

Status: Needs review » Needs work
Issue tags: -API change, -D7 Form API challenge

The last submitted patch, drupal.base-form-id.62.patch, failed testing.

sun’s picture

Status: Needs work » Needs review

#62: drupal.base-form-id.62.patch queued for re-testing.

Status: Needs review » Needs work
Issue tags: +API change, +D7 Form API challenge

The last submitted patch, drupal.base-form-id.62.patch, failed testing.

effulgentsia’s picture

This is really, really nice! The following nits are pretty minor.

+++ includes/form.inc	1 Sep 2010 17:30:16 -0000
@@ -389,10 +389,12 @@ function drupal_build_form($form_id, &$f
-    drupal_theme_initialize();
-    $registry = theme_get_registry();
-    if (isset($registry[$form_id])) {
-      $form['#theme'] = $form_id;
+    // 'form' itself is a theme wrapper, not a theme function. Therefore, theme
+    // functions only have to care for rendering the inner form elements, not
+    // the form itself.
+    $form['#theme'] = array($form_id);
+    if (isset($form_state['build_info']['base_form_id'])) {
+      $form['#theme'][] = $form_state['build_info']['base_form_id'];
     }

This is the hunk responsible for the test failure. There are form ids for which there are no base form ids, that do not have a theme hook. Or, you can have form ids with a base form id, and neither one has a theme hook. We need to keep the call to theme_get_registry(), or else add a new theme function like theme_form_contents(), or theme_element(), whose implementation is return drupal_render_children($element) to use as a fallback.

+++ includes/theme.inc	1 Sep 2010 17:28:16 -0000
@@ -755,6 +755,14 @@ function theme($hook, $variables = array
+      // Iteratively strip everything after the last '__' delimiter, until an
+      // implementation is found.
+      while ($pos = strrpos($candidate, '__')) {
+        $candidate = substr($candidate, 0, $pos);
+        if (isset($hooks[$candidate])) {
+          break;
+        }
+      }

We don't really need this, do we? When theme() is passed an array, that array should be complete, so the caller can have full control over fallback order.

+++ modules/comment/comment.module	1 Sep 2010 17:28:16 -0000
@@ -1751,7 +1749,19 @@ function comment_get_display_page($cid, 
+function comment_forms() {
+  $forms = array();
+  foreach (node_type_get_types() as $type) {
+    $forms['comment_form__' . $type->type]['callback'] = 'comment_form';
+  }
+  return $forms;

comment_form__TYPE is clever for automatic theme hook fallback, except unnecessary if we set $form['#theme'] to an array, as we already are in this patch. While I like it for consistency with template file naming (i.e., comment-form--article.tpl.php being essentially the same concept as what already exists for node--article.tpl.php), I'm concerned about introducing function names like comment_form__article_validate() or hook_form_comment_form__article_alter(). Maybe in D8, we can standardize on a convention to end the entire function name with __SPECIFIER, but if in D7, we have suffixes like validate(), submit(), and alter(), then perhaps we should keep to single underscore? I lean slightly to comment_article_form(), since I think of 'form' as a kind of suffix (convention only; no magic meaning like validate, submit, and alter), and one that helps avoid name collision should an administrator decide to use 'validate', 'submit', or 'alter' as a node type name. I.e., is comment_form_validate() the form builder for the the comment form on a 'validate' content type, or is it the validate handler for the base form id? I think a form id of 'comment_validate_form' steers clear of collision danger, even if it's a little ugly. Having written that, I really want D8 to move closer to real OOP: I think we're pushing polymorphism via function name creativity to its breaking point.

+++ modules/system/system.api.php	1 Sep 2010 17:28:17 -0000
@@ -1354,6 +1354,40 @@ function hook_form_FORM_ID_alter(&$form,
+ * @param $form
+ *   Nested array of form elements that comprise the form.
+ * @param $form_state
+ *   A keyed array containing the current state of the form.
+ *
+ * @see hook_form_FORM_ID_alter()
+ * @see drupal_prepare_form()
+ */
+function hook_form_BASE_FORM_ID_alter(&$form, &$form_state) {

This can receive a $form_id too, so let's document that. While hook_form_FORM_ID_alter() receives $form_id as well, that's never useful so its okay to omit that from the hook definition, but for this one, I could see a use-case for wanting $form_id.

Powered by Dreditor.

effulgentsia’s picture

+++ modules/poll/poll.module	1 Sep 2010 17:28:17 -0000
@@ -247,7 +247,13 @@ function poll_form($node, &$form_state) 
+  // node_form() uses button-level submit handlers for the main form actions,
+  // which invoke form-level submit handlers, if any are defined. Upon preview
+  // and final submission, we need to renumber poll choices.
+  $form['#submit'][] = 'poll_node_form_submit';

Do we need to introduce this BC break (i.e., a requirement for node modules to explicitly add their submit handler instead of having it be auto-discovered)? Can we instead have node_form() do it?

Yay, poll module, for once again providing a use-case for catching BC breaks :)

Powered by Dreditor.

sun’s picture

1) Dang! And I already looked forward to kill yet another early theme initialization. I'll revert the changes, but keep the comment.

2) Since we revert 1), we can revert that, too. But when reverting, we should move it to a separate issue, because I think that we should support the combination of both, forced suggestions and theme function name patterns.

3) If we don't go with a double underscore, yes, then we have to decide on one of the more problematic names:

- comment_form_TYPE breaks _validate and _submit and any other auto-suggested suffix.

- comment_TYPE_form potentially breaks any contributed add-on modules, i.e., where TYPE == anything && comment_TYPE == module name.

- TYPE_comment_form entirely violates module namespaces, just like Node module.

I don't think that comment_form__TYPE is really problematic. Instead, it rather adds consistency, and it entirely avoids all aforementioned namespace issues.

In the end, I'd rather use the double underscore instead of introducing any namespace problems. Even if that means that comment_form form_ids may change in D8 or later on. That's still better than potentially violating other/existing namespaces now.

I disagree that usage of OOP resolves anything here. OOP gets extremely ugly when trying to apply Drupal's modularity. The same likely applies to PHP's new namespaces. Instead, for D8 or beyond, we want to introduce double underscores as a new standard to cleanly separate parts in function names; e.g., MODULE__EXPOSINGMODULE__HOOK(), or similar. TBD.

4) Good catch on the missing $form_id argument in the docs. Will add that.

5) While we could try to automatically add hook_TYPE_node_form_submit() handlers, I'm not sure whether we should. Technically, Node API only contains hook_form(), hook_validate(), and hook_submit(). If we would add auto-suggestion support for hook_TYPE_node_form_submit(), then I'd ask you why there is no auto-suggestion for hook_TYPE_node_form_validate() - and that never was auto-suggested. So this issue boils down to the question why Poll module implements hook_TYPE_node_form_submit() instead of hook_submit() in the first place. I'm highly opposed to add any auto-suggestion magic for regular form validation/submit handlers.

Thoughts?

sun’s picture

Status: Needs work » Needs review
FileSize
35.12 KB

Incorporating #66 - #68.

effulgentsia’s picture

Status: Needs review » Needs work

Thanks. I agree with #68.3.

I'm still not sure about #68.5. Just to be clear, we're not talking about hooks, we're talking about FORM_ID_submit() and BASE_FORM_ID_submit(). These are auto-suggested by default for all forms with the former taking precedence over the latter, unless the form builder function explicitly sets its own #validate and #submit. Now, in HEAD, node_form() does not set $form['#submit'], and therefore, poll_node_form_submit gets auto-discovered because $form_id = 'poll_node_form'. This patch adds $form['#submit'] = array() to node_form(), because you want to stop form.inc from auto-setting it to node_form_submit should $form_id . '_submit' not be there. But, why not have it to do $form['#submit'] = function_exists($form_id . '_submit') ? array($form_id . '_submit') : array() instead? Wouldn't that be backwards compatible with HEAD, and remove the need for the poll.module hunk in this patch?

I agree that the cognitive disconnect involved in node_form_validate() being the form-level handler, node_form_submit() being a button-level handler, and TYPE_node_form_submit() being a form-level handler is a WTF. But it's what we have, because we didn't manage to remove this legacy WTF from D7. Do we really want to open that can of worms in this issue though?

Other than above, this looks ready to me. Another review from fago, and perhaps a test, would be nice.

effulgentsia’s picture

Status change in #70 wasn't intentional. My suggestion in #70 is just a suggestion, and is open to debate.

sun’s picture

Status: Needs work » Needs review
FileSize
37.01 KB

While your explanation in #70 makes sense, I rather meant the following point:

Considering a custom module node type "foo" (like poll)

- you cannot add a foo_node_form_validate() and expect that to be invoked, because node_form() manually sets a #validate, so Form API does not auto-suggest any further validation handlers.

- by coincidence, you were able to just add a foo_node_form_submit(), but only just because node_form() only manually sets a #validate, but no #submit.

Clarified the comments in node_form() based on this discussion.

Note that I'm not totally opposed to manually auto-suggesting a TYPE_node_form_submit handler in node_form(), but well, it just does not make any sense for me, because we'd only auto-suggest #submit, but not #validate.

Btw, in Poll module's case, it's entirely not clear to me why it is implementing TYPE_node_form_submit() in the first place instead of hook_submit() of Node API. Attached patch fixes that.

#WTF

It seems we mistakenly lost Node API's hook_submit() somewhere along the road in D7. http://api.drupal.org/api/function/hook_validate/7 still exists, but hook_submit() is gone.

Only hook_node_submit() remained, but that hook is invoked for all nodes, regardless of node type.

Status: Needs review » Needs work

The last submitted patch, drupal.base-form-id.72.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
36.98 KB

ok. Discussed this in length with effulgentsia. All lessons learned should be contained in code comments now.

sun’s picture

FileSize
36.71 KB

Fixed that auto-suggested #submit handler logic.

effulgentsia’s picture

Status: Needs review » Reviewed & tested by the community

This looks great. Summary:

1) Review this patch in context, rather than just reading it: most of the +/- signs are just big blocks of code being out-dented via removal of an if condition.

2) There is no BC break in here, except the one that is the purpose of the issue: the automatic calling of hook_form_BASE_FORM_ID_alter() between hook_form_alter() and hook_form_FORM_ID_alter(), and the fallback to BASE_FORM_ID_(submit|validate)() if FORM_ID_(submit|validate)() doesn't exist (and if the form doesn't explicitly set #validate/#submit). While this is a theoretical BC break for modules that implement hook_forms() without wanting this behavior, it is much more likely for this behavior to be desired than undesired. Furthermore, since we have not yet fixed #766146: Support multiple forms with same $form_id on the same page, and may not in D7, this patch allows modules that need multiples instances of the same base form to coexist on a page (e.g., multiple "add to cart" buttons within an e-commerce site) to be implemented much easier than the hacks currently being done in the d6 versions of those modules.

3) The per-type comment form control made possible by this patch is a great use-case to demonstrate the value of the patch, and is an excellent, non-bc-breaking addition to comment.module.

4) The non-bc-breaking replacement of an if statement for #node_edit_form, with a hook_node_form_alter() is a really nice cleanup.

rfay’s picture

subscribe

effulgentsia’s picture

Status: Reviewed & tested by the community » Needs work
+++ includes/form.inc	4 Sep 2010 00:16:55 -0000
@@ -389,6 +389,9 @@ function drupal_build_form($form_id, &$f
   if (!isset($form['#theme'])) {
+    // theme_form() itself is in #theme_wrappers and not #theme. Therefore, the
+    // #theme function only has to care for rendering the inner form elements,
+    // not the form itself.
     drupal_theme_initialize();
     $registry = theme_get_registry();
     if (isset($registry[$form_id])) {

Oops. Sorry. I missed this in my #76 review. We need to add elseif(isset($registry[BASE_FORM_ID])) at the bottom of this. Otherwise, comment-form.tpl.php will no longer be used if it exists in the theme, and that's a regression relative to head. I suggest elseif rather than making #theme an array, since you already have $registry.

Powered by Dreditor.

sun’s picture

Status: Needs work » Needs review
FileSize
36.98 KB

d'oh, sorry, yes, this was contained earlier already but got lost somehow during the re-rolls since #30 or so. Fixed.

effulgentsia’s picture

Status: Needs review » Reviewed & tested by the community

thanks

fago’s picture

Wow, great improvements! However I don't like the comment_form__TYPE naming thing - function names like comment_form__article_alter() are *really* ugly and a major WTF. From the above examples I like comment_article_form most too as the _form suffix is already common.

For that - I'm not sure about how to deal with the problem of possible conflicting module names with type names, but strictly speeking comment module has already claimed comment_*. Thus module comment_FOO already violates the namespace - so it is up to the module to avoid conflicts with the comment module. Anyway, avoiding that scenario is preferable.

So what about introducing another prefix to the node type for the form ids? We can stick with "comment_form" as base form id and use "comment_node_TYPE_form"?

effulgentsia’s picture

Status: Reviewed & tested by the community » Needs review

So what about introducing another prefix to the node type for the form ids? We can stick with "comment_form" as base form id and use "comment_node_TYPE_form"?

+1. Setting to "needs review" rather than "needs work" in case sun wants to argue against it. But I like this because "comment_node_TYPE" is the bundle name as per comment_entity_info(). Also, I've been thinking that we will need a contrib module that allows comments to be attached to other entity types, not just nodes, so this leaves room for that.

sun’s picture

FileSize
38.15 KB

Hm. Ok, but I disagree with comment_node_TYPE_form. Sub-IDs of whatever kind should always be suffixes to the original type. Otherwise, there are many more potential namespace conflicts.

Therefore, I went with comment_form_node_TYPE. And made #theme consistent accordingly, except for cases where a regular theme function sub-pattern (e.g., comment__node_TYPE) is required.

sun’s picture

That was one replacement too much.

effulgentsia’s picture

This works for me if it works for fago.

Additionally, since for comments specifically, we have comment__node_TYPE and comment_wrapper__node_TYPE for theme hook names, we could have comment_form() set #theme to 'comment_form__node_TYPE' if that exists in the registry. So we can continue to follow the __ pattern for theme hook names, where that pattern is consistent, while keeping the FAPI functions 'alter', 'validate', 'submit', and the builder callback, all using single underscore.

effulgentsia’s picture

Sorry, one more comment about this. Are we concerned about a site having one node type named "Foo" and another node type named "Foo Submit", such that a function comment_form_node_foo_submit() would run as both the submit handler for the comment form on a 'foo' node, and as the form builder function for the comment form on a 'foo_submit' node? This same problem exists with #79, but can be solved by fago's suggestion in #81 (though maybe #81 comes with its own risks).

sun’s picture

FileSize
37.86 KB

We don't care for #86.

Attached patch makes comment form use #theme comment_form__node_TYPE, i.e., the regular theme sub-pattern behavior.

fago’s picture

@ a) comment_form_node_TYPE vs. b) comment_node_TYPE_form:

1. Resulting function names:

comment_form_node_article_validate()
hook_form_comment_form_node_article_alter()

vs

comment_node_article_form_validate()
hook_form_comment_node_article_form_alter()

I'd prefer the second as a _form suffix is already commonly used and makes it more clear that associated handlers/hooks deal about a form as it leads to suffixes like form_alter(), form_validate(), form_submit().

2. Possible collisions:

As noted for a) we have the possible collision of type names and builder function for TYPE + TYPE_(submit|validate) - which is rather weird as the user could trigger that just by configuration. For b) the only collision I can see is a possible module called "comment_node_TYPE" implementing the form comment_node_TYPE_form - but with the 'node' prefix I'd say we are on the safe side here.

Consequently I'd prefer comment_node_TYPE_form - thus always keeping _form at the end of the form id. I do not feel very strong about that, but I think it is the better way to go.

sun’s picture

Honestly, I don't care which variant we choose. @effulgentsia, can you post your feedback and opinion on #88, please? I'll just do what's required to get this in then, if anything.

effulgentsia’s picture

+++ modules/comment/comment.module	6 Sep 2010 23:55:36 -0000
@@ -1787,6 +1797,11 @@ function comment_form($form, &$form_stat
+  $form['#theme'] = 'comment_form__node_' . $node->type;

This is triggering watchdogs. For now, we need to wrap this in a theme registry check the way form.inc does it. Separately, I'll open an issue for us to register theme implementations of 'comment_form', 'node_form', and other core forms.

Re #88: I don't really care all that much either, and I see pros and cons each way, but I slightly agree with fago. What I don't like about fago's preference is that you lose the ability to grep for 'comment_form' and catch everything, but I agree with fago in thinking about 'form' as a kind of suffix by convention, and it does seem more protected from namespace collision. As long as we're setting #theme the way we are in comment_form(), then ultimately, I'm fine with either.

sun’s picture

FileSize
37.88 KB

This is triggering watchdogs. For now, we need to wrap this in a theme registry check the way form.inc does it. Separately, I'll open an issue for us to register theme implementations of 'comment_form', 'node_form', and other core forms.

I don't think there should be default implementations for these theme functions. I'd expect no watchdog messages when changing the assignment to an array (containing just one element). I.e., a watchdog would be valid if I want a certain theme function. But when only passing suggestions, then there should be no watchdog messages. If that is not the case yet, then that needs to be fixed in a separate issue, yes.

This is interesting. Normally, we do not set #theme for forms. IIRC, we (I?) skipped this entire problem by removing the #theme definition in node_form() entirely. However, in most cases it makes sense to define theme suggestions - although that shouldn't necessarily mean we have to register and implement a totally useless default theme function.

sun’s picture

FileSize
37.87 KB

Dang. Forgot comment.pages.inc.

sun’s picture

Any feedback?

effulgentsia’s picture

Status: Needs review » Needs work
+++ modules/comment/comment.module	7 Sep 2010 16:01:44 -0000
@@ -1787,6 +1797,11 @@ function comment_form($form, &$form_stat
+  $form['#theme'] = array('comment_form__node_' . $node->type, 'comment_form');

Sorry. Been short on time. But this is 99% done, so let's finish it. This is still triggering a watchdog, so I don't think it should land as-is. I honestly don't know why theme() triggers watchdogs when a theme key isn't found, especially since drupal_render() is perfectly capable of defaulting to a reasonable implementation (i.e., drupal_render_children()) when theme() returns an empty string. I agree that getting consensus on that is for a separate issue, but my initial feeling is that it should not depend on whether #theme is a string or an array, but rather on whether theme() is called for a render array or not. Alternatively, perhaps allowing #theme to be an array whose last entry is NULL might be a way of indicating that hey, these are all just suggestions, don't panic if none of them are implemented.

Anyway, assuming we don't want to bog down this issue with changes to theme() or drupal_render() let's just add the registry check to comment_form(), or perhaps have drupal_build_form() remove $form['#theme'] if its entries are not implemented, since it already has the registry, so we can avoid polluting comment.module with a theme_get_registry() call. In any case, I think it's better to have some workaround like that until we fix theme() or drupal_render() than it is to try to convince Dries or webchick to commit a patch that is triggering unnecessary watchdogs.

Other than that, I think this patch is ready to go.

webchick’s picture

That watchdog stuff was added for DX, to avoid the situation where you call theme('fooo', $bar, $baz); where the theme function is actually called theme_foo() and get absolutely nothing back. See #412730: Theme system should optionally report when a theme key is not found.

sun’s picture

Status: Needs work » Needs review
FileSize
38.57 KB

ok, let's fix #theme suggestions in a separate issue. Attached patch implements effulgentsia's suggestion in #94, i.e., checking #theme for all forms, since we have the registry anyway.

Status: Needs review » Needs work

The last submitted patch, drupal.base-form-id.96.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
39.18 KB

meh.

Status: Needs review » Needs work

The last submitted patch, drupal.base-form-id.98.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
38.64 KB

Welcome to 100. :)

Dries’s picture

Status: Needs review » Fixed

Reviewed once more. Committed to CVS HEAD.

sun’s picture

Status: Fixed » Needs work
Issue tags: +Needs documentation

Needs documentation in the module upgrade docs.

effulgentsia’s picture

Priority: Major » Normal

Thanks Dries! Now that all that remains is documentation, no longer "major" (sorry webchick, i can sense you cringing at that).

webchick’s picture

RAWR! ;)

sun’s picture

Status: Fixed » Closed (fixed)
Issue tags: -API change, -D7 Form API challenge

Automatically closed -- issue fixed for 2 weeks with no activity.