web-dev-qa-db-ja.com

異なるリージョンでノードのフィールドを表示するためのベストプラクティスは何ですか?

D7では、ノードのビューを作成するために使用しました。各フィールドには独自の表示があります。各ディスプレイは、サイトの任意の領域に配置するブロックを作成します。しかしもちろん、ビューはSQLを多用します。

Drupal 8はすべてファンシーです。ページのさまざまな領域にノードのフィールドを表示するDrupal 8の方法は何ですか?

編集:私の現在の試みは、指定された各フィールドにブロックを提供するカスタムモジュールを作成することです。

7
Alex

なぜすべてのフィールドを個別のブロックにしたいのか正確にわかりませんか?他に何もないとしても、それはかなり非効率的です。

1つまたは2つのブロックを追加するには、ctoolsモジュールによって提供されるエンティティビューブロックを使用できます。現在のノードを取得し、特定のビューモードで表示します。もちろん、すべてのフィールドが別々になっていると維持するのは面倒ですが、なぜそうしたいのか本当にわかりませんか?

4
Berdir

D8のCtoolsには、Chaos tools blocksと呼ばれる実験的なモジュールが付属しており、ページマネージャーのさまざまなレイアウトでこれを実行できます。

これは、コンテンツタイプを表示するノードバリアントを作成する場合に非常に役立ちます。

有効にした後、表示されているノードから任意のフィールドを追加できます。ブロックの追加をクリックすると、「コンテンツ」の下で利用可能なフィールドの完全なリストが表示されます。

欠点は、モジュールが実験的なものであり、利用できるドキュメントがあまりないことです。

これはアクティブなスレッドです https://www.drupal.org/node/280921

モジュールページ https://www.drupal.org/project/ctools

私はそれを自分で試してみましたが、うまくいきます。

これがあなたやこの種のシナリオの解決策を探している人を助けることを願っています。

3
Nicolas Pinos

Drupal 8)でノードのフィールドを異なる領域に表示するためのベストプラクティスは何ですか?

そのためのベストプラクティスはないと思います。多分良いプラクティスとは言えないかもしれませんが、不可能ではありません。いくつかのオプションに従ってください。

私にとってはこれが最良のオプションです。現在のノードをロードして目的のnode_fieldを表示するブロックを作成できます。このようにして、UIを介して簡単に管理できます( 'node_type' selectおよび 'field_name' selectを使用したブロックは、簡単かつ高速に実行できます)。


編集開始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'];
  }
}
_

編集終了1


または... _preprocess_region_でフィールドを取得し、変数にロードします(これは簡単に説明できます)。

_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() =ページを壊します。あなたがこれを世話しても、誰かまたはあなたはこれを忘れることができ、なぜその情報がもう表示されないのか頭痛になります。

2
Vagner

Field Block モジュールは、あなたが求めていることのほとんどを行います。これにより、任意のエンティティタイプ/バンドルの任意のフィールドを、お好みの領域のブロックとして表示できます。

1
NewZeal

たとえば、ノードには「サイドバー」というフィールドがあります。もちろん、そのフィールドのコンテンツは、通常の「コンテンツ」の外側の別のリージョンにレンダリングする必要があります。 -18時間前のアレックス

テーマのレイアウトとサイドバー領域を使用する代わりに、次のモジュールのいずれかを使用して、サイドバー領域を持つパネルまたはディスプレイスイートレイアウトを作成できます。次に、ノードフィールドと必要な他のブロックをサイドバーや作成した他のリージョンに挿入できます。

パネル

パネルモジュールを使用すると、サイト管理者は複数の用途に合わせてカスタマイズされたレイアウトを作成できます。コアとなるのは、ドラッグアンドドロップコンテンツマネージャーで、レイアウトを視覚的にデザインし、そのレイアウト内にコンテンツを配置できます。他のシステムとの統合により、これを使用するノード、これを使用するランディングページを作成し、分類やノードページなどのシステムページをオーバーライドして、非常に細かい権限でサイトのレイアウトをカスタマイズできます。

Display Suite

Display Suiteでは、ドラッグアンドドロップインターフェイスを使用してコンテンツの表示方法を完全に制御できます。ノード、ビュー、コメント、ユーザーデータなどを、何十ものテンプレートファイルを操作することなく、思い通りに配置できます。

1
No Sssweat

クイック編集機能を使用する場合は、UIを使用してさまざまなビューモードを作成して使用できます(構造/表示モード/ビューモードの下)。つまりたとえば、ティーザーモードとフルビューモードだけに限定されません。また、ビューでカスタムビューモードを使用することもできます。そして、そのような方法でレンダリングされたコンテンツには、必要なすべてのコンテキストリンクがあります。

0