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;
}
  • 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 Sep 4 '18 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 – miststudent2011 Sep 4 '18 at 12:07
4

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.

| improve this answer | |
  • can you please provide me a working example? – miststudent2011 Jul 3 '18 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. – Postovan Dumitru Jul 3 '18 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" ? – miststudent2011 Jul 3 '18 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. – Postovan Dumitru Jul 3 '18 at 14:38
  • Thanks for the Help will try and let you know if it worked. – miststudent2011 Jul 4 '18 at 6:27

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.