프로그래밍 방식으로 나뭇 가지 템플릿에서 블록을 렌더링


28

page.html.twig 템플릿에서 뷰 블록을 렌더링해야합니다. D7에서는 다음과 같이합니다.

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

Drupal 8에서 module_invoke는 더 이상 사용되지 않으며 이것을 사용하는 것이 좋습니다. (블록 이름을 두 번째 매개 변수로 추가했습니다)

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

몇 가지 시도했습니다. 먼저 나뭇 가지 템플릿으로 시도했지만 나뭇 가지 템플릿에서 PHP 함수를 호출하는 방법을 모르므로 너무 좋지 않았습니다.

그런 다음 .theme 파일의 preprocess_page () 함수에서 함수를 호출했지만 작동하기 전에 나뭇 가지 템플릿 내에서 변수 작업을 시도하여 작동하지 않는 간단한 작업을 시도했습니다. 예 :

.theme 파일의 template_preprocess_page (& $ vars) 함수에서 :

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

나뭇 가지 템플릿 내에서 my_var를 호출하려고했지만 작동하지 않고 "사이트에 오류가 있습니다. 관리자에게 문의하십시오"라는 오류 메시지가 나타납니다.

요약하면 다음과 같습니다.

  1. 잔가지 템플릿 내에서 변수를 사용할 수있게하려면 어떻게해야합니까?
  2. 잔가지 템플릿 내에서 함수를 어떻게 호출합니까?
  3. .theme 파일 또는 나뭇 가지 템플릿 안에 블록을 렌더링합니까?

답변:


47

module_invoke ()를 잘못 사용하고 있습니다. 이는 {$ module_name} _block_view () 함수를 호출하는 멋진 방법입니다.

그것이 변경되었다는 사실은 중요하지 않습니다. 요점은 블록 시스템이 8.x에서 완전히 변경되었으며 이제 플러그인과 구성 엔티티를 사용하고 있다는 것입니다. 이러한 기능은 더 이상 존재하지 않습니다.

몇 가지 옵션이 있습니다.

a) 기존 블록 구성 엔터티를 재사용하고 봅니다. 매우 쉽지만 구성이 존재해야합니다 (예 : 비활성화 된 블록).

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

b) 블록 플러그인 인스턴스를 직접 생성하고 구성에 전달합니다 (내 보낸 블록 구성 엔티티에서 블록 플러그인 ID 및 구성을 쉽게 찾을 수 있음). 단점은 렌더 캐싱을 얻지 못하지만 이미 캐시 된 (노드 템플릿과 같은) 어딘가에 표시하면 실제로 중요하지 않습니다.

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

c)보기의 경우보기를 직접로드하여 표시 할 수도 있습니다.

d) 접근 방식을 완전히 다시 생각하고 블록 영역 또는 페이지 관리자 (8.x의 표준 블록 플러그인을 사용)를 사용할 수도 있습니다.


답변 주셔서 감사합니다. A 또는 B와 함께 가고 싶습니다. A 지역은 작동하지만 지역 사용을 피하고 싶습니다. 내가 가지고있는 유일한 문제는 나뭇 가지 템플릿에서 block_output을 호출 할 때 오류가 있습니다- "예기치 않은 태그 이름"block_output "이므로 preprocess_page 함수에서 변수를 만들었더라도 해당 변수를 사용 가능하게 만드는 방법을 모르겠습니다. 나는 그것을 시도 할 것입니다
Rick Bergmann

{%? {{block_output}}을 사용하십시오.
Berdir

그렇습니다! 여전히 나뭇 가지를 끊으려고합니다. 감사.
Rick Bergmann

Drupal 8.0.0부터 entityManager 는 더 이상 사용되지 않습니다. entityTypeManager를 대신 사용하십시오 .
Philipp Michael

이 코드를 어디에 두어야합니까? $ block = \ Drupal \ block \ Entity \ Block :: load ( 'your_block_id'); $ variables [ 'block_output'] = \ Drupal :: entityManager ()-> getViewBuilder ( 'block')-> view ($ block); 고맙습니다!

11

Drupal 8에서는 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();
}

그런 다음 다음과 같이 나뭇 가지 템플릿에서 렌더링 할 수 있습니다.

{{ content.custom_block_output }}

참고 : 이렇게하면 블록의 일반 버전이로드됩니다. 변수를 사용하여 블록의 인스턴스를로드하려면 (/ admin / structure / block에서 생성 한 후) 다음과 같이로드해야합니다.

    // 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
이것이 저에게 가장 쉬운 해결책이었습니다.
기 illa 보이스

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.