Bagaimana saya bisa secara render membuat bidang node menghormati pengaturan mode tampilan?


9

Saya ingin merender bidang simpul di dalam blok. Ini berfungsi seperti ini:

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

Tapi ini bukan 100% seolah-olah saya hanya akan membuat bidang secara normal, membuatnya terlihat dalam pengaturan mode tampilan.

Jawaban:


0

Saya pikir viewmode harus diterapkan ke node, bukan ke lapangan. Jadi, Anda perlu mendapatkan viewbuilder dan merender node. Setelah itu Anda bisa memilih array yang diberikan untuk bidang dari array render node'r. Jenis seperti ini:

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

PS Anda harus "[EntityTypeManager]" bagaimanapun disuntikkan sebagai layanan @ entity_type.manager. Atau dapatkan di Block-Plugin Anda buat () dari $ container-> get ('entitas_type.manager').


1
tidak terlalu. $nodeviewmemiliki #nodesebagai kunci
Alex

1
juga, ini membuat simpul, bukan bidang yang terpisah
Alex

1
Ya, saya membuat simpul (dan semua isinya). Tapi ini yang Anda sesuaikan dalam pengaturan mode tampilan Anda. Mungkin saya salah menjawab pertanyaan Anda.
Rainer Feike

1
"$ nodeview [youfield-here];" adalah nol, setidaknya pada Drupal 8.6.x
Onkeltem

1
Ganti "yourfield-sini" dengan nama mesin bidang Anda.
Rainer Feike

28

Untuk merender bidang tunggal dengan pengaturan tampilan mode tampilan, Anda dapat menggunakan view()metode bidang:

Contoh untuk rendering gambar dalam format teaser:

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

Atau seluruh tubuh:

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

1
Sayangnya, ini tidak menghormati pengaturan mode tampilan, seperti pengaturan label dan formatter
Alex

1
Ini seharusnya bekerja, Anda bahkan dapat menggunakan ranting debug dengan perintah ini. Jika Anda memberikan mode tampilan yang ada sebagai string, bidang akan diformat dengan ini. Jika Anda memberikan array, Anda dapat memberikan pengaturan tampilan sendiri, misalnya['label' => 'inline' ]
4k4

1
Saya percaya saya sudah mencobanya tetapi tidak berhasil. aku akan mencoba lagi. terima kasih sejauh ini
Alex

1
Saya menemukan itu menghormati formatter, tetapi bukan pengaturan formatter. Output dari ini termasuk pengaturan yang benar.
Grayside

1
ini pada dasarnya membuat saya mendapatkan jawaban, di mana saya bisa mendapatkan variabel saya di .twig: $vars['var_name'] = $node_object->field_name->view()[0]; dan kemudian di ranting, saya bisa me-render {{var_name}}
bdanin

4

Jawaban ini dibangun di 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);

Untuk merender secara lengkap bidang yang Anda selesaikan dengan menelepon renderRoot(), yang menetapkan konteks render terpisah dari apa yang akan digunakan respons laman - konteks render tunggal untuk permintaan atau sub-permintaan. Kami juga bisa menggunakan renderPlain(), tetapi kemudian itu akan luput dari semua hal.

Di Drush repl tetapi tidak dalam eksekusi halaman normal, ini memberi saya peringatan:

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

terkait dengan jawaban Alex , berikut adalah cara saya memodifikasinya untuk menggunakan config_pages dan membangun blok 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;

}

Mungkin lebih baik untuk membuat bidang arbitrer dari pengaturan config_pages sebagai lawan untuk menarik data dari sebuah node, tapi saya kira itu benar-benar tergantung pada use-case spesifik mengenai metode mana yang terbaik.


2

Berkat jawaban Rainer Feike saya datang ke solusinya:

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

}

Menggunakan $viewBuilder->viewFieldsaya dapat membuat bidang apa pun secara terpisah yang saya butuhkan. Saya hanya perlu mengetahui cara menambahkan caching tergantung pada pengaturan mode tampilan, tapi ini adalah pertanyaan lain :)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.