Hello there

I've tried to print a block using $block = module_invoke("block", "block_view", 6); , but this returns a simple array with ['subject'] and ['content'] as keys, what I want to get is a standard themed block, I mean its final markup, so if I print it inside content's region and I am admin, I get the "configure this block" button as I get when I position it inside a region using block's panel.

In Drupal 6 it was just by using theme('block',$block), but when I try the same I get many warning saying theme function expected many more keys, in addition it expects an object instead an array, I tried doing a cast (object)$block but still doesn't work.

Do you know any way I can solve this? I mean, how can I get a rendered (html) block programatically as regions do when printing page.tpl.php?

Thank you in advance =)

Comments

cesarpo’s picture

I did something like this:

// delta now is a String, the id of the block, not a number.
$block = module_invoke('module', 'block_view', 'delta');    
$rendered_block = theme('block', $block);
pakogax’s picture

Thank you for your help, but is what I explain in my post and page crashes. I used to work in Drupal 6 but I am using Drupal 7. Does it work for you in drupal 7?

tuongaz’s picture

Try this for Drupal 7:

$block = block_load($module,$delta);
$renderable_block=  _block_get_renderable_array(_block_render_blocks(array($block)));
lorinpda’s picture

Hi,
First I would highly recommend you get a copy of the "Examples for Developers" located here: http://drupal.org/project/examples. The "render example" is loaded with great information.

I took look at the Drupal 7 block.module listing and came up with this:

function print_block_test($region = 'sidebar_first', $block_id = 58) {

  $renderable_block = t('Block Not Found');
  $output = '';
  
  $block_list = block_list($region);

  foreach($block_list as $block) {
   if ($block->bid == $block_id) {
      $renderable_block=  _block_get_renderable_array(array($block));
      $output = drupal_render($renderable_block);
      break;
   }
  }

  return $output;
}

So, in my example you need to supply the region name and then the bid (block id field located in the block database table). The documentation for hook_page_alter() http://api.drupal.org/api/drupal/modules--system--system.api.php/functio... describes the default Drupal 7 region names.

The "render example" ( "Examples for Developers") demonstrates how you can iterate through the regions of a given page.

Note! Since this method was intended for educational purposes only, I looked at one of my development installations. 58 happens to be the block id (bid) for the "Search" block. It's for demonstration purposes only. :) So in other words, look at your own installation and determine the block id (bid) for whatever block you are trying to render.

Sample use: You can call the above function as a menu callback (hook_menu()). The block found is rendered in the content region.

I hope that helps.

robinrew’s picture

Yea i had a bit of a head scratch over this one.... module_invoke is one of those indispensable drupal functions.

The drupal 6 method below applied to the webform module block:

<?php 
         $block =  module_invoke('webform', 'block', 'view', 'client-block-11'); 
         print $block['content']; 
  ?>

The answer is directly under are noses as it turns out, everything in drupal 7 is now stored to the last point in a render array, and therefore you just have to render out the array...

<?php
          $block = module_invoke('webform', 'block_view', 'client-block-11');
          print render($block); 
?>

You can obtain the block information by going to 'Administer -> Site building -> blocks' for drupal 6 or 'structure -> blocks' for drupal 7 and hit 'configure' next to the block to check its url.

drupal 7 url for block = admin/structure/block/manage/webform/client-block-11/configure
drupal 6 url to block = admin/build/block/configure/webform/client-block-11

Needless to say, but for the new.. don't forget to have the 'text format' on 'php code' when implementing the php code in your node. This can be turned on in the module page.

hope this helps.

Firemyst’s picture

This worked for me. The confusing point was that the new modules have no IDs at all, even at the end. Maybe they do if they are inherited from a Drupal 6 install, but otherwise they are just names, and work exactly as described here.

marcopanichi’s picture

...block created in a view?

achaux’s picture

This did not work for me, but print render($block['content']) did work:

$block = module_invoke('block', 'block_view', 'client-block-11');
print render($block['content']);
maggie_au’s picture

Yes, print render($block['content']); works for me
Thank you so much for letting us know~

longtom’s picture

Would you mind taking a step back and defining the files into which I place this code, and any functions I need to embed it in? Currently, I am trying to clone a module block, and have the code sitting in my custom module, but it is doing almost nothing.

here is my code
$block = module_invoke('module_name', 'block_view', 'block_name');
print render($block);

So far, this (ie my attempt), apparently, apparently is a good example of how not to do it.

UPDATE

The code

$block = module_invoke('module_name', 'block_view', 'block_name');

can be placed in a custom module, into a hook_block_view function.

longtom’s picture

-

Khetam’s picture

This worked for me.
Thanks.

keithm’s picture

None of the above approaches completely worked for me. Here's mine:

/**
 * Get a block suitable for rendering.
 * Note: the block does not have to be enabled in $region.
 * @see includes/block.module/_block_render_blocks()
 * @see includes/block.module/_block_get_renderable_array()
 */
