1

I'm building a site with Drupal and I have a small problem. I'm rendering a form using hook_menu. The form renders fine and all is good. I am then adding some more markup to the page using hook_page_alter(). Hook_page_alter looks like this:

function renderer_page_alter(&$page) {
  if(drupal_is_front_page()) { 
    $q = db_query('SELECT name, mname, number_of_instances FROM {event_type} ORDER BY number_of_instances DESC');
    foreach($q as $event) {
      $options['name'][] = $event->name;
      $options['mname'][] = $event->mname;
    }  
    $tri = array(
      '#theme' => 'frontpage_canvas',
      '#options' => $options
    );
    return $page['content']['triangles'] = $tri;
  }
}

So in my local MAMP install, the content is displayed with the results from hook_page_alter() first then followed by the form. However, in the remote install, the order is reversed (with the submit button for the form at the top of the page and the rest of the content beneath it). The only difference between the installs (that I can think of) is that the remote install is Drupal 7.8 and the local one is Drupal 7.9.

I would like to have the remote install in the same way as the local one. Has anyone come across an issue like this before?

The basic structure of the rendered HTML is like this:

<div class=content>
   //all the form information is in here
</div>
<div class=rendered>
   //all the output from hook_page_alter() is here
</div>

EDIT: The issue is that for some reason, block.tpl.php is adding two divs:

<div id="block-system-main" class="block block-system first last odd">
  <div class="content"> 
     //My form markup is in here
  </div>
</div>
//The hook_page_alter markup is in here.

So, is there any way to force Drupal to add the hook_page_alter markup to the same div as the form is being rendered in? Because the way it's being rendered at the moment, the #weight property doesn't affect the positioning.

Thanks,

1 Answer 1

3

The display order in render arrays is set using the #weight attribute, elements with a higher #weight will be rendered after those with a lower value.

If you want to force the content added in hook_page_alter() to be rendered at the top of the content area declare it like this:

$tri = array(
  '#theme' => 'frontpage_canvas',
  '#options' => $options,
  '#weight' => -1000
);

or at the bottom of the content area:

$tri = array(
  '#theme' => 'frontpage_canvas',
  '#options' => $options,
  '#weight' => 1000
);

You can also adjust the #weight for other elements that already exist in the $page array passed in to the function, so you have total control over the display order.

Sign up to request clarification or add additional context in comments.

6 Comments

The weirdest thing happened. Last night it was all working fine, I woke up this morning and it went back to the submit button being on top. The issue seems to be that, for some reason, the remote install is adding a block to the content region and putting to form in there. The form is being rendered inside <div id="block-system-main" class="block block-system first last odd">. The code is exactly the same but one of the installs is adding that block and the other one isn't. It's weird!
Just a stab...are you logged in to one site and not the other? Or logged in as a different user on one than the other? Also are the themes exactly the same on both installations?
Logged in to both sites as the same user (admin). And yep the themes are exactly the same. Feel free to check out the markup yourself - planb.kerrmarin.co.uk -
Okay... found out what it was... In the blocks section I had the content block to be rendered on all pages except the front page in my local install. So the block-system-main block wasn't being rendered which allowed all the content to be in the same div and therefore the weight works fine. Thanks for your help Clive.
@KerrM: No problem, glad you got it sorted :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.