Was ist die beste Vorgehensweise, um die Felder eines Knotens in verschiedenen Regionen in Drupal 8 anzuzeigen?
Ich denke, es gibt keine Best Practice dafür, vielleicht nicht einmal eine gute Practice, aber es ist nicht unmöglich, ein paar Optionen zu befolgen
Für mich ist dies die beste Option: Sie können einen Block erstellen, der den aktuellen Knoten lädt und Ihr gewünschtes Knotenfeld anzeigt. Auf diese Weise können Sie problemlos über die Benutzeroberfläche verwalten (Ihr Block mit 'node_type' select und 'field_name' select ist einfach und schnell zu erledigen).
Beginnen Sie mit der Bearbeitung 1
Hier meine Implementierung dieses Blocks, testen und kommentieren Sie bitte die Ergebnisse
<?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'];
}
}
Edit beenden 1
Oder ... holen Sie Ihr Feld ein preprocess_region
und laden Sie eine Variable (dies ist leicht zu demonstrieren).
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();
}
}
}
}
Und in Ihrer Zweigdatei verwenden
{% if node_field %}
{{ node_field }}
{% endif %}
VORSICHT:
In Zukunft können Sie dieses Feld nicht mehr entfernen. Wenn Sie es entfernen, wird Ihre Seite beschädigt. Erläuterung: $node->get('field_descricao')
wird keine Null auswerten, dann null->view()
= kaputte Seite. Selbst wenn Sie sich darum kümmern, kann jemand oder sogar Sie dies vergessen und es wird Ihnen Kopfschmerzen bereiten, warum diese Informationen nicht mehr angezeigt werden.