function siteoverride_embed_block($module, $delta, $region='content') {
  // Create block stub.
  $block = new stdClass();
  $block->module = $module;
  $block->delta = $delta;
  $block->region = $region;
  // Load title.
  global $theme_key;
  drupal_theme_initialize();
  $block1 = db_query("SELECT title FROM {block} WHERE module = :module AND delta = :delta AND theme = :theme",
                    array(':module' => $module, ':delta' => $delta, ':theme' => $theme_key))->fetchObject();
  if (is_object($block1) && isset($block1->title)) {
    $block->title = $block1->title;
  }
  // Render the content and subject for the block.
  $blocks = _block_render_blocks(array($block));
  // Get an array of blocks suitable for drupal_render().
  $array = _block_get_renderable_array($blocks);
  return $array;
}

Then, if your module is 'block' and delta is '1', write in your template file:

print render(siteoverride_embed_block('block', '1'));

jlyon’s picture

Thanks, keithm. Worked for me!

kerios83’s picture

THX @robinrew I have spending 2 hours searching for this !

pionplus’s picture

thanks for great code....but i`m newbe and i don`t understand where to put block identity (block title or other) in the code. and i don`t know where to put `second` code in template. i` using D7.4 and Analityc theme...

cheers
pionplus

andsigno82’s picture

Works like a charm! It has also theming calls!

Thanks
Thanks
Thanks

mattez’s picture

I found this

$block = block_load('block', '1');
$output = drupal_render(_block_get_renderable_array(_block_render_blocks(array($block))));
print $output;

(here: http://api.drupal.org/api/drupal/includes--module.inc/function/module_in...)
This only works form me...

dswans’s picture

Had no trouble with this in drupal 6. Have spent hours on this, running through every possible example and combination, nothing has worked except this. (Still cant get it to work for views).
Your code is amazing.

ghan’s picture

Mattez, this code works for me (rendering a block in a view tpl, D7). Thanks!

apprayo’s picture

Thanks!

texis’s picture

Unfortunately - I've tried all mentioned here but I almost always get the following error:

Notice: Trying to get property of non-object in function block_block_view() (line: 245 in file /users/zalohovane/zusorchidea.com/test/modules/block/block.module).

T

prasannah.ganeshan’s picture

In your webform advanced settings you can save a webform as a block. Did anyone try this for a change. For me I had the same issues. Tried it with views and all the jazz. Finally this was right under my eyes I had not noticed it.

Let me know if this works for you.

Cheer,
Prasannah

arulan_pari’s picture

$block = block_load('block', '1');
$output =_block_get_renderable_array(_block_render_blocks(array($block)));
$output = drupal_render($output);
print $output;

rahulshah_1988’s picture

Hi,

As I said I have 2 separate things one is a view and other one is block. I just want to wrap them up and display them together. Any idea how can I accomplish that?

I started with one block inside another block using all of the techniques of using module_invoke but not able to get it working.

Please help.

Thanks in advance.
Rahul

Robar’s picture

I couldn't get the code here to work for me, I suspect that I just couldn't find the right parameters. So, my solution, which I am sure someone more knowledgeable will explain to me why you shouldn't do this, is to place the block into a clean region and copy the HTML from the generated 'view source' of the webpage and place that into the div I want in content. Seems to work????

Rohan

vensires’s picture

That's understandable Rohan but then what's the reason of using a block and not plain HTML? If the client or another developer changes the block from the UI, the copy of the block is expected to get changed too. If this doesn't happen, you misuse the block module. There are some cases it might be acceptable but never welcomed.

P3Hosting’s picture

I am relatively new to Drupal, and have spent several hours figuring out how to do this as there was no one place it was all documented.

givens:
Drupal 7.23
You wish to display a view in your content.
modules>core>php filter is enabled and permissions are set to allow you to inject php code into your content.
You have created your block and view

To locate the name of the block to be displayed
Structure>Blocks
Find your block in the list and click on the configure option
Then in your browsers address bar you will see something like the following:
YourDomain.tld/content/town#overlay=admin/structure/block/manage/views/intownshow-block/configure

The information between '/views/' and '/configure' is the name of your view or it's delta (I believe that is the correct term) or in this case 'intownshow-block'.

Now go to the content you wish to place the block in and edit it using the “PHP Code” in the text format dropdown.

Insert the following were you wish your block to appear in your content:

<?php

$block = block_load('views', 'intownshow-block');
print drupal_render(_block_get_renderable_array(_block_render_blocks(array($block))));

?>

Note there is a space between 'print' and 'drupal_render...' in the above

Then save the edited content and view it should work.

vensires’s picture

Wouldn't it be simpler if you just used the following code in your case?

  print views_embed_view('intownshop', 'block');
osman’s picture

There is a (more) up-to-date documentation for embedding block content to any template.

Placing the contents of a block in any location
https://www.drupal.org/node/26502

osman

easwari’s picture

module_invoke didn't work for me and I had to use block_load but where delta is the machine name and not the block id. 

$my_block = block_load('my_module_name', 'delta');
$block_for_display = drupal_render(_block_get_renderable_array(_block_render_blocks(array($my_block))));

Within my_module, I had hook_block_view and another function prepare the block content for rendering as shown in this example:
https://api.drupal.org/api/examples/block_example!block_example.module/7...

function my_module_block_view($delta ='') {
    $block = '';
    switch ($delta) {
        case 'blockA':
            $block['content'] = my_module_contents($delta);
            break;
    }
    return $block;
}

function my_module_contents($which_block) {
    switch ($which_block) {
        case 'blockA':
            $content = array(
                '#markup' => variable_get('some_field'),
            );
            return $content;
    }
}