How to insert a block or a region in the middle of Drupal node content

The solution for Drupal 7.10:

/** in template.php **/

function THEME_preprocess_node(&$variables) {

//load your adblock
$adblock = block_load('block', '1');
$output .= drupal_render(_block_get_renderable_array(_block_render_blocks(array($adblock))));
$variables['ad'] = $output;
/** in node.tpl.php **/

$array = explode("", $body[0]['value']);
$array[1] = $ad. $array[1];
$content['body'] = implode("", $array);
print render($content['body']);

Inserting Adsense Into Content - Drupal 6.X

For Drupal 6.x, the process is a bit simpler than in Drupal 5.x. First, you'll want to define a new region for your Adsense "in body" code in your theme's .info file. Beneath your defined regions, add a line that defines your new region (if there are no regions, make sure you redefine all your regions (left, right, header, etc.) or they will disappear):

regions[left] = Left
regions[right] = Right
regions[header] = Header
regions[incontent] = In Content

Next, we expose this region variable to your node template file. Simply add the following to your theme's template.php file:

function theme_name_preprocess_node(&$vars, $hook) {
// don't load region in teaser view
if ($hook == 'node' && !$vars['teaser']) {
$vars['incontent'] = theme('blocks', 'incontent');

Make sure you replace theme_name with the folder (directory) name of your theme. The preprocess_node statement tells the function that we're addressing your node.tpl.php file.

Finally, the last step is to insert code in your node.tpl.php file that will actually insert the new ad region into the middle of your content:

$arr = explode ("", $content); // center content ads
$arr[2] = $incontent . $arr[2];
$content = implode("", $arr);

Important: This code snippet needs to be inserted before

print $content

What this does is simply insert the content of your incontent block after the second paragraph printed by your node.tpl.php file. So in effect, by assigning an Adsense block to your incontent block, your ads will be inserted after the second paragraph within your body content. To adjust the number of paragraphs used for insertion, simply adjust the 2 in the second line of the example above.

The only remaining step, to make this all work, is to actually assign an Adsense block to your new incontent region. Before you do this, you need to clear the theme cache, which will cause the changes you made to your .info file (the newly defined regions) to load. To do so, simply visit your theme select/ configuration page (via Administer -> Site Building -> Themes). If for some reason you get the message, when visiting your block page, that your blocks were disabled since they were assigned to invalid regions - don't panic, simply confirm that you have all your regions in place in your .info theme file, and then clear your theme cache as described above.

The code from your link is:

$array = explode("", $body[0]['value']);
$array[1] = $ad. $array[1];
$content['body'] = implode("", $array);
print render($content['body']);

That looks like it should work, except I can't figure out why it's providing a blank delimiter for explode() . What if you ran explode and implode with the first parameter set to ""?



Have you ever wondered how you can get a block to display smack down in the middle of your Body content? Say you write articles and these get displayed like normally in the Content region. You can add blocks to regions around it but only if your theme has them declared or if you did that yourself in the template of with Display Suite. And the cat is cute.

What you cannot so easily do is have a block displayed on each Article node in the middle of your Body. Not even with Display Suite. If you know a little .php however, it is not so difficult. And of course if the node.tpl.php file does not scare you.

This is what I did for my Article Content Type. I created a dedicated node.tpl.php file for the Article Content Type by copying node.tpl.php and renaming the new file node--article.tpl.php. You can do this also for you Page Content Type and any other you may have - in the same naming style.

I searched for the following .php line print render($content); and commented it out. Note that this line outputs the Body field of all the Article nodes on your site. If you comment it out on your production website, none of your Article nodes will have any Body fields till you are finished with this entire process. So make sure you work first in your development environment, perform adequate testing there and then make all the changes at once.

Next, I added a new region to my theme called new-region (Of course change the name to whatever you want).

The reason I did this is so that I can create a block of content in the Drupal UI and assign it to this region. This will in turn be called with .php in the middle of the Article Body fields. So after this, I went back to my article--note.tpl.php and declared a new variable ($added_string) containing said call for the region:

$added_string = render(block_get_blocks_by_region('new-region'));

Next, I used a .php command to break up the render version of the $content variable (which holds the Body text). Seeing that this text is mostly a sequence of paragraphs, I broke it up at each paragraph and stored all the resulting pieces in the array named $content_array:

$content_array = explode("", render($content));

UPDATE: Here if you have more fields in your content type and you want to add your block in the middle of the body field - which is expected to be simple html - you should explode only the specific body array element, like so:

$content_array = explode("", render($content['body']));

OK, so what I wanted to do is have the block display roughly in the middle of the Body field. It is difficult to be precise given that you cannot break up the $content variable exactly in the middle. The .php command above, however, created an array with a number of elements (and since we used the paragraph as the separator) we can also deduce that $content_array is now an array of all the paragraphs in the Body.

Now, we find out how many paragraphs it has and divide that number in 2 to figure out where we want to insert the block content (after how many paragraphs). For this you can also set a number of your own, but in my case I wanted the block to be more or less in the middle, no matter how long the Article content got:

$content_array_half_size = count($content_array) / 2;

The above command retrieved the half of the total number of items (paragraphs) in the array and stored that number in the variable called $content_array_half_size. Next, I used another command to insert the region I wanted (now found in the variable $added_string) into the Body array ($content_array) placing it after the item that equals to the number representing half of the total items:

array_splice($content_array, $content_array_half_size, 0, $added_string);

And finally, I needed to recreate the string to be outputted as the Body field because currently $content_array is an array which holds a number of paragraphs - with the block included in the middle:

$final_content = implode("", $content_array);

As you notice, I used the same selector ("") as criterion to implode the array elements. And now the $final_content variable holds a big string with our Body and block in the middle of it. All we need to do is print it out:

print $final_content;

OK, so after saving this file and adding your block to that region in your Drupal administration interface, you can test. If you are satisfied, you can go ahead and implement these changes on your production site.

You could of course not use a block as a content holder to be placed in the middle of the Body. You can hardcode in the node--article.tpl.php file the $added_string to whatever you want. But using a block in a region gives you then the opportunity to always return to the Drupal UI to show/hide that block based on various dependencies: page, role, or even add more blocks to that region. Also, you can use the Context module to disable the region itself etc. And that is cool.

Based on this concept, I wrote a module now hosted on

Hope this helps.

Danny Sipos, a Drupal enthusiast and developer from Brussels

Add new comment

Filtered HTML

  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <pre>
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.