Whats best practice to show a node's fields in different regions in Drupal 8?
I think, there is no best practice for that, maybe not even a good practice, but its not impossible to do, follow a couple of options
For me this is best option: You can create a block that load current node and show your desired node_field. This way, and you can manage via UI easily (Your block with 'node_type' select and 'field_name' select is easy and fast to do that).
Begin Edit 1
Here my implementation of that block, test and please comment the results
<?php /** * @file * Contains \Drupal\ module_name\Plugin\Block\NodeFieldBlock. */ namespace Drupal\module_name\Plugin\Block; use Drupal\Core\Block\BlockBase; use Drupal\Core\Cache\Cache; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityDisplayRepositoryInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\field\Entity\FieldConfig; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; /** * Provides a Filter by vocabulary terms block. * * @Block( * id = "node_field_block", * admin_label = @Translation("Node Field") * ) */ class NodeFieldBlock extends BlockBase implements ContainerFactoryPluginInterface { /** * The Entity Type Manager. * * @var Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * The Entity Field Manager. * * @var Drupal\Core\Entity\EntityFieldManagerInterface */ protected $entityFieldManager; /** * The Entity Display Repository. * * @var Drupal\Core\Entity\EntityDisplayRepository */ protected $entityDisplayRepository; /** * Dependency injection through the constructor. * * @param array $configuration * A configuration array containing information about the plugin instance. * @param string $plugin_id * The plugin ID for the plugin instance. * @param mixed $plugin_definition * The plugin implementation definition. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_type_manager * The Entity Type Manager. * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager * The Entity Field Manager. * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository * The Entity Display Repository. */ public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, EntityDisplayRepositoryInterface $entity_display_repository) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->entityTypeManager = $entity_type_manager; $this->entityFieldManager = $entity_field_manager; $this->entityDisplayRepository = $entity_display_repository; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('entity_type.manager'), $container->get('entity_field.manager'), $container->get('entity_display.repository') ); } /** * {@inheritdoc} */ public function defaultConfiguration() { return array( 'node_type' => array_keys(node_type_get_names())[0], 'view_mode' => 'default', 'field' => '', ); } /** * {@inheritdoc} */ public function blockForm($form, FormStateInterface $form_state) { $types = node_type_get_names(); $config = $this->configuration; if ($node_type = $form_state->getValue(array('settings', 'node_type'))) { $config['node_type'] = $node_type; } $form['node_type'] = array( '#title' => $this->t('Content type'), '#type' => 'select', '#options' => $types, '#default_value' => $config['node_type'], '#ajax' => array( 'callback' => array(get_class($this), 'updateFieldList'), 'wrapper' => 'edit-node-wrapper', ), ); $form['options'] = array( '#type' => 'container', '#prefix' => '<div id="edit-node-wrapper">', '#suffix' => '</div>', ); $form['options']['view_mode'] = array( '#title' => $this->t('View mode'), '#type' => 'select', '#multiple' => FALSE, '#options' => $this->getViewModes($config['node_type']), '#default_value' => $config['view_mode'], ); $form['options']['field_list'] = array( '#title' => $this->t('Field list'), '#type' => 'select', '#multiple' => FALSE, '#options' => $this->getFieldList($config['node_type']), '#default_value' => $config['field'], ); return $form; } /** * {@inheritdoc} */ public function blockSubmit($form, FormStateInterface $form_state) { $this->configuration['node_type'] = $form_state->getValue('node_type'); $this->configuration['view_mode'] = $form_state->getValue(array('options', 'view_mode')); $this->configuration['field'] = $form_state->getValue(array('options', 'field_list')); } /** * {@inheritdoc} */ public function build() { $config = $this->configuration; $build = array(); if ($node = \Drupal::routeMatch()->getParameter('node')) { if ($config['node_type'] == $node->getType()) { if ($field = $node->get($config['field'])) { $build['field'] = $field->view($config['view_mode']); } } } return $build; } /** * {@inheritdoc} */ public function getCacheTags() { if ($node = \Drupal::routeMatch()->getParameter('node')) { return Cache::mergeTags(parent::getCacheTags(), array('node:' . $node->id())); } else { return parent::getCacheTags(); } } /** * {@inheritdoc} */ public function getCacheContexts() { return Cache::mergeContexts(parent::getCacheContexts(), array('route')); } /** * Função que cria uma lista de fields de um node type. * * @param string $node_type * O id do node type. * @return array * Retorna a lista de campos do node type. */ protected function getFieldList($node_type) { if (!empty($node_type)) { $list = $this->entityFieldManager->getFieldDefinitions('node', $node_type); foreach ($list as $id => $field) { if ($field instanceof FieldConfig) { $list[$id] = $field->label(); } else { unset($list[$id]); } } return $list; } return array(); } /** * Função que cria uma lista de view modes de um node type. * * @param string $node_type * O id do node type. * @return array * Retorna a lista de view mode do node type. */ protected function getViewModes($node_type) { return $this->entityDisplayRepository->getViewModeOptionsByBundle('node', $node_type); } /** * Handles switching the node type selector. */ public static function updateFieldList(&$form, FormStateInterface &$form_state, Request $request) { return $form['settings']['options']; } }
End Edit 1
Or... get your field in preprocess_region and load in a var (this is easy to demonstrate).
function THEME_preprocess_region(&$variables) { //TODO: change for you region name if ($variables['region'] == 'sidebar_right') { if ($node = \Drupal::routeMatch()->getParameter('node')) { //TODO: change for you node type if ($node->getType() == 'article') { //If you need a flag for this type $variables['is_article'] = TRUE; //Here is your field $variables['node_field'] = $node->get('field_descricao')->view(); } } } }
And use in your twig file
{% if node_field %} {{ node_field }} {% endif %}
CAUTION:
In the future you can't remove this field, if you remove, will break your page. Explanation: $node->get('field_descricao') will evaluate no null then null->view() = broke page. Even you take care of this, someone or even you can forget about this and will be a headache why that information not show anymore.