1

I would like to create multiple blocks using the data rendered from the variable table in Drupal 8. I was able to achieve it in Drupal 7, but I can't find a way to do the same in Drupal 8.

The code I use for Drupal 7 is the following.

/**
 * Create a block that will display the calendar feed
 * Implements hook_block_info
 */
function my_module_block_info() {
  $blocks = array();
  $block_urls = variable_get('my_module_content');
  $block_regions = variable_get('my_module_content_block_region');
  $number_of_blocks = count($block_urls);
  if ( $number_of_blocks > 0 ) {
    foreach ( $block_urls as $key => $block_url ) {
      $blocks['eventblock-' . $key] = array(
        'info' => t('my_module_widget_block_' . $key), 
        'status' => TRUE,
        'region' => $block_regions[$key],
        'cache' => DRUPAL_NO_CACHE,
      );
    }
  }
  return $blocks;
}

/**
 * Render the my_module block
 * Implements hook_block_view
 */
function my_module_block_view($delta = '') {
  $block = array();
  $block_urls = variable_get('my_module_content' , array());
    foreach ( $block_urls as $key => $block_url ) {
      switch ($delta) {
        case 'eventblock-' . $key:
          $widgetURL= $block_urls[$key];
          $block['content'] = my_module_content_generate($widgetURL); // Some function to generate block content.
          break;
        }
    }

  return $block;
}
2
  • A bit late, but a not for anyone looking at this. You can use plugin derivates, but there's a very good chance you don't have. Any block plugin can be placed as many times as you want. Instead of derivates, you just add configuration settings to your block and you're done For example in the simplenews module, in 7.x I had to expose a block for each newsletter. In 8.x, I have a single block plugin with a configuration setting to select 1-N newsletters that should be used for it. And now users can create 20 different blocks with that if they want
    – Berdir
    Commented Sep 4, 2018 at 11:45
  • @Berdir Thanks for the answer I was able to create blocks but cant assign a region to the created block programmatically reason is block id is not being generated once blocks are being displayed in the Block UI, Created another question here drupal.stackexchange.com/q/266049 Commented Sep 4, 2018 at 12:07

1 Answer 1

5

In order to create blocks dynamically in Drupal 8, you will have to define a plugin derivative. Plugin Derivatives.

This way you can create multiple instances of the same block. Hope this helps.

Block Derivatives Example

Remember to respect the folder structure when creating your derivative and block class.

Derivative

<?php

namespace Drupal\YOUR_MODULE_NAME\Plugin\Derivative;

use Drupal\Component\Plugin\Derivative\DeriverBase;

class YOUR_DERIVATIVE_NAME extends DeriverBase {

/**
 * {@inheritdoc}
 */
public function getDerivativeDefinitions($base_plugin_definition) {
// @todo might as well include your configuration here and assign a value.
  $block_urls = ['1', '2', '3'];

  foreach ($block_urls as $block_url) {
    $this->derivatives[$block_url] = $base_plugin_definition;
    $this->derivatives[$block_url]['admin_label'] = 'Sample Label ' . $block_url;
  }

  return $this->derivatives;
  }

}

Block

<?php

namespace Drupal\YOUR_MODULE_NAME\Plugin\Block;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Session\AccountInterface;


/**
 * Provides a block.
 *
 * @Block(
 *   id = "YOUR_BLOCK_ID",
 *   admin_label = @Translation("YOUR_BLOCK_ID"),
 *   deriver = "Drupal\YOUR_MODULE_NAME\Plugin\Derivative\YOUR_DERIVATIVE_NAME"
 * )
 */

class YOUR_BLOCK_NAME extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    $id = $this->getDerivativeId();

    $build = [
      '#markup' => $this->t('Your Block Content with ID' . $id),
    ];

    return $build;
  }

  /**
   * {@inheritdoc}
   */
  protected function blockAccess(AccountInterface $account) {
    return AccessResult::allowedIfHasPermission($account, 'access  content');
  }

}

Rename YOUR_MODULE_NAME, YOUR_BLOCK_NAME, YOUR_BLOCK_ID, YOUR_DERIVATIVE_NAME accordingly.

5
  • can you please provide me a working example? Commented Jul 3, 2018 at 13:36
  • I edited my answer. I would strongly recommend doing it yourself and avoid copy/pasting. This will help in a long run. Don't hesitate to ask me if you need any other help. Commented Jul 3, 2018 at 13:58
  • I got a small doubt. How do I assign different block id "YOUR_BLOCK_ID" for different url? In D7 I used to do foreach and used to retrieve unique id based on url for every url. Is it possible to do the same in D8?. And how do I do the same for Block name "YOUR_BLOCK_NAME" ? Commented Jul 3, 2018 at 14:19
  • You just need to specify the array of $block_urls and when you're iterating throughout them in the foreach, $this->derivatives[$block_url] is actually setting an unique ID for the block. YOUR_BLOCK_NAME is just supposed to be the name of the class/plugin. Don't worry and just do it :)) If everything fails, just gimme your email and I'll send you the whole module. Commented Jul 3, 2018 at 14:38
  • Thanks for the Help will try and let you know if it worked. Commented Jul 4, 2018 at 6:27

Your Answer

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

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