Görüntüleme modu ayarlarına uygun olarak bir düğümün alanını programlı olarak nasıl oluşturabilirim?


9

Bir düğümün alanını bir blok içinde oluşturmak istiyorum. Şöyle çalışır:

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

Ancak bu, alanı normal şekilde görüntüleyeceğim gibi% 100 değil, görünüm modu ayarlarında görünür olmasını sağlıyor.

Yanıtlar:


0

Bence vizör alana değil, düğüme uygulanmalıdır. Bu yüzden, görünüm oluşturucuyu almanız ve düğümü oluşturmanız gerekir. Daha sonra, düğüm için oluşturulan diziden alan için oluşturulan diziyi seçebilirsiniz. Bunun gibi:

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

PS Her nasılsa @ entity_type.manager hizmeti olarak enjekte edilmelidir "[EntityTypeManager]". Veya $ container-> get ('entity_type.manager') adresinden Block-Plugin create () öğenize ekleyin.


1
tam olarak değil. $nodeviewsahip #nodeanahtar olarak
Alex

1
Ayrıca, bu ayrı alanları değil, düğüm oluşturur
Alex

1
Evet, düğümü (ve tüm alanları) oluşturuyorum. Ancak, görüntüleme modu ayarlarınızda yaptığınız şey budur. Belki sorunuzu yanlış anladım.
Rainer Feike

1
"[youfield-burada] $ nodeview;" boş, en azından Drupal 8.6.x üzerinde
Onkeltem

1
"Burada-alanınızı" alanınızın makine adıyla değiştirin.
Rainer Feike

29

Bir görüntüleme modunun ekran ayarıyla tek bir alan oluşturmak için alan view()yöntemini kullanabilirsiniz :

Görüntüyü teaser biçiminde oluşturmaya örnek:

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

Ya da tam vücut:

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

1
ne yazık ki, bu etiketler ve formatlayıcı ayarları gibi görünüm modu ayarlarına uymuyor
Alex

1
Bu çalışmalıdır, bu komutla dal hata ayıklamasını bile kullanabilirsiniz. Varolan bir görünüm modunu dize olarak sağlarsanız, alan bununla biçimlendirilir. Bir dizi sağlarsanız, örneğin kendi görüntü ayarlarınızı yapabilirsiniz['label' => 'inline' ]
4k4

1
i zaten denedim ama işe yaramadı inanıyorum. tekrar deneyeceğim. şimdiye kadar teşekkürler
Alex

1
Biçimlendiriciye saygı duyduğunu görüyorum, ancak biçimlendirici ayarlarına değil. Bunun çıktısı doğru ayarları içerir.
Grayside

2
bu aslında cevabımı bana verdi. Burada değişkenimi .twig'e alabilirim: $vars['var_name'] = $node_object->field_name->view()[0]; ve sonra dalda , {{var_name}}
bdanin

4

Bu cevap 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);

Arama yaparak bitirdiğiniz alanı tamamen programlı olarak oluşturmak için renderRoot(), tipik sayfa yanıtlarının kullanacağı işlemden ayrı bir oluşturma içeriği oluşturur - bir istek veya alt istek için tek bir oluşturma içeriği. Biz de kullanabilirdik renderPlain(), ama sonra her şeyden kaçacaktı.

Drush yanıtında ama normal sayfa yürütmede değil, bu benim için bir uyarı attı:

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'in cevabı ile ilgili olarak , ben nasıl config_pages kullanmak ve global_footer blok oluşturmak için nasıl değiştirildi :

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

}

Bir düğümden veri çekmenin aksine bir config_pages kurulumundan rastgele alanları oluşturmak muhtemelen daha iyidir, ancak sanırım gerçekten hangi yöntemin en iyi olduğuna dair özel kullanım durumuna bağlıdır.


2

Sayesinde Rainer Feike cevabı I çözüm geldi:

<?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->viewFieldI kullanarak , istediğim alanları ayrı ayrı oluşturabilirim. Sadece görünüm modu ayarlarına bağlı olarak önbellek eklemeyi öğrenmem gerekiyor, ancak bu başka bir soru :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.