The site's header banner is displayed using a custom block containing an image. Is it possible to create a default block which will return visibility = TRUE only in the case that there are no other blocks which are visible in the header region for the page currently being rendered? In other words, can a PHP-code visibility test access the list of blocks which will be rendered in the block's region? If not, how can this functionality be implemented?
1 Answer
There is a function that returns the list of the blocks available in a region, but it cannot be invoked from the PHP code used to establish the visibility of a block as it would probably cause a recursive call.
Looking at the code of block_list(), you can write the visibility code for your block. What you need to change is the query that obtains the list of all the blocks to exclude the block for which you are writing the visibility code.
The actual query executed by the function is the following:
$result = db_query(db_rewrite_sql("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.theme = '%s' AND b.status = 1 AND (r.rid IN (" . db_placeholders($rids) . ") OR r.rid IS NULL) ORDER BY b.region, b.weight, b.module", 'b', 'bid'), array_merge(array($theme_key), $rids));
The function code requires you know the region in which the block is visible; if you move the block in a different region, then you need to change the code used to test the block visibility accordingly.
In Drupal 7, a module can implement hook_block_list_alter() to alter the list of visible blocks.
Act on blocks prior to rendering.
This hook allows you to add, remove or modify blocks in the block list. The block list contains the block definitions, not the rendered blocks. The blocks are rendered after the modules have had a chance to manipulate the block list.
You can also set
$block->content
here, which will override the content of the block and preventhook_block_view()
from running.