以编程方式在树枝模板中渲染块


28

我需要在page.html.twig模板中呈现一个views块。在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()函数中调用了该函数,但是在使它起作用之前,我尝试了一些简单的方法,只是试图使在twig模板中起作用的变量也不起作用,例如:

在.theme文件的template_preprocess_page(&$ vars)函数中:

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

我试图在树枝模板中调用my_var,但是它不起作用,并且收到一条错误消息,提示“该站点有错误,请与管理员联系”。

因此,总而言之,这是我的问题:

  1. 如何使变量在树枝模板中可用?
  2. 如何在树枝模板内调用函数?
  3. 是否在.theme文件或树枝模板内渲染块?

Answers:


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一起使用。一个区域可以使用,但我想避免使用一个区域。我唯一的问题是,当我在树枝模板中调用block_output时,我遇到一个错误-“意外的标记名” block_output”,因此即使我在preprocess_page函数中创建了该变量,我也不知道如何使该变量可用。我会尽力解决的
瑞克·伯格曼

听起来您正在使用{%?使用{{block_output}}。
贝尔迪尔

是的,就是这样!仍在尝试解决问题。谢谢。
里克·伯格曼

自Drupal 8.0.0起,entityManager已弃用。请改用entityTypeManager
菲利普·迈克尔

我在哪里放置此代码?$ 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
这是我的解决方案,也是迄今为止最简单的解决方案。
纪尧姆·布瓦

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.