Làm cách nào tôi có thể lập trình kết xuất trường của một nút theo các cài đặt chế độ xem?


9

Tôi muốn kết xuất trường của một nút trong một khối. Nó hoạt động như thế này:

<?php

if ($node) {
  if (isset($node->field_body_secondary) && $field = $node->field_body_secondary->value) {
    $markup = render($field);
    $build = array(
      '#type' => 'markup',
      '#markup' => $markup,
    );
  }
}

return $build;

Nhưng đây không phải là 100% như thể tôi chỉ hiển thị trường bình thường, làm cho nó hiển thị trong cài đặt chế độ xem.

Câu trả lời:


0

Tôi nghĩ rằng chế độ xem nên được áp dụng cho nút, không phải cho trường. Vì vậy, bạn cần phải có được viewbuilder và kết xuất nút. Sau đó, bạn có thể chọn mảng kết xuất cho trường từ mảng kết xuất của nút. Kiểu như thế này:

$vb = [EntityTypeManager]->getViewBuilder('node'); // Drupal\node\NodeViewBuilder
$nodeview = $vb->view($node, $viewmode);
$fieldrenderarray = $nodeview[youfield-here];

PS Bạn cần "[EntityTypeManager]" bằng mọi cách được chèn dưới dạng dịch vụ @ entity_type.manager. Hoặc lấy nó trong Block-Plugin tạo () từ $ container-> get ('entity_type.manager').


1
không hẳn. $nodeview#nodechìa khóa
Alex

1
Ngoài ra, điều này làm cho nút, không phải các trường riêng biệt
Alex

1
Có, tôi kết xuất nút (và tất cả các trường của nó). Nhưng đây là những gì bạn điều chỉnh trong cài đặt chế độ xem của bạn. Có lẽ tôi đã nhầm câu hỏi của bạn.
Rainer Feike

1
"$ gật đầu [youfield-here];" là null, ít nhất là trên Drupal 8.6.x
Onkeltem

1
Thay thế "yourfield-here" bằng tên máy của trường bạn.
Rainer Feike

28

Để hiển thị một trường đơn lẻ với cài đặt hiển thị của chế độ xem, bạn có thể sử dụng view()phương thức của trường:

Ví dụ để hiển thị hình ảnh ở định dạng trêu ghẹo:

$build['image'] = $node->field_image->view('teaser');

Hoặc cơ thể đầy đủ:

$build['body'] = $node->body->view('full');

1
thật không may, điều này không tôn trọng các cài đặt chế độ xem, như nhãn và cài đặt định dạng
Alex

1
Điều này sẽ hoạt động, bạn thậm chí có thể sử dụng twig debug với lệnh này. Nếu bạn cung cấp chế độ xem hiện tại dưới dạng chuỗi, trường sẽ được định dạng bằng cái này. Nếu bạn cung cấp một mảng, bạn có thể đưa ra các cài đặt hiển thị của riêng mình, ví dụ['label' => 'inline' ]
4k4

1
Tôi tin rằng tôi đã thử nó nhưng nó không hoạt động. tôi sẽ thử lại. cảm ơn cho đến nay
Alex

1
Tôi thấy nó là tôn trọng các trình định dạng, nhưng không phải là các thiết lập định dạng. Đầu ra của điều này bao gồm các cài đặt chính xác.
Grayside

1
điều này về cơ bản đã đưa tôi đến câu trả lời, nơi tôi có thể nhận được biến của mình trong .twig: $vars['var_name'] = $node_object->field_name->view()[0]; và sau đó trong twig, tôi có thể kết xuất {{var_name}}
bdanin

4

Câu trả lời này được xây dựng trên https://drupal.stackexchange.com/a/208061/394

// Designate the field we want to render.
$field_name = 'body';
// Retrieve a render array for that field with the given view mode.
$render_array = $entity->$field_name->view('full');
// Render the result.
\Drupal::service('renderer')->renderRoot($render_array);

Để hoàn toàn lập trình hoàn thành trường bạn hoàn thành bằng cách gọi renderRoot(), nó sẽ thiết lập bối cảnh kết xuất riêng biệt với những phản hồi trang điển hình sẽ sử dụng - bối cảnh kết xuất duy nhất cho một yêu cầu hoặc yêu cầu phụ. Chúng tôi cũng có thể sử dụng renderPlain(), nhưng sau đó nó sẽ thoát khỏi tất cả mọi thứ.

Trong Drush thay thế nhưng không phải trong thực thi trang bình thường, điều này đã đưa ra một cảnh báo cho tôi:

PHP warning:  DOMDocument::loadHTML(): Tag drupal-entity invalid in Entity, line: 1 in /drupal/core/lib/Drupal/Component/Utility/Html.php on line 286

2

liên quan đến câu trả lời của Alex , đây là cách tôi sửa đổi nó để sử dụng config_pages và xây dựng khối global_footer:

<?php

public function build() {
$config_name = 'global_footer';
$config = config_pages_config($config_name);
$build = array();
$markup = array();

$fieldsToRender = array(
  'field_body', 'field_foo', 'field_bar'
);

$viewmode = 'default';
$entityType = 'config_pages';
$display = entity_get_display($entityType, $config_name, $viewmode);
$viewBuilder = \Drupal::entityTypeManager()->getViewBuilder($entityType);

foreach ($fieldsToRender as $field_name) {
  if (isset($config->{$field_name}) && $field = $config->{$field_name}) {
    $fieldRenderable = $viewBuilder->viewField($field, $display->getComponent($field_name));
    if (count($fieldRenderable) &&! empty($fieldRenderable)) {
      $markup[] = \Drupal::service('renderer')->renderRoot($fieldRenderable);
    }
  }
}

if (count($markup)) {
  $build = array(
    '#type' => 'markup',
    '#markup' => implode("", $markup),
  );
}

return $build;

}

Có lẽ tốt hơn để hiển thị các trường tùy ý từ thiết lập config_pages thay vì kéo dữ liệu từ một nút, nhưng tôi đoán nó thực sự phụ thuộc vào trường hợp sử dụng cụ thể như phương pháp nào là tốt nhất.


2

Nhờ câu trả lời của Rainer Feike, tôi đã tìm ra giải pháp:

<?php

public function build() {
  $node = \Drupal::routeMatch()->getParameter('node');
  $build = array();
  $markup = array();

  $fieldsToRender = array(
    'field_node_ref', 'field_foo', 'field_bar',
  );

  $viewmode = 'default';
  $entityType = 'node';
  $display = entity_get_display($entityType, $node->getType(), $viewmode);
  $viewBuilder = \Drupal::entityTypeManager()->getViewBuilder($entityType);

  foreach ($fieldsToRender as $field_name) {
    if (isset($node->{$field_name}) && $field = $node->{$field_name}) {
      $fieldRenderable = $viewBuilder->viewField($field, $display->getComponent($field_name));
      if (count($fieldRenderable) &&! empty($fieldRenderable)) {
        $markup[] = \Drupal::service('renderer')->renderRoot($fieldRenderable);
      }
    }  
  }

  if (count($markup)) {
    $build = array(
      '#type' => 'markup',
      '#markup' => implode("", $markup),
    );
  }

  return $build;

}

Sử dụng $viewBuilder->viewFieldtôi có thể kết xuất bất kỳ trường nào tôi cần. Tôi chỉ cần tìm hiểu làm thế nào để thêm bộ nhớ đệm tùy thuộc vào cài đặt chế độ xem, nhưng đây là một câu hỏi khác :)

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.