8

My module provides a simple block which needs to contain an unordered list with some images. From a block function, I am returning a renderable array:

$block['content'] = array(
    'list' => array(
        '#theme' => 'item_list',
        '#type' => 'ul',
        '#attributes' => array('class' => 'foo1'),
        '#items' => array(
          /* ...  what should go here? */
        ),
    ),
);

I would like to have some renderable arrays as items in the item list, but I seem to be unable to insert any arrays into the #items array.

The Drupal 7 theme_item_list API docs says:

items: An array of items to be displayed in the list. If an item is a string, then it is used as is. If an item is an array, then the "data" element of the array is used as the contents of the list item. If an item is an array with a "children" element, those children are displayed in a nested list. All other elements are treated as attributes of the list item element.

I tried using both "data" and "children" elements, but I get either empty <li>'s or there is a word Array inside them.

What is the proper way to do this? Is theme_item_list the right/up-to-date solution?

1
  • '#items' => array('data' => 'my data') doesn't seem to really do anything more than '#items' => 'my data' (look at the code for theme_item_list). 'children' is used specifically to create a nested list. I'm not sure why it's set up this way.
    – thirdender
    Commented Sep 14, 2014 at 17:49

3 Answers 3

5

Something like this:

foreach ($images as $image) {

  // New array for readability
  $options = array(
    'path' => $image->url,
    'alt' => $image->alt,
  );

  // Push the image tag onto the items array
  $block['content']['list']['#items'][] = theme('image', $options);
}
2
  • 1
    This works and is easier than my answer. The only advantage of my answer is that everything is still in render arrays and can be manipulated by other modules/themes. If that isn't important to you, then this is definitely a good way to go. Commented Sep 7, 2011 at 15:21
  • I have been pondering this solution. As mentioned above, the only issue is not keeping the page structure as a renderable array - if other modules wanted to change the itemes, it would be much harder. But I guess it's good enough :) Thanks! Commented Sep 8, 2011 at 7:35
4

I ran into this exact same problem. From what I can tell reading the source code for theme_item_list() it can't use renderable arrays as items for the list. I ended up passing the renderable array with all the images to my own theme function to output the list. You can basically take your current code and change the #theme property to your custom theme function and add your renderable arrays as children of your list array. To make your function easier, you can add the <li> and </li> tags as #prefix and #suffix respectively to your image render arrays and call drupal_render_children() on your array, then you just wrap it in a <ul> and your good.

0

I'm using following code and it render's the list after an ajax call

$test = array("type"=>"ol","items"=>array('data'=>'1'),'attributes'=>array());
$commands[] = ajax_command_replace('#item-'.$ot->nid,theme_item_list($test));

main difference is the "#", if you read the code of the function at Drupal API function theme_item_list, you'll see there are no hashes for the variables

    function theme_item_list($variables) {
        $items = $variables ['items'];
        $title = $variables ['title'];
        $type = $variables ['type'];
        $attributes = $variables ['attributes'];
    ... }

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.