Attached path makes text fields with the 'formatted_text' setting use D7's'#text_format' selector instead of a standalone filter_form().
Comes with tests.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

yched’s picture

A change from a different patch sneaked in the previous one.

David_Rothstein’s picture

This looks good on a first glance... no time to review it carefully now, so mostly just subscribing :)

It seems like a bit of a shame that text_field_widget_validate() is needed - it looks like a hack, but I guess it's required with the way that core is doing things now (appending '_format' to the end of the string to match a field to its text format, etc).

bjaspan’s picture

Priority: Normal » Critical
sime’s picture

I'd prefer if the direction was to use a normal FAPI textfield for this stuff, with some custom altering based on widget type, rather than the way cck has always done it by defining it's own widgets. The reason for this is constant frustration with custom widgets that do not implement the properties and behaviors common and useful in their generic widget cousins.

So in this case are we not just adding one of these perfectly functional features of textfield to text_textfield and text_textarea??

Forgive me if I'm out of my head. I wouldn't try this review if I wasn't at Drupalcon!

Footnote: I haven't been in this area of the code for a while, but the $filter_key stuff is not intuitive, along with what looks like hard-coding of the column where we expect the filter_key to be ($filter_key = (count($element['#columns']) == 2) ? $element['#columns'][1] : 'format';). Admittedly that was not added by this patch, but the patch makes it more glaring.

yched’s picture

re #4: those comments are not relevant to this specific patch. Widgets implemented as specific form 'elements', potentially reusable in non-CCK forms, was done in CCK D6. I'm not sure I remember all the reasons off-hand, and returning to a more classic FAPI implementation might possibly be discussed. But this should happen in a separate thread and definitely not hold on this patch, which just makes the current code inline with the new D7 construct for input formats.

yched’s picture

Anyone ? This is simple and straightforward, no real reason to have this languish, AFAICT...

KarenS’s picture

yched, I'm rolling this fix into #372743: Body and teaser as fields, since that won't work without this change and making body fields into textfields is going to change all this code anyway.

yched’s picture

Sure, why not - but we could as well commit it as is, just needs someone to mark it RTBC ;-)

KarenS’s picture

Status: Needs review » Reviewed & tested by the community

I tried this out and think it is RTBC. I will incorporate these changes in to the other patch, but this one doesn't need to wait on that.

sun’s picture

Status: Reviewed & tested by the community » Needs work
+ * Extract the input format into the expected 'format' value.

It is called text format now.

+  $filter_key  = (count($element['#columns']) == 2) ? $element['#columns'][1] : 'format';

Double space. Also, braces should wrap the entire statement, not just the condition.

Even after reading the code multiple times, I have no real clue what text_field_widget_validate() really does and why.

David_Rothstein’s picture

Also, one more minor thing - in the tests, the messages that get printed (for example ''Widget is displayed') are not wrapped in t().

KarenS’s picture

The text field has two columns, 'value', and 'format'. The selected format has to be pulled out of the filter form so that it will be stored with the text value. Yve's code does that during the validation step. It has to be re-named because the filter code creates a new form element and names it 'value_format' and we are storing the selected format in the field as 'format'. We often use the 'validation' step to do post-processing like this since it's the easiest place to alter the values before they are saved.

yched’s picture

Will reroll shortly for the remarks above.

yched’s picture

@sun #10
(count($element['#columns']) == 2) ? $element['#columns'][1] : 'format';
"braces should wrap the entire statement, not just the condition. "

Sounds odd, and I cannot find where is this stated. Do you have a link or something ?

yched’s picture

Updated patch :
- Adressed comments above (except sun's remark about braces around conditionl expressions, which I can't see applied in the rest of core)
- Better code comments about why text_field_widget_validate() is needed. I also tried to use a #value_callback instead of a form_set_values() in validate, but it turns out to be impossible because of form processing order.
- Fixed the bug mentioned in http://drupal.org/node/372743#comment-1388568.
Relies on a needed fix for filter_form() - patch in #411596: filter format form when only 1 format available.

Since all concerns raised since the last RTBC are adressed, setting back to RTBC

yched’s picture

Status: Needs work » Reviewed & tested by the community
sun’s picture

Status: Reviewed & tested by the community » Postponed

Sorry, but after a second thought and backtalk to chx, I don't think this is the proper solution. In almost all cases, form_set_value() is a hack, or a prove of a poor API.

What we really need is: #text_format should optionally allow to accept an array, passed on as arguments to filter_form().

That's a separate issue (which doesn't exist yet AFAIK). Thus, marking this one as postponed.

