0

I have a lateral section which will be different for every page in my site, but the content is practically unaltered for every single page.

I had the intention of using hook_block_view_alter. I would create an empty block in the region, and would fill the content dinamically with PHP in a hook in a custom module.

Will the content be cached or should I better create different blocks for every single page and change the content only if the content changes?

4

hook_block_view_alter() isn't going to affect the cache settings for the block automatically, though you can find a way if you really want to as Molot points out below; typically you use hook_block_info_alter() to change the cache settings for a block:

function mymodule_block_info_alter(&$blocks, $theme, $code_blocks) {
  $blocks['block']['my_block_id']['cache'] = DRUPAL_CACHE_PER_PAGE;
}

Here, DRUPAL_CACHE_PER_PAGE will cache your block for each page, which could be quite a bit better than not caching at all and creating the content dynamically for each page. If you need dynamic content every time, choose DRUPAL_NO_CACHE. Clear the block cache to make Drupal aware of your new settings.

But! If you are prepared to have a custom module to run alter hooks, consider writing a block from scratch. If you are going to have a custom block, I feel that it helps if it is impossible to accidentally delete in the Drupal UI.

To implement a basic block you need hook_block_info and hook_block_view.

hook_block_info is where you tell Drupal that the block exists and how to cache it:

function mymodule_block_info() {
  $blocks['myblock'] = array(
    'info' => t('My Awesome Block'),
    'cache' => DRUPAL_CACHE_PER_PAGE,
  );
  return $blocks;
}

Next, hook_block_view does the work of generating the content. I find that assigning the content to a callback makes my code easier to read, but do what works for you. Using switch() makes it easy to add more blocks to your module later on.

function mymodule_block_view($delta='') {
  $block = array();

  switch ($delta) {

    case 'myblock':
      $block['subject'] = t('My awesome block');
      $block['content'] = mymodule_some_function_to_build_the_block_content();
      break;

  }

  return $block;
}
  • It is a really detailed reply. Thank you very much. I was able to create a new block and assign it to a region with the IU. However, I found 2 problems: 1st was that the cache was not used, because I had the restriction: "Block caching is inactive because you have enabled modules defining content access restrictions." I was able to override this by configuring settings.php uncommenting the line: $conf['block_cache_bypass_node_grants'] = TRUE; The second problem I am investigating, is that the block is rendered in memory even if the region is not called. Maybe with a rule in template.tpl.php. – Cesar Dec 24 '14 at 8:57
  • Do you mean that you are rendering regions conditionally within your theme templates? I think a more typical approach is to always render the regions but to include the blocks conditionally, e.g. with the Context module or the basic block configuration in core. – calebtr Dec 24 '14 at 10:10
  • Yes, I make as you say, I had deleted the block programmaticaly (erasing the code in hook_block_info) and I forgot to select the pages where to display the block. I avoid logic in the template as much as I can, only for doing 'theme_hook_suggestion' and views_embed_view (I don't want to use Context or Panels modules). – Cesar Dec 24 '14 at 10:14
  • Actually I believe you can do things that break cache in hook_block_view_alter(). The point is, it shouldn't be done that way, not that it can't. +1 from me, I just wanted to clarify it a bit, that's all. – Mołot Dec 24 '14 at 10:26
  • @Cesar, I don't understand the situation where a "region is not called". When does this happen? – calebtr Dec 24 '14 at 18:12

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.