Cách thực hành tốt nhất để hiển thị các trường của nút ở các vùng khác nhau là gì?


7

Trong D7, chúng tôi đã sử dụng để tạo chế độ xem cho các nút, với mỗi trường có một màn hình riêng. Mỗi màn hình tạo ra một khối để đặt ở bất kỳ khu vực nào của trang web. Nhưng tất nhiên, Lượt xem nặng về SQL.

Bây giờ, Drupal 8 là tất cả ưa thích. Cách 8 Drupal hiển thị các trường của một nút trong các khu vực khác nhau của trang là gì?

Chỉnh sửa: nỗ lực hiện tại của tôi là tạo một mô-đun tùy chỉnh cung cấp một khối cho từng trường được chỉ định.

Câu trả lời:


4

Không chắc chắn chính xác lý do tại sao bạn muốn có mỗi trường là một khối riêng biệt? Điều đó khá kém hiệu quả, nếu không có gì khác.

Để có một hoặc hai khối bổ sung, bạn có thể sử dụng khối chế độ xem Thực thể được cung cấp bởi mô-đun ctools. Nó sẽ lấy nút hiện tại và hiển thị nó trong một chế độ xem nhất định. Tất nhiên điều đó sẽ gây khó khăn để duy trì nếu mỗi lĩnh vực riêng biệt, nhưng tôi không thực sự thấy lý do tại sao bạn muốn làm điều đó?


ví dụ, chúng ta có một "thanh bên" cho các nút. tất nhiên, nội dung của trường đó phải được hiển thị bên ngoài "nội dung" thông thường, ở một khu vực khác.
Alex

3

Ctools trong D8 đi kèm với một mô-đun thử nghiệm được gọi là các khối công cụ Chaos sẽ cho phép bạn thực hiện điều này trong bất kỳ bố cục biến thể của trình quản lý trang nào.

Điều này rất hữu ích nếu bạn đang tạo một biến thể nút để hiển thị một loại nội dung.

Sau khi bạn bật nó, bạn có thể thêm bất kỳ trường nào từ nút đang được xem. Bạn sẽ thấy một danh sách đầy đủ các trường có sẵn trong "Nội dung" khi bạn nhấp vào thêm khối.

Nhược điểm, mô-đun là thử nghiệm và không có nhiều tài liệu có sẵn.

Đây là một chủ đề tích cực về nó https://www.drupal.org/node/2809213

Trang mô-đun https://www.drupal.org/project/ctools

Tôi đã thử nó và nó hoạt động tốt.

Hy vọng điều này sẽ giúp bạn hoặc bất cứ ai đang tìm kiếm một giải pháp cho loại kịch bản này.


2

Cách tốt nhất để hiển thị các trường của một nút trong các khu vực khác nhau trong Drupal 8 là gì?

Tôi nghĩ rằng, không có thực hành tốt nhất cho điều đó, thậm chí có thể không phải là một thực hành tốt, nhưng nó không phải là không thể làm, làm theo một vài lựa chọn

Đối với tôi đây là tùy chọn tốt nhất: Bạn có thể tạo một khối tải nút hiện tại và hiển thị node_field mong muốn của bạn. Bằng cách này, và bạn có thể quản lý thông qua UI một cách dễ dàng (Khối của bạn với 'node_type' select và 'field_name' select rất dễ dàng và nhanh chóng để làm điều đó).


Bắt đầu Chỉnh sửa 1
Ở đây tôi thực hiện khối đó, kiểm tra và vui lòng nhận xét kết quả

<?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'];
  }
}

Kết thúc chỉnh sửa 1


Hoặc ... đưa trường của bạn vào preprocess_regionvà tải một var (điều này rất dễ chứng minh).

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

Và sử dụng trong tập tin twig của bạn

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

THẬN TRỌNG:
Trong tương lai, bạn không thể xóa trường này, nếu bạn xóa, sẽ phá vỡ trang của bạn. Giải thích: $node->get('field_descricao')sẽ đánh giá không null sau đó null->view()= trang bị hỏng. Ngay cả bạn quan tâm đến điều này, ai đó hoặc thậm chí bạn có thể quên điều này và sẽ đau đầu tại sao thông tin đó không hiển thị nữa.


anh chàng đó là một câu trả lời bệnh hoạn! tôi sẽ thử lại sau
Alex

Làm thế nào về hiệu suất và bộ nhớ đệm? đây có phải là người biểu diễn không?
Alex