yched’s picture

Status: Postponed » Reviewed & tested by the community

I don't agree. I strongly suggest we commit this now and revisit when that other issue - not yet created - lands...
The code in this patch is correct and harmless. It *could* be better if the feature it reiies on was more flexible, but pretty please let's not block #372743: Body and teaser as fields and other important followups (#409750: Overhaul and extend node build modes...).

sun’s picture

The point is: This hack cannot be discovered easily, because we're introducing an additional element validation function to make the actual functionality work as it should. If we commit this now, I _seriously_ predict we will have this hack until Drupal 8. Because neither you or someone else will care, once Field API works as intended. This hack is unacceptable and developers will suffer from it. If this patch gets committed anyway, this issue deserves nothing else than the Hall Of Shame tag.

yched’s picture

I feel this is taking a somewhat dramatic turn... The fields code still has a number of TODOs, which are slowly being striked out. We can add a TODO note to revisit this when a patch for form_process_text_format() lands (I created #412016: Custom key name for #text_format. for this). I suspect this might take some discussion and a few iterations.
Again, there's a patch congestion around fields API, let's not add to this by postponing over details on other APIs.

Status: Reviewed & tested by the community » Needs work

The last submitted patch failed testing.

yched’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
7.28 KB

Rerolled.

Damien Tournoud’s picture

Status: Reviewed & tested by the community » Postponed

This should use a proper API, and #text_format is not. Conclusion: it is still too early for that. Let's postpone in favor of #414424: Introduce Form API #type 'text_format'.

Damien Tournoud’s picture

Status: Postponed » Needs work

After discussion on #drupal, I believe that this is the way to go.

Except that I believe this is *not* a temporary solution: there is no need at all for form values to map directly to field storage. On the contrary, this is generally not true. We should remove references to #412016: Custom key name for #text_format. inside this patch.

Damien Tournoud’s picture

Oh, and that conversion between form values <=> data storage should probably be done in a #process function of the widget, not in a #validate function.

yched’s picture

#process uses $edit. $edit doesn't contain values for '#type = value' elements. filter_form() currently uses a 'value' when only one format is available.
That's why #value_callback didn't work, btw.

Sun tells me that the latest patch in #304330: Text format widget removes the use of 'value', though.

yched’s picture

Status: Needs work » Needs review
FileSize
7.62 KB

Updated patch. The changes that went in #304330: Text format widget now let us do the job in a #value_callback instead of a form_set_value() in #element_validate.
Also contains the fix for #423308: Textarea widget broken (missing return in text_textarea_process()) and comes with tests for both widgets.

Status: Needs review » Needs work

The last submitted patch failed testing.

yched’s picture

Status: Needs work » Needs review

"Failed to install HEAD" - works fine on my setup, requiering retest.

yched’s picture

Damien Tournoud’s picture

Status: Needs review » Reviewed & tested by the community

Obviously, this is not perfect, because we still need to think about a more generic solution (see #414424: Introduce Form API #type 'text_format'). But it at least harmonize text fields with all other core text widgets, which is important at this point.

sun’s picture

Status: Reviewed & tested by the community » Needs work

Looks much, much better now. Some minor nitpicks only:

 /**
+ * Helper function to determine the value for a formatted text widget.

Albeit this is a yet-undocumented FAPI feature, let's be more precise here:
"Form element value handler to determine the value of a formatted text widget."

+ * '#text_format' puts the format in '[column 0]_format' in incoming values,
+ * while we need it in '[column 1]'.

..." or 'format' (the default)".

To get this in, we need a new critical issue for documenting #value_callback.

sun’s picture

Meh. I forgot one issue:

+function text_field_widget_formatted_text_value($form, $edit = FALSE) {

Albeit _form_builder_handle_input_element() uses $form as argument, $element is what is passed in reality, because form_builder() invokes _form_builder_handle_input_element() and form_builder() invokes itself recursively.

yched’s picture

The params and PHPdoc for text_field_widget_formatted_text_value() are directly taken from form.inc's value callbacks :

/**
 * Helper function to determine the value for a checkbox form element.
 *
 * @param $form
 *   The form element whose value is being populated.
 * @param $edit
 *   The incoming POST data to populate the form element. If this is FALSE,
 *   the element's default value should be returned.
 * @return
 *   The data that will appear in the $form_state['values'] collection
 *   for this element. Return nothing to use the default.
 */
function form_type_checkbox_value($form, $edit = FALSE) {
  ...
}

I will reroll for the remark about ''[column 1]", but for the rest, I'd suggest committing the current, and fixing the existing core value callbacks consistently if it considered necessary ?

yched’s picture

Status: Needs work » Reviewed & tested by the community

Rerolled for the '[column 0]' / '[column 1]' PHPdoc bit sun mentioned in #32.
The other remarks should go in a 'document #value_callback / fix signature of existing core implementations' issue, IMO. Created #447930: #value_callback documentation and signature (D7) for this.

sun’s picture

Thanks!

Yes, probably it's RTBC, but it seems your attachment didn't make it.

yched’s picture

Oops. Thks sun.

Dries’s picture

text_field_widget_formatted_text_value seems to be a hack. We might be able to avoid that if we did #414424: Introduce Form API #type 'text_format' first.

Status: Reviewed & tested by the community » Needs work

The last submitted patch failed testing.

yched’s picture

Status: Needs work » Reviewed & tested by the community

Rerolled.

I missed comment #38 somehow. Dries : This has been discussed before. text_field_widget_formatted_text_value() is not a hack, it's translating form values structure into storage structure. As Damien wrote in #24, there's no reason to expect or enforce that both structures match, and a value_callback is a valid way to do that. Somewhere else in core, you'd do that in a _submit handler, field widgets cant use that and rely on FAPI callbacks.

#414424: Introduce Form API #type 'text_format' is still highly hypothetical, and it's been pointed several times that making all core formatted textareas consistently use the current official D7 construct (#text_format) will make enriching / moving away from it easier.

I'm a little puzzled at how complex it is to get this fairly simple patch in :-/

bjaspan’s picture

Status: Reviewed & tested by the community » Needs work

yched: you forgot the patch, so it "needs work" :-).

yched’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
5.22 KB

Doh... Here's the patch.

yched’s picture

Status: Reviewed & tested by the community » Needs work

Let's hold this. While working on the last test failures in #372743: Body and teaser as fields I noticed a few hiccups when the user only has access to one input format - raises notices on preview. Investigating.

Will teach me to rant about patches that take too long to get in, I guess :-(

yched’s picture

Status: Needs work » Needs review
FileSize
5.41 KB

So the issue was that when the current user only has access to one format, the format selector is hidden with '#access' = FALSE, and FAPI then doesn't make the format value available in our #value_callback. Saved format was then 0, while node body, for example, receives the actual format (which is necessarily the current default format) in its submit handler.
Storing 0 is no good because, although *at display time* it gets interpreted as 'the default format', it might be a different format than when the node was edited.
This also caused notices on preview.

Attached patch fixes this by explicitly saving the default format if no format value is available.
I'm aware it's not helping Dries to not consider text_field_widget_formatted_text_value() as a hack :-(.
The only alternate solution I see in a foreseeable future is #412016: Custom key name for #text_format..

Status: Needs review » Needs work

The last submitted patch failed testing.

yched’s picture

Status: Needs work » Fixed

This got committed along with #372743: Body and teaser as fields

Status: Fixed » Closed (fixed)

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