1

I have a page with the following structure:

  • Header zone

    • Header One Area (block)
  • Content zone

    • Content Area (node)

The rendered node has an image attached to it. What I need to have happen is to make the attached image render inside the "Header One Area" block instead of as part of the content.

This is proving difficult, since blocks and their #markup are rendered before a node is processed. The better idea I had is to create a preprocess function for the page, through code figure out the node_id being rendered, grab its images, and then dynamically modify the blocks markup.

I have tried creating a MYTHEME_preprocess_page() method inside my template.php and then accessing the block via:

if ($block = block_get_blocks_by_region('header_one_area')) {
   // what code do I need here to make a #markup modification stick ???
   $block['block_4']['#markup'] = "<h2>TEST</h2>";
   print kpr($block);
}

I'm not quite sure how to actually modify its markup dynamically before it is rendered here.

Do you have any suggestion?

7

I think you are looking for hook_block_view_alter(). It provides both the alterable $data, as well as $block, which contains the module and delta.

To determine which blocks are available, you could start off with:

function MYTHEME_block_view_alter(&$data, $block) {
  kpr($block->module);
  kpr($block->delta);
}

Then once you find the module:

/**
 * Implements hook_block_view_alter().
 */
function YOURTHEME_block_view_alter(&$data, $block) {
  if ($block->module == 'block' && $block->delta == 1) {
    $data['content'] = '<p>New content</p>';
  }
}

Or even:

/**
 * Implements hook_block_view_MODULE_DELTA_alter().
 */
function YOURTHEME_block_view_block_4_alter(&$data, $block) {
  $data['content'] = '<p>New content</p>';
}
|improve this answer|||||
  • 1
    Thanks Tim! This is a good solution and noted for future reference! My requirements though brought another solution over at the drupal.org boards. All I had to do was create a Views Block, unformatted field displaying the image with a Contextual Filter set to Content:Nid based on the Content URL ID. Thanks for the response! – skålfyfan Sep 8 '11 at 0:55
  • This is wrong, $data['content'] needs to be array and not html api.drupal.org/api/drupal/modules!block!block.api.php/function/… – Marko Blazekovic Jan 17 '17 at 13:18
  • 2
    @MarkoBlazekovic you are mistaken. It says right on that page under $data: > content: Either a string or a renderable array representing the content of the block. – tim.plunkett Jan 23 '17 at 14:34
0

if you can delegate the changes to the browser client, you can use Jquery to manipulate the html. See this functions (with examples) to manipulate (change/move/detach/attach/etc) your html http://api.jquery.com/category/manipulation/

http://www.w3schools.com/jquery/jquery_html.asp is another interesting resource.

here is one example to move one html element inside other (in this example the div with id="one" will be inserted inside div id="six"using the appendTo() Jquery method):

<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    $("div#one").appendTo("div#six");
});
</script>
</head>
<body>
<div id="one"><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/FullMoon2010.jpg/200px-FullMoon2010.jpg"></div>
<div id="two">text</div>
<table border=1><tr><td>
<div id="six">text</div>
</td></tr></table>
</body>
</html>

note that you can use jquery in the header (like previous example) to put inside your page.tpl.php or you can use jquery after render your html target:

<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
</head>
<body>
<div id="one"><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/FullMoon2010.jpg/200px-FullMoon2010.jpg"></div>
<div id="two">text</div>
<table border=1><tr><td>
<div id="six">text</div>
</td></tr></table>
<script type="text/javascript">

    $("div#one").appendTo("div#six");

</script>
</body>
</html>
|improve this answer|||||
  • 1
    -1 for linking to w3fools, -1 for suggesting altering output with JS. – tim.plunkett Sep 7 '11 at 20:49
  • Hello Tim, why linking to w3schools.com is an -1 and why use Jquery methods designed to alter html is -1? this can not be an alternative?. – cigotete Sep 7 '11 at 20:54
  • w3fools.com, and because you should use the right tool for every job. When preventing the HTML from ever being generated is so straightforward given the right function, why waste the time having PHP generate it, and then jQuery go through and process it? – tim.plunkett Sep 7 '11 at 22:11
  • Hello Tim, I agree with use the best alternatives, also I agree in try to make this from the backend, but if an user do not know how to use/get the best, maybe you will be useful to know other possibility. I am offering a possible alternative if the user can not achive the best alternative. – cigotete Sep 7 '11 at 22:51
0

The accepted answer will overwrite the block's content altogether. #prefix and #suffix can be used to add markup to the block before or after the content.

function mymodule_block_view_alter(&$data, $block) {
  $data['content']['#prefix'] = '<div class="my-class">';
  $data['content']['#suffix'] = '</div>';
}

The #prefix and #suffix will be honoured for any Drupal render array when it's passed through render() (or drupal_render()).

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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