When placing prefixes on forms via $form['#prefix'] the content is placed outside the entire form block and floats in the region. This content should be outside the form but inside the block.

(Specifically working with the user_register form.)

Comments

iLLin’s picture

Project: Form Block » Drupal core
Version: 7.x-1.x-dev » 7.x-dev
Component: Code » forms system
Priority: Normal » Major

I can confirm this with a custom block to and it only happens when you are logged out. Logged in it works as its intended. This is most likely a core bug. Moving there.

iLLin’s picture

Priority: Major » Normal
iLLin’s picture

More information:

Standard block template with form #prefix/#suffix added when logged in:

  <div id="myblock-id">
    <h2>Subject</h2>
    <div class="content">
       <div id="prefix">Prefix Markup</div>
       <form>Form Stuff</form>
       <div id="suffix">Suffix Markup</div>
     </div>
  </div>

Same block form output when logged out:

  <div id="prefix">Prefix Markup</div>
  <div id="myblock-id">
    <h2>Subject</h2>
    <div class="content">
       <form>Form Stuff</form>
     </div>
  </div>
  <div id="suffix">Suffix Markup</div>

For some reason the prefix/suffix are added outside the block id when not logged in.

doublejosh’s picture

As a working around, in my form_alters I've started to put the form suffix on the submit element.
Also placed my form prefix on the first fieldset.

muri’s picture

Form prefix and suffix properties are for wrapping form items. Rather than above you can wrap like

$form['element'] = array(
  '#type' => 'textfield', 
  '#prefix' =>'<div id="prefix">',
  '#suffix' => '</div>',
);

This will produce

<div id="prefix"><!--prefix-->
  <div class="form-item form-type-textfield form-item-element">
    <input type="text" class="form-text" maxlength="128" size="60" value="" name="element" id="edit-element">
  </div>
</div><!--suffix-->
doublejosh’s picture

What's the preferred form prefix/suffix then? Perhaps #type = '#markup' ...something like this:

$form['form_prefix'] = array(
  '#markup' => t('My message.'),
);
$form['form_suffix'] = array(
  '#markup' => t('My details.'),
);
foopang’s picture

Status: Active » Needs review
StatusFileSize
new513 bytes

Hi, I found the bug in _block_get_renderable_array() function,
In line 337, the block content is put on the top level of the renderable array:

$build[$key] = $block->content;

And in line 353, the block theme wrapper callback is directly added to the renderable array, any #prefix and #suffix elements will be placed after all theme wrappers of the block content have been rendered, so they are placed outside the block.

To fix this problem, we can just put the block content into a child element of the renderable array in line 337:

$build[$key]['content'] = $block->content;

I've created a patch for this issue, please kindly test!

smira’s picture

smira’s picture

requested a re-test since is seems like the block module has changed quite a bit this past week!

kolier’s picture

#7 works on 7.23.

Anonymous’s picture

checked ok for #dcprague sprint, still needs further review

reecemarsland’s picture

Status: Needs review » Reviewed & tested by the community

#7 works for 7.x-dev.

Tested both logged in and logged out forms and both prefix and suffix.

k.skarlatos’s picture

Steps to reproduce

  1. Fresh install Drupal
  2. Install and enable form block module
  3. Custom block with a form works fine
  4. Block enabled with form block fails
k.skarlatos’s picture

Applied #7 using steps in #13 and works as intended.

yurg’s picture

#7 works for me perfectly, save a lot of headaches.

yurg’s picture

Issue summary: View changes

note

joekrukosky’s picture

#7 worked for me as well but if you don't wish to patch core, I got a neat work around from BTMindgrub. Simply render the form in the block:

<?php

  $form = drupal_get_form('my_form_id');
  $output = render($form);
  return $output;

?>
swim’s picture

Issue summary: View changes

I had to apply this patch (#7) to a number of 7.23 sites and it worked fine across all of them. Thank you @foopang =).

When can we expect to see this committed to core? I'm amazed more people have not encountered this issue.

star-szr’s picture

Version: 7.x-dev » 8.x-dev
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs backport to D7

If this is an issue in 8.x as well it needs to be fixed there per the backport policy.

Can we please test this on 8.x? If it's fixed for 8.x then the issue can go back to 7.x and have the 'needs backport to D7' tag removed.

star-szr’s picture

Issue tags: +Needs manual testing

This can theoretically be tested using the steps in #13 and the 8.x version of https://drupal.org/project/formblock.

lokapujya’s picture

i just noticed this problem in my own custom D7 code. Although I'd like to fix it, what could this potentially break in existing D7 modules?

lokapujya’s picture

Status: Needs work » Needs review
StatusFileSize
new603 bytes
lokapujya’s picture

Version: 8.0.x-dev » 7.x-dev

If you look at the D8 search box markup with that patch, you will see that the prefix is inside the block.

lokapujya’s picture

This would need automated tests too. But fixing it would break sites that are relying on the current behavior, so we would need a pretty good change notice too. How do we handle this situation?

garbo’s picture

A simple solution to this is when you write mymodule_block_view() you put the form in a sub-array within $block['content'] like this:

$block['content'] = array('form' => drupal_get_form('mymodule_my_form'));
lokapujya’s picture

Issue tags: -Needs backport to D7
muri’s picture

I think the form always needs to be rendered before assigned to $block objects content. As $block core below doesn't accept any content if it is not rendered.

if (is_string($block->content)) {
          $block->content = array('#markup' => $block->content);
        }

As in #16 therefore it should be as below with drupal_render(). Thanks joekrukosky!

$form = drupal_get_form('my_form_id');
  $output = drupal_render($form);
  return $output;
jeroent’s picture

Thanks @garbo,
#24 was the solution for my problem.

Status: Needs review » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.