8

I am trying to alter a custom module block, without success. My block class is the following.

class BreadcrumbBlock extends BlockBase {

public function build() {
    return [
        '#theme' => 'breadcrumb_block',
        '#content' => array('value' => 1),
        '#cache' => array(
                'contexts' => array('url'),
        ),
    ];
 }
 .....

In hook_block_view_alter() where can I alter the block? Where are $data['subject'] and $data['content'] in a block?

4
  • Why are you trying to alter your custom block?
    – Eyal
    Commented Sep 24, 2016 at 22:01
  • Because has dynamic content according to modules.
    – user7011
    Commented Sep 28, 2016 at 11:43
  • It's a custom block, you have all the power. You don't need alter functions.
    – Eyal
    Commented Sep 28, 2016 at 16:57
  • You don't need to use pre render hooks, you have the render function.
    – Eyal
    Commented Sep 28, 2016 at 16:58

3 Answers 3

6

I think you must use a 'pre_render'. Some thing like : http://www.drupal8.ovh/en/tutoriels/150/change-drupal-8-powered-by-block

use Drupal\Core\Render\Markup;

function yourmodule_block_view_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
  if ($block->getBaseId() === 'system_powered_by_block') {
    $build['#pre_render'][] = '_yourmodule_block_poweredby_prerender';
  }
}

function _yourmodule_block_poweredby_prerender(array $build) {
    $build['content']['#markup'] = Markup::create('Your text');
    return $build;
}
1
  • 1
    But this is not working for custom block types. Even I'm not getting base id of custom block types in this hook.
    – Cool
    Commented Aug 18, 2017 at 13:49
5

Another method which can be used to alter any block without additional #pre_render callback. Note that custom callback function is called after the system Drupal\block\BlockViewBuilder::preRender() and may be not rendered properly. For example, if you add content to an empty block using the method from the above comment then the title of the block will be lost.

Go to the src folder in your module and create OverrideAnyBlockContent.php file with the following content:

<?php

namespace Drupal\YOUR_MODULE;

/**
 * Helper class to override any block content in a HOOK_block_view_alter().
 */
class OverrideAnyBlockContent {

  /**
   * The render array.
   *
   * @var array
   * @see https://www.drupal.org/docs/8/api/render-api/render-arrays
   */
  protected $renderArray;

  public function __construct(array $render_array) {
    $this->renderArray = $render_array;
  }

  public function getPlugin() {
    return $this;
  }

  public function build() {
    return $this->renderArray;
  }

}

Then in YOUR_MODULE.module file:

function YOUR_MODULE_block_view_alter(array &$build, Drupal\Core\Block\BlockPluginInterface $block) {
if ($block->getBaseId() === 'system_powered_by_block') {
    // @see https://www.drupal.org/docs/8/api/render-api/render-arrays
    $render_array = [
      '#type' => 'markup',
      '#markup' => "Any text, HTML, {$php_variable}, whatever, ....",
    ];

    // Uncomment the line below if you need to merge new render array with the
    // original one.
    // $render_array += $build['#block']->getPlugin()->build();

    // Now block will be pre-rendered using new render array. No additional
    // '#pre_render' callback is required.
    // @see Drupal\block\BlockViewBuilder::preRender()
    $build['#block'] = new Drupal\YOUR_MODULE\OverrideAnyBlockContent($render_array);
  }
}

Taken from examples module issue: https://www.drupal.org/node/2893964

1

The simpliest way would be to use a preprocess hook like so:

function MODULE_OR_THEME_NAME_preprocess_block__BLOCK_ID(&$variables, $hook) {
   // block render array is here to be altered => $variables['content']
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.