Lập trình kết xuất một khối trong mẫu twig


28

Tôi cần kết xuất khối lượt xem trong mẫu page.html.twig của mình. Trong D7 tôi sẽ làm điều này:

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

Trong Drupal 8 module_invoke không được dùng nữa và nên sử dụng cái này: (Tôi đã thêm tên của khối làm tham số thứ hai)

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

Tôi đã thử một vài điều. Đầu tiên đã thử làm điều đó trong một mẫu twig nhưng tôi không biết cách gọi các hàm php trong một mẫu twig, vì vậy điều đó không thành công lắm.

Sau đó, tôi đã gọi hàm trong hàm pre process_page () trong tệp .theme nhưng trước khi tôi có thể làm cho nó hoạt động, tôi đã thử một cái gì đó đơn giản hơn chỉ để thử làm một biến hoạt động trong khuôn mẫu twig không hoạt động, ví dụ:

Trong hàm template_pre process_page (& $ vars) trong tệp .theme:

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

Tôi đã cố gắng gọi my_var bên trong mẫu twig nhưng nó không hoạt động và tôi nhận được thông báo lỗi "Trang web có lỗi, vui lòng liên hệ với quản trị viên"

Vì vậy, để tóm tắt, đây là câu hỏi của tôi:

  1. Làm cách nào để tạo các biến có sẵn trong các mẫu twig?
  2. Làm cách nào để gọi các hàm bên trong các mẫu twig?
  3. Tôi có kết xuất các khối bên trong tệp .theme hoặc mẫu twig không?

Câu trả lời:


47

Bạn đang đi sai hướng với module_invoke (). Đó chỉ là một cách ưa thích để gọi hàm {$ module_name} _block_view ().

Thực tế là nó đã thay đổi không thành vấn đề, vấn đề là hệ thống khối đã thay đổi hoàn toàn trong 8.x và hiện đang sử dụng các plugin và các thực thể cấu hình, các chức năng đó không còn tồn tại.

Bạn có một vài lựa chọn.

a) Sử dụng lại một thực thể cấu hình khối hiện có và xem nó. Rất dễ dàng, nhưng yêu cầu cấu hình đó tồn tại, ví dụ như một khối bị vô hiệu hóa.

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

b) Tạo trực tiếp phiên bản plugin khối, chuyển cấu hình (bạn có thể dễ dàng tìm thấy id và cấu hình plugin của khối trong thực thể cấu hình khối được xuất). Nhược điểm là bạn không nhận được kết xuất bộ nhớ đệm, nhưng nếu bạn hiển thị nó ở đâu đó đã được lưu trong bộ nhớ cache (như mẫu nút), điều đó không thực sự quan trọng.

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

c) Trong trường hợp xem, bạn cũng có thể tải chế độ xem trực tiếp và hiển thị nó.

d) Bạn cũng có thể suy nghĩ lại cách tiếp cận của mình hoàn toàn và sử dụng các vùng khối hoặc Trình quản lý trang (sử dụng các plugin khối tiêu chuẩn trong 8.x).


Cảm ơn bạn vì câu trả lời. Tôi muốn đi với A hoặc B. Vùng sẽ hoạt động nhưng tôi muốn tránh sử dụng vùng. Vấn đề duy nhất tôi gặp phải là khi tôi gọi blockDefput trong mẫu twig tôi gặp lỗi - "Tên thẻ không mong đợi" blockDefput "vì vậy tôi không biết làm thế nào để biến đó có sẵn ngay cả khi tôi đã tạo nó trong hàm pre process_page. Tôi sẽ thử làm việc đó.
Rick Bergmann

Âm thanh như bạn đang sử dụng {%? Sử dụng {{blockDefput}}.
Berdir

Vâng, chính là nó! Vẫn đang cố gắng để có được hang của cành. Cảm ơn.
Rick Bergmann

Vì thực thể Drupal 8.0.0 không được dùng nữa. Sử dụng entityTypeManager thay thế.
Philipp Michael

Tôi để mã này ở đâu? $ block = \ Drupal \ block \ Entity \ Block :: load ('your_block_id'); $ biến ['blockDefput'] = \ Drupal :: entityManager () -> getViewBuilder ('block') -> view ($ block); Cảm ơn bạn!

11

Trong Drupal 8, công cụ này hoạt động để hiển thị một plugin khối (nghĩa là một plugin mà bạn đã tạo trong một mô-đun tùy chỉnh) trong một pre process_hook:

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

Sau đó, bạn có thể kết xuất nó trong mẫu twig của mình như thế này:

{{ content.custom_block_output }}

Lưu ý: điều này sẽ tải lên một phiên bản chung của khối của bạn. Nếu bạn muốn tải lên một thể hiện của khối của mình bằng các biến (sau khi bạn đã tạo nó tại / admin / architecture / block), bạn phải tải nó theo cách này:

    // 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;
      }
    }

1
Đây là giải pháp cho tôi và cho đến nay là cách dễ nhất.
Guillaume Bois

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.