Какова наилучшая практика для отображения полей узла в разных регионах?

В D7 мы использовали представление для узлов, причем каждое поле имело собственный дисплей. Каждый дисплей создает блок для размещения в любом регионе сайта. Но, конечно, Views тяжелее SQL.

Теперь, Drupal 8 - все это причудливо. Что такое способ Drupal 8 для отображения полей узла в разных регионах страницы?

Изменить: моя текущая попытка - создать настраиваемый модуль, который предоставляет блок для каждого указанного поля.

6 голосов | спросил Alex 27 PMpWed, 27 Apr 2016 15:24:52 +030024Wednesday 2016, 15:24:52

7 ответов


4

Непонятно, почему вы хотите, чтобы каждое отдельное поле было отдельным блоком? Это довольно неэффективно, если ничего другого.

Чтобы иметь один или два дополнительных блока, вы можете использовать блок представления Entity, предоставляемый модулем ctools. Он займет текущий узел и отобразит его в определенном режиме просмотра. Конечно, будет больно поддерживать, если каждое поле является отдельным, но я действительно не понимаю, почему вы хотели бы это сделать?

ответил Berdir 27 PMpWed, 27 Apr 2016 22:17:15 +030017Wednesday 2016, 22:17:15
2
  

Какова наилучшая практика отображения полей узла в разных регионах в Drupal 8?

Я думаю, что нет лучшей практики для этого, может быть, даже не хорошей практики, но ее невозможно сделать, следуя нескольким опциям

Для меня это лучший вариант: вы можете создать блок, который загружает текущий узел и покажет нужный node_field. Таким образом, вы можете легко управлять через пользовательский интерфейс (ваш блок с выбором «node_type» и «field_name» выбирается легко и быстро).


Начать редактирование 1
Здесь моя реализация этого блока, проверка и прокомментируйте результаты

<?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


Или ... получите свое поле в preprocess_region и загрузите в var (это легко продемонстрировать).

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();
      }
    }
  }
}

И используйте в своем файле twig

{% if node_field %} 
  {{ node_field }}
{% endif %}

ВНИМАНИЕ:
В будущем вы не сможете удалить это поле, если вы его удалите, сломает вашу страницу. Объяснение: $node->get('field_descricao') будет оценивать значение null, затем null->view() = сломанная страница. Даже вы позаботитесь об этом, кто-то или даже вы можете забыть об этом, и будет головной болью, почему эта информация больше не отображается.

ответил Vagner 5 Maypm16 2016, 17:42:14
2

Ctools в D8 поставляется с экспериментальным модулем, называемым Блоки инструментов хаоса , которые позволят вам сделать это в любом макете варианта менеджера страниц.

Это очень полезно, если вы создаете вариант узла для отображения типа содержимого.

После включения вы можете добавить любое поле из просматриваемого узла. Вы увидите полный список полей, доступных в разделе «Содержимое», когда вы нажимаете на блок добавления.

Недостатком является то, что модуль является экспериментальным и доступной документации недостаточно.

Вот активный поток об этом https://www.drupal.org/node/2809213

Страница модуля https://www.drupal.org/project/ctools

Я пробовал это сам, и он отлично работает.

Надеюсь, это поможет вам или любому, кто ищет решение для такого рода сценариев.

ответил Nicolas Pinos 28 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 28 Sep 2017 03:25:34 +0300 2017, 03:25:34
1
  

например, у нас есть поле« боковая панель »для узлов. конечно, что   содержимое поля должно отображаться вне нормального «содержимого», в   другой регион. - Alex 18 часов назад

Вместо того, чтобы использовать макет темы и область боковой панели, вы можете использовать один из следующих модулей и создать макет панели или дисплея с областью боковой панели. Затем вы можете вставить поля узла и другие блоки, которые вам нужны, на боковой панели и в других регионах, которые вы создаете.

Панели

  

Модуль «Панели» позволяет администратору сайта создавать персонализированные   макеты для нескольких целей. По своей сути это перетаскивание контента   менеджер, который позволяет визуально проектировать макет и размещать контент   внутри этого макета. Интеграция с другими системами позволяет вам   создавать узлы, которые используют это, целевые страницы, которые используют это, и даже   переопределить системные страницы, такие как таксономия и страницу узла, чтобы вы   может настроить макет вашего сайта с очень мелкозернистым   разрешения.

Display Suite

  

Display Suite позволяет вам полностью контролировать, как ваш контент   отображается с помощью интерфейса перетаскивания. Расположите свои узлы, виды,   комментарии, данные пользователя и т. д., как вы хотите, без необходимости работать с   путь через десятки файлов шаблонов.

ответил No Sssweat 7 Mayam16 2016, 07:58:17
1

Модуль Блок поля делает в значительной степени то, что вы просите. Он позволяет отображать любое поле в любом типе /пакете сущности в виде блока в области, которая вам нравится.

ответил NewZeal 10 AM00000050000004531 2016, 05:48:45
0

Если вы хотите использовать функцию быстрого редактирования, вы можете создавать и использовать разные режимы просмотра через пользовательский интерфейс (в разделе «Режимы структуры /отображения /Режимы просмотра»). То есть вы не ограничены только, скажем, режимами «Тизер» и «Полный просмотр». И вы также можете использовать свои настраиваемые режимы просмотра в представлениях. И контент, созданный таким образом, будет иметь все необходимые контекстные ссылки.

ответил Stanislav Agapov 27 PMpWed, 27 Apr 2016 15:57:08 +030057Wednesday 2016, 15:57:08
-1

В Drupal 7 я делал то же самое, что и Alex: Создавайте представления для размещения контента в блоках. Я нашел эту нить, которая ищет способ сделать работу QuickEdit.
Display Suite и ViewModes кажется ответом.

Это кажется мне самым чистым способом: используя версию Displayup для Drupal 8, вы можете добавлять поля от узлов к блокам.
Полные инструкции находятся на https://www.drupal.org/node/2754967 . Этот метод сохраняет создание кучи представлений и позволяет встроенное редактирование.

ответил Roo 21 +03002016-10-21T06:08:59+03:00312016bEurope/MoscowFri, 21 Oct 2016 06:08:59 +0300 2016, 06:08:59

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132