1
Điều đó là ổn, trên giai đoạn xây dựng chỉ hiển thị một yếu tố (không tra cứu, không có danh sách xây dựng ... chỉ cần kiểm tra nếu tồn tại), không có gì khác. Mỗi tuyến đường khối này là build ( getCacheContexts), nếu có một nút với loại cụ thể, thì sẽ kết xuất một trường. Và có, nếu bạn truy cập bộ đệm lần thứ hai sẽ được sử dụng. Nếu bạn thay đổi nút thì khối của bạn sẽ được xây dựng lại ( getCacheTags). Trong trường hợp này (chặn lấy thông tin nút), đối tượng khối phải ghi đè thông tin bộ đệm, nếu không khối của bạn sẽ chỉ được xây dựng một lần và sẽ được sử dụng cho mọi nơi.
Vagner

1

ví dụ, chúng ta có một "thanh bên" cho các nút. tất nhiên, nội dung của trường đó phải được hiển thị bên ngoài "nội dung" thông thường, ở một khu vực khác. - Alex 18 giờ trước

Thay vì sử dụng bố cục của chủ đề và vùng thanh bên, bạn có thể sử dụng một trong các mô-đun sau và tạo bảng điều khiển hoặc bố cục bộ hiển thị với vùng thanh bên. Sau đó, bạn có thể chèn các trường nút và các khối khác bạn cần trên thanh bên và trên các khu vực khác mà bạn tạo.

Tấm

Mô-đun Panels cho phép người quản trị trang tạo bố cục tùy chỉnh cho nhiều mục đích sử dụng. Về cốt lõi, nó là trình quản lý nội dung kéo và thả cho phép bạn thiết kế trực quan bố cục và đặt nội dung trong bố cục đó. Tích hợp với các hệ thống khác cho phép bạn tạo các nút sử dụng cái này, trang đích sử dụng cái này và thậm chí ghi đè lên các trang hệ thống như phân loại và trang nút để bạn có thể tùy chỉnh bố cục trang web của mình với quyền truy cập rất tốt.

Bộ hiển thị

Display Suite cho phép bạn kiểm soát hoàn toàn cách hiển thị nội dung của mình bằng giao diện kéo và thả. Sắp xếp các nút, chế độ xem, nhận xét, dữ liệu người dùng, v.v ... theo cách bạn muốn mà không phải thực hiện theo cách của bạn thông qua hàng tá tệp mẫu.


tôi biết những mô-đun này. họ có biểu diễn không? ví dụ, lượt xem khá nặng vì chúng thực hiện các truy vấn sql bổ sung mặc dù nút đã được tải
Alex

1
Trong lịch sử những mô-đun đã được cải thiện theo tuổi tác. Tôi chưa thấy các biện pháp hiệu suất trên các phiên bản D8, nhưng chúng đều được xây dựng và sử dụng bởi các công ty lo lắng rất nhiều về hiệu suất. Vì vậy, tôi hy vọng rằng nếu ngày nay chúng không được xây dựng tốt như chúng có thể, chúng sẽ sớm ra mắt.
acrosman

1

Các Dòng Khối mô-đun làm khá nhiều những gì bạn đang yêu cầu. Nó cho phép bất kỳ trường nào trong bất kỳ loại / gói thực thể nào được hiển thị dưới dạng một khối trong khu vực bạn thích.


Thật không may, nó tạo ra một khối cho mọi loại nội dung và trường dẫn đến rất nhiều khối: /
Alex

0

Nếu bạn muốn sử dụng tính năng Chỉnh sửa nhanh, bạn có thể tạo và sử dụng các Chế độ xem khác nhau thông qua giao diện người dùng (bên dưới Cấu trúc / Chế độ hiển thị / Chế độ xem). Tức là bạn không bị giới hạn chỉ với các chế độ xem Teaser và Full. Và bạn cũng có thể sử dụng các chế độ xem tùy chỉnh của mình trong Chế độ xem. Và nội dung được hiển thị theo cách như vậy sẽ có tất cả các liên kết theo ngữ cảnh bắt buộc.


Nhưng điều đó có nghĩa là tôi sẽ phải tạo chế độ xem cho mọi trường?
Alex

Không, bạn có thể tạo chế độ xem mới cho các nút và điều chỉnh nó ở tab "Quản lý hiển thị" của loại nội dung. Mỗi chế độ xem (được coi là một bộ hiển thị trường) có thể được điều chỉnh riêng biệt với các chế độ khác.
Stanislav Agapov

-1

Trong Drupal 7, tôi đã từng làm chính xác như Alex: Tạo chế độ xem để đặt nội dung trong các khối. Tôi tìm thấy chủ đề này đang tìm cách để QuickEdit hoạt động.
Display Suite và ViewModes dường như là câu trả lời.

Đây có vẻ là cách sạch nhất đối với tôi: Sử dụng phiên bản Drupal 8 của Display Suite, bạn có thể thêm các trường từ nút vào khối.
Hướng dẫn đầy đủ có trên https://www.drupal.org/node/2754967 . Phương pháp này giúp tiết kiệm việc tạo ra một loạt các chế độ xem và cho phép chỉnh sửa nội tuyến.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.