16

Given this renderable array:

$output = array(
    'twitter-icon' => array(
      '#type' => 'markup',
      '#markup' => '<div class="twitter-icon"></div>'
    ),
    'twitter-link' => array(
      '#type' => 'markup',
      '#markup' => l('follow us on Twitter', 'https://twitter.com/#!/zujava'),
    ), 
  );

How do I wrap both of these elements in a single DIV?

3 Answers 3

34

You can also use the #container form element, and code similar to the following one:

$wrapper = array(
  '#type' => 'container',
  '#attributes' => array(
    'class' => array('class-name'),
  ),
);

$wrapper['twitter-icon'] => array(
  '#type' => 'markup',
  '#markup' => '<div class="twitter-icon"></div>'
);

$wrapper['twitter-link'] => array(
  '#type' => 'markup',
  '#markup' => l(t('follow us on Twitter'), 'https://twitter.com/#!/zujava'),
); 

The #container element wraps its children elements with a <div> tag, whose CSS class is the one passed in the #attributes property.

You could even use a container for the "twitter-icon" element, but that doesn't give you any pro, except in the case you could possibly add an element to that, as with the following code:

$wrapper = array(
  '#type' => 'container',
  '#attributes' => array(
    'class' => array('class-name'),
  ),
);

$wrapper['twitter-icon'] => array(
  '#type' => 'container',
  '#attributes' => array(
    'class' => array('twitter-icon'),
  ),
);

if ($condition) {
  $wrapper['twitter-icon']['twitter-icon-text'] => array(
    '#type' => 'markup',
    '#markup' => t('Icon text'),
  );
}

$wrapper['twitter-link'] => array(
  '#type' => 'markup',
  '#markup' => l(t('follow us on Twitter'), 'https://twitter.com/#!/zujava'),
); 
2
  • To me this is the best answer, as it uses the physical array structure to represent what is being wrapped, will copy and paste better (moving an element in @ninjascorner answer could break the opening/closing DIVs), and doesn't require extra theme functions. Thanks!
    – Justin
    Dec 6, 2011 at 15:07
  • That is correct: You can add another element that is rendered in the same container, without moving the #suffix property from the last element, or the #prefix property from the first element, to the new added element. As you said, this is less error-prone.
    – apaderno
    Dec 6, 2011 at 15:12
7

Is this what are you looking for?

$output = array(
    'twitter-icon' => array(
      '#type' => 'markup',
      '#markup' => '<div class="twitter-icon"></div>'
      '#prefix' => '<div class="test">',
    ),
    'twitter-link' => array(
      '#type' => 'markup',
      '#markup' => l('follow us on Twitter', 'https://twitter.com/#!/fdgf'),
      '#suffix' => '</div>',
    ), 
);

Hope that helps!

5
  • @nija +1ed, Great answer I had forgotten those attributes. Please read my answer, can this be achieved through theming based alternative to your suffix and prefix. Dec 6, 2011 at 4:43
  • @stefgosselin, you mean you want to create a tpl file to theme it? Dec 6, 2011 at 5:05
  • Thanks for this answer. I knew how to do this on one element, but it didn't occur to me split up the suffix and prefix. Interesting. It feels messy to me, but I can't articulate why so I can't really have an issue.
    – Justin
    Dec 6, 2011 at 15:05
  • @ninjascorner Sorry for the delay, I could not find the note I had on this subject. There is also I think a way possible less elegant than other answers, usable in theme or module that is using the theme hook theme_render_example_add_div See api.drupal.org/api/examples/…) Dec 7, 2011 at 3:42
  • This is only good if you're super sure that both elements will always get rendered. It is easy to end up with unclosed <div> when splitting like this.
    – kufeiko
    Jun 13, 2018 at 10:46
2

You also can create a theme for this.

$form['twitter']['#theme'] = 'my_twitter_theme';

$form['twitter']['icon'] = array(
'twitter-icon' => array(
  '#type' => 'markup',
  '#markup' => '<div class="twitter-icon"></div>'
);

$form['twitter']['link'] = array(
  '#type' => 'markup',
  '#markup' => l('follow us on Twitter', 'https://twitter.com/#!/zujava'),
);

And in your theme hook:

function my_hook_theme(){
  return array(
    'my_twitter_theme' => array('form' => NULL)
  );
} 

And in the theme function:

function theme_my_twitter_theme($form){
  $output = "";

  $output .= "<div class=\"twitter\">";
  $output .= drupal_render($form['icon']);
  $output .= drupal_render($form['link']);
  $output .= "</div>";    

  $output .= drupal_render($form);
  return $output;
}

I use this in Drupal 6, i'm not sure if works also in D7 but i hope so

1
  • Yes, I figured this method out after posting (well, I copies the examples module). It works great, but I don't consider it the best method because (if I understand correctly), you have to put your class name in the function, reduces it's reusability.
    – Justin
    Dec 6, 2011 at 15:04

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.