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
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 = explode("<p>", 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("<p>", 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("<p>", $content_array);
As you notice, I used the same selector (
"<p>") 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:
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 for Drupal.org. It is currently in my sandbox and awaiting review to be promoted to a full project.
Hope this helps.