Skip to main content

Blog Post

Drupal 8: How to Reference a Views' Block Display from a Field

by Michelle Cox
January 25, 2017

In Drupal 7, if you wanted to reference a view display from a node field, you had to use a module such as Viewfield. In Drupal 8, this can be done with Drupal core alone by using the built in entity reference to reference a block instance created from the view.

Step 1: Create a hidden region in your theme.

  1. Open your THEMENAME.info.yml file
  2. Find the section for "regions:"
  3. Add a new line: hidden: 'Hidden region for referenced blocks'
    Hidden region
  4. Save and clear the cache.

Step 2: Create a view with a block display.

  1. Go to admin/structure/views/add
  2. Create your view with a block display.
    Block Display
  3. Do any additional tweaking you'd like and save the view.

Step 3: Place an instance of the block in the hidden region.

  1. Go to admin/structure/block
  2. Find the hidden region you just added in step 1.
  3. Hidden region
  4. Click "Place block".
  5. Find your Views block.
  6.  Click "Place block".
  7. Configure as desired and save.
    Reference block
    Hidden region

Step 4: Create a reference field.

  1. Go to the field admin of your content type at admin/structure/types/manage/TYPE/fields.
  2.  Click "Add field".
  3. In the "Add a new field" dropdown, choose "Other" under "Reference"
    Reference field
  4. Label the field and save.
  5.  Under "Type of item to reference" choose "Block" under "Configuration" and save.
    Reference field
  6. Configure as desired. Leave "Reference method" set to "Default".
    Reference field
  7. Optionally set a block as the default:
    1. If you are only going to ever reference one view from this field and you want it automatically added, you can set it as the default value.
    2. If you would like to be able to select from multiple blocks, leave the default value blank and the user can choose when entering content. The default format of the field is autocomplete but this can be changed to a dropdown in admin/structure/types/manage/TYPE/form-display to make the choices more obvious.
  8. Save the field.

Step 5: Add the block to your content.

  1. Add a new item of the content type from step 4 at /node/add/TYPE.
  2. You should see your new field. If you set the default in Step 4, the view will automatically be filled in.

Content block

(Optional) Step 6: Alter code to limit the field.

If you are allowing the user to choose the view when entering content, you'll notice that the list is cluttered because it is showing _all_ the blocks on the site.

Reference field

To make things cleaner, you can limit the list to just blocks placed in the hidden region with this:

1) If you don't already have one, create a custom module for site wide alterations.

2) Add the following directory structure under the root directory of the module: src/Plugin/EntityReferenceSelection.
Directory Structure

3) In EntityReferenceSelection, add a file named BlockSelection.php. (The filename can be changed; just be sure it matches the class name.)

4)  In this file, add the following code. Be sure to replace "MODULE_NAME_HERE", "YOUR_SITE_THEME". Also change "hidden" if you chose a different name for the region.

<?php

nnamespace Drupal\MODULE_NAME_HERE\Plugin\EntityReferenceSelection;

use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Component\Utility\Html;

/**
 * Filters the block listing for an entity reference field. * * @EntityReferenceSelection( *   id = "blocks", *   label = @Translation("Blocks: Filter by blocks in hidden region"), *   entity_types = {"block"}, *   group = "blocks", *   weight = 1 * ) */class BlockSelection extends DefaultSelection {

  /**   * {@inheritdoc}   */public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
    $target_type = $this->configuration['target_type'];

    $query = $this->buildEntityQuery($match, $match_operator);
    if ($limit > 0) {
      $query->range(0, $limit);
    }

    $result = $query->execute();

    if (empty($result)) {
      return array();
    }

    $options = array();
    $entities = $this->entityManager->getStorage($target_type)->loadMultiple($result);
    foreach ($entities as $entity_id => $entity) {
      $block_theme = $entity->getTheme();
      $block_region = $entity->getRegion();

      // Only add blocks that are in the hidden region of the main theme.if ($block_theme == 'YOUR_SITE_THEME' && $block_region == 'hidden') {
        $bundle = $entity->bundle();
        $options[$bundle][$entity_id] = Html::escape($this->entityManager->getTranslationFromContext($entity)
          ->label());
      }
    }

    // Sort the options alphabetically.asort($options['block']);
    return $options;
  }

}

5. Save the file and clear the cache.
6. Edit the field you added in step 4 above.
7. Change the reference method to "Blocks: Filter by blocks in hidden region" and save.
Reference Type
8. Add a new item of the content type from step 4 at /node/add/TYPE.
9. The field will now be restricted to only showing blocks in the "hidden" region.

Hidden Region

As you can see, with just Drupal core you can give your content editors the flexibility to choose from different sets of data (views) while creating a node. For even more flexibility, add the Paragraphs module and add your block reference field to a paragraph type. If you then assign the field on the content type to reference paragraphs, you can set it up so your editor can choose either a premade list (one of the views) or curate the list themselves by choosing a paragraph that allows them to pick individual items of content. With a single content type, your editors can create a variety of different pages depending on their needs.

Headshot

Meet team member, Michelle Cox

Michelle started using Drupal in 2005 with the 4.6 release. She spent the next seven years actively participating in the community by writing and maintaining three contributed modules, assisting in the forums and on IRC, and performing webmaster duties on the *.drupal.org sites. After a two year break to focus on photography, she came back to Drupal and contributes to the community by helping with webmaster tasks and working with her co-maintainers on her contributed modules.

Michelle first discovered her love of programming by writing BASIC programs on her Commodore 64 as a teen. While working toward her BS in computer science at University of Wisconsin - La Crosse
, she started work as a Visual Foxpro developer and continued to work in VFP until 2004. She kept programming as a hobby when she left the professional world to take care of her two boys. Michelle  discovered Drupal while working on her family website and quickly fell in love with both the software and the community. Prior to Mediacurrent, she developed a local community social networking site and wrote the Advanced Forum, Author Pane, and Advanced Profile Kit modules.

In addition to being a coder, Michelle is a mom, photographer, and Whovian. Percentages vary.

Learn more about Michelle >

Related Insights