ฉันจะแสดงผลฟิลด์ของโหนดโดยทางโปรแกรมตามการตั้งค่าโหมดมุมมองได้อย่างไร?


9

ฉันต้องการแสดงฟิลด์ของโหนดภายในบล็อก มันได้ผลเช่นนี้:

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

แต่นี่ไม่ใช่ 100% ราวกับว่าฉันเพิ่งจะเรนเดอร์ฟิลด์ตามปกติทำให้มองเห็นได้ในการตั้งค่าโหมดดู

คำตอบ:


0

ฉันคิดว่าโหมด view ควรใช้กับโหนดไม่ใช่ฟิลด์ ดังนั้นคุณต้องรับตัวสร้าง view และสร้างโหนด หลังจากนั้นคุณสามารถเลือกอาร์เรย์ที่เรนเดอร์สำหรับฟิลด์จากโหนดการเรนเดอร์ node'r แบบนี้:

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

ป.ล. คุณต้อง "[EntityTypeManager]" แต่อย่างใดฉีดเป็นบริการ @ entity_type.manager หรือรับมันใน Block-Plugin ของคุณสร้าง () จาก $ container-> get ('entity_type.manager')


1
ไม่มาก $nodeviewมี#nodeกุญแจ
Alex

1
นอกจากนี้สิ่งนี้ทำให้โหนดไม่แยกฟิลด์
อเล็กซ์

1
ใช่ฉันแสดงโหนด (และทุกฟิลด์มัน) แต่นี่คือสิ่งที่คุณปรับในการตั้งค่าโหมดดู บางทีฉันอาจมีคำถามของคุณผิด
Rainer Feike

1
"$ nodeview [youfield-นี่];" เป็นโมฆะอย่างน้อยใน Drupal 8.6.x
Onkeltem

1
แทนที่ "yourfield-here" ด้วยชื่อเครื่องของฟิลด์ของคุณ
Rainer Feike

29

หากต้องการแสดงผลฟิลด์เดียวด้วยการตั้งค่าการแสดงผลของโหมดดูคุณสามารถใช้view()วิธีการของฟิลด์:

ตัวอย่างสำหรับการแสดงผลภาพในรูปแบบทีเซอร์:

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

หรือร่างกายเต็ม:

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

1
น่าเสียดายที่สิ่งนี้ไม่เกี่ยวข้องกับการตั้งค่าโหมดมุมมองเช่นการตั้งค่าป้ายกำกับและการจัดรูปแบบ
Alex

1
สิ่งนี้ควรใช้งานได้คุณสามารถใช้การดีบัก twig ด้วยคำสั่งนี้ได้ หากคุณระบุโหมดมุมมองที่มีอยู่เป็นสตริงฟิลด์จะถูกจัดรูปแบบด้วยสิ่งนี้ หากคุณจัดเตรียมอาร์เรย์คุณสามารถตั้งค่าการแสดงผลของคุณเองได้เช่น['label' => 'inline' ]
4k4

1
ฉันเชื่อว่าฉันลองแล้ว แต่มันใช้งานไม่ได้ ฉันจะลองอีกครั้ง ขอบคุณจนถึงตอนนี้
อเล็กซ์

1
ฉันพบว่ามันเกี่ยวข้องกับตัวจัดรูปแบบ แต่ไม่ใช่การตั้งค่าตัวจัดรูปแบบ ผลลัพธ์ของสิ่งนี้รวมถึงการตั้งค่าที่ถูกต้อง
Grayside

2
สิ่งนี้ทำให้ฉันได้รับคำตอบที่ฉันสามารถรับตัวแปรของฉันใน. twig: $vars['var_name'] = $node_object->field_name->view()[0]; และจากนั้นใน twig ฉันสามารถแสดง {{var_name}}
bdanin

4

คำตอบนี้สร้างขึ้นใน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);

ในการสร้างการเรนเดอร์ฟิลด์โดยทางโปรแกรมโดยสมบูรณ์โดยการเรียกrenderRoot()ซึ่งสร้างบริบทการเรนเดอร์แยกจากการตอบกลับของหน้าเว็บทั่วไปที่จะใช้ - บริบทการเรนเดอร์เดี่ยวสำหรับคำขอหรือคำขอย่อย เราสามารถใช้งานrenderPlain()ได้ แต่จากนั้นมันจะหนีออกมาทุกสิ่ง

ใน Drush repl แต่ไม่ใช่ในการประมวลผลหน้าปกตินี่ทำให้ฉันได้รับคำเตือน:

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

เกี่ยวข้องกับคำตอบของAlexนี่คือวิธีที่ฉันแก้ไขเพื่อใช้config_pagesและสร้างบล็อก 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;

}

มันอาจจะดีกว่าที่จะแสดงฟิลด์โดยพลการจากการตั้งค่า config_pages ซึ่งต่างจากการดึงข้อมูลจากโหนด แต่ฉันคิดว่ามันขึ้นอยู่กับกรณีการใช้งานเฉพาะซึ่งเป็นวิธีที่ดีที่สุด


2

ขอบคุณคำตอบของ Rainer Feikeฉันมาที่ทางออก:

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

}

การใช้$viewBuilder->viewFieldฉันสามารถแสดงฟิลด์ใด ๆ ได้ตามต้องการ ฉันแค่ต้องการหาวิธีเพิ่มแคชขึ้นอยู่กับการตั้งค่าโหมดดู แต่นี่เป็นคำถามอื่น :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.