Secara render merender blok dalam templat ranting

28

Saya perlu merender blok views di halaman saya.html.twig template Di D7 saya akan melakukan ini:

<?php
  $block = module_invoke('module_name', 'block_view', 'block_delta');
  print render($block['content']);
?>

Dalam Drupal 8 module_invoke sudah usang dan disarankan untuk menggunakan ini: (Saya telah menambahkan nama blok sebagai parameter kedua)

Drupal::moduleHandler()->invoke($block, 'views_block__blog_block_1', $args = array());

Saya mencoba beberapa hal. Pertama mencoba melakukannya dalam ranting template tetapi saya tidak tahu bagaimana memanggil fungsi-fungsi php dalam ranting template, sehingga tidak berjalan dengan baik.

Kemudian saya memanggil fungsi dalam fungsi preprocess_page () dalam file tema. Tetapi sebelum saya bisa membuatnya berfungsi, saya mencoba sesuatu yang lebih sederhana hanya untuk mencoba membuat variabel bekerja di dalam ranting templat yang tidak berfungsi dengan baik, misalnya:

Dalam fungsi template_preprocess_page (& $ vars) dalam file .theme:

$test = 'Hello World';
$vars['$my_var'] = $test;

Saya mencoba memanggil my_var di dalam template ranting tetapi tidak berhasil dan saya mendapat pesan kesalahan yang mengatakan "Situs ini memiliki kesalahan, silakan hubungi administrator"

Jadi, untuk meringkas, inilah pertanyaan saya:

  1. Bagaimana cara membuat variabel tersedia di dalam templat ranting?
  2. Bagaimana cara saya memanggil fungsi di dalam ranting template?
  3. Apakah saya membuat blok di dalam file tema. Atau template ranting?
Rick Bergmann
sumber

Jawaban:

47

Anda salah jalur dengan module_invoke (). Itu hanya cara yang bagus untuk memanggil fungsi {$ module_name} _block_view ().

Fakta bahwa itu berubah tidak masalah, intinya adalah bahwa sistem blok benar-benar berubah pada 8.x dan sekarang menggunakan plugins dan entitas konfigurasi, fungsi-fungsi itu tidak ada lagi.

Anda punya beberapa pilihan.

a) Gunakan kembali entitas konfigurasi blok yang ada dan lihat. Sangat mudah, tetapi mengharuskan konfigurasi itu ada, misalnya sebagai blok yang dinonaktifkan.

$block = \Drupal\block\Entity\Block::load('your_block_id');
$variables['block_output'] = \Drupal::entityTypeManager()
  ->getViewBuilder('block')
  ->view($block);

b) Buat instance plugin blok secara langsung, berikan konfigurasi (Anda dapat menemukan id plugin blok dan konfigurasi dengan mudah di entitas konfigurasi blok yang diekspor). Kelemahannya adalah Anda tidak mendapatkan render caching, tetapi jika Anda menampilkannya di suatu tempat yang sudah di-cache (seperti templat simpul), itu tidak masalah.

$variables['block_output'] = \Drupal::service('plugin.manager.block')
  ->createInstance($plugin, $configuration)
  ->build();

c) Dalam hal tampilan, Anda juga dapat memuat tampilan secara langsung dan menampilkannya.

d) Anda juga dapat memikirkan kembali pendekatan Anda sepenuhnya dan menggunakan wilayah blok atau Pengelola Halaman (yang menggunakan plugin blok standar di 8.x).

Berdir
sumber
Terima kasih atas jawaban Anda. Saya ingin pergi dengan A atau B. Wilayah akan bekerja tetapi saya ingin menghindari menggunakan suatu daerah. Satu-satunya masalah yang saya alami adalah ketika saya memanggil block_output dalam templat ranting saya memiliki kesalahan - "Nama tag tak terduga" block_output "jadi saya tidak tahu bagaimana membuat variabel itu tersedia walaupun saya membuatnya dalam fungsi preprocess_page. Saya akan mencoba menyelesaikannya
Rick Bergmann
Sepertinya Anda menggunakan {%? Gunakan {{block_output}}.
Berdir
Ya, itu dia! Masih berusaha memahami ranting. Terima kasih.
Rick Bergmann
Karena Drupal 8.0.0 entitasManager sudah tidak digunakan lagi. Gunakan entitasTypeManager sebagai gantinya.
Philipp Michael
di mana saya meletakkan kode ini? $ block = \ Drupal \ block \ Entity \ Block :: load ('your_block_id'); $ variabel ['block_output'] = \ Drupal :: entityManager () -> getViewBuilder ('block') -> view ($ block); Terima kasih!
11

Di Drupal 8, ini berfungsi untuk merender plugin blok (yaitu, yang Anda buat dalam modul khusus) di preprocess_hook:

function mymodule_preprocess_something(array &$variables) {
  $customblock = \Drupal::service('plugin.manager.block')->createInstance('my_custom_block', []);
  $variables['content']['custom_block_output'] = $customblock->build();
}

Anda kemudian dapat merendernya di templat ranting Anda seperti ini:

{{ content.custom_block_output }}

Catatan: ini akan memuat versi generik dari blok Anda. Jika Anda ingin memuat instance dari blok Anda dengan variabel (setelah Anda membuatnya di / admin / struktur / blok), Anda harus memuatnya dengan cara ini:

    // Load Instance of custom block with variables
    $example_block = \Drupal::entityManager()->getStorage('block')->load('example_block_machine_name');
    if (!empty($example_block)){
      $example_block_content = \Drupal::entityManager()
        ->getViewBuilder('block')
        ->view($example_block);
      if ($example_block_content) {
        // Add block content to build array
        $variables['content']['custom_block_output'] = $example_block_content;
      }
    }
oknate
sumber
1
Ini adalah solusi bagi saya dan sejauh ini yang paling mudah.
Guillaume Bois