You are here

fieldblock.module in Field as Block 8

Same filename and directory in other branches
  1. 7 fieldblock.module

Allow fields to be rendered in blocks.

File

fieldblock.module
View source
<?php

/**
 * @file
 * Allow fields to be rendered in blocks.
 */
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;

/**
 * Implements hook_form_alter().
 *
 * Adds a column to the "display fields" table-form, with a checkbox for each
 * field.
 */
function fieldblock_form_field_ui_display_overview_form_alter(&$form, FormStateInterface &$form_state, $form_id) {
  $entity_type = $form['#entity_type'];
  $bundle = $form['#bundle'];
  $mode = $form['#mode'];

  /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $entity_view_display */
  $entity_view_display = EntityViewDisplay::load($entity_type . '.' . $bundle . '.' . $mode);

  // Add a column header.
  $form['fields']['#header'][] = t('Display as block');

  // Add checkboxes.
  $field_names = array_merge($form['#fields'], $form['#extra']);
  foreach ($field_names as $field_name) {
    $form['fields'][$field_name]['fieldblock'] = array(
      '#type' => 'checkbox',
      '#default_value' => $entity_view_display
        ->getThirdPartySetting('fieldblock', $field_name) ? true : false,
      '#title' => '',
    );
  }

  // Add a submit handler.
  $form['#submit'][] = 'fieldblock_field_display_submit';
}

/**
 * Form submit handler for field_ui_display_overview_form.
 * Stores which fields are published as blocks as a third_party_settings array
 * in the EntityViewDisplay object of the entity type / bundle / view mode.
 *
 * @param mixed[] $form
 *   A form API array.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   The state of the submitted form.
 */
function fieldblock_field_display_submit($form, FormStateInterface $form_state) {
  $entity_type = $form['#entity_type'];
  $bundle = $form['#bundle'];
  $mode = $form['#mode'];

  /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $entity_view_display */
  $entity_view_display = EntityViewDisplay::load($entity_type . '.' . $bundle . '.' . $mode);
  $fields = $form_state
    ->getValue('fields');
  foreach ($fields as $field_name => $field) {
    if (isset($field['fieldblock']) && $field['fieldblock'] == 1) {
      $entity_view_display
        ->setThirdPartySetting('fieldblock', $field_name, $form['fields'][$field_name]['human_name']['#markup']);
    }
    else {
      if ($entity_view_display
        ->getThirdPartySetting('fieldblock', $field_name)) {
        $entity_view_display
          ->unsetThirdPartySetting('fieldblock', $field_name);
      }
    }
  }
  $entity_view_display
    ->save();

  // Invalidate the block cache to update fielblock derivatives.
  if (\Drupal::moduleHandler()
    ->moduleExists('block')) {
    \Drupal::service('plugin.manager.block')
      ->clearCachedDefinitions();
  }
}

/**
 * Implements hook_entity_view_alter().
 *
 * Takes fields out of the current entity and caches them in a post render cache
 * context. The #post_render_cache callback makes this data available to the
 * fieldblock when it is built, We also hide the field from the render array.
 *
 * @param array &$build
 *   A renderable array representing the entity content.
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   The entity object being rendered. Not used in this implementation.
 * @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display
 *   The entity view display holding the display options configured for the
 *   entity components.
 *
 * @see \Drupal\fieldblock\Plugin\Block\FieldBlock::fieldBlockPostRenderCache
 * @see https://www.drupal.org/node/2151609
 */
function fieldblock_entity_view_alter(array &$build, $entity, EntityViewDisplayInterface $display) {
  $fieldblock_settings = $display
    ->getThirdPartySettings('fieldblock');
  $display_id = $display
    ->get('id');
  foreach ($fieldblock_settings as $field_name => $field_label) {
    $fieldblock_id = $display_id . ':' . $field_name;
    if (count(\Drupal\Core\Render\Element::children($build[$field_name]))) {

      // This is where we take out the field and cache it in a post render
      // cache context.
      $build['#post_render_cache']['Drupal\\fieldblock\\Plugin\\Block\\FieldBlock::fieldBlockPostRenderCache'][] = array(
        'build' => $build[$field_name],
        'fieldblock_id' => $fieldblock_id,
      );
      hide($build[$field_name]);
    }
  }
}

Functions

Namesort descending Description
fieldblock_entity_view_alter Implements hook_entity_view_alter().
fieldblock_field_display_submit Form submit handler for field_ui_display_overview_form. Stores which fields are published as blocks as a third_party_settings array in the EntityViewDisplay object of the entity type / bundle / view mode.
fieldblock_form_field_ui_display_overview_form_alter Implements hook_form_alter().