Answers:
有两种类型的块,呈现两种块的方法略有不同:
内容块是您在界面中创建的块。它们非常类似于节点可配置的数据结构,以及字段等。如果要呈现其中之一,则可以执行与实体一样的常规操作,加载它们并使用视图构建器呈现它们:
$bid = ??? // Get the block id through config, SQL or some other means
$block = \Drupal\block_content\Entity\BlockContent::load($bid);
$render = \Drupal::entityTypeManager()->
getViewBuilder('block_content')->view($block);
return $render;
块也可以是插件,可以在各种模块中定义。一个示例可以是面包屑块。如果要渲染这些,则需要使用块插件管理器。
$block_manager = \Drupal::service('plugin.manager.block');
// You can hard code configuration or you load from settings.
$config = [];
$plugin_block = $block_manager->createInstance('system_breadcrumb_block', $config);
// Some blocks might implement access check.
$access_result = $plugin_block->access(\Drupal::currentUser());
// Return empty render array if user doesn't have access.
// $access_result can be boolean or an AccessResult class
if (is_object($access_result) && $access_result->isForbidden() || is_bool($access_result) && !$access_result) {
// You might need to add some cache tags/contexts.
return [];
}
$render = $plugin_block->build();
// In some cases, you need to add the cache tags/context depending on
// the block implemention. As it's possible to add the cache tags and
// contexts in the render method and in ::getCacheTags and
// ::getCacheContexts methods.
return $render;
两种类型共享的是块,即一旦将它们插入一个区域,您将创建一个配置实体,其中包含该块的所有设置。在某些情况下,处理配置实体会更加有用。由于同一块可以通过不同的配置放置在多个区域中,因此使用块配置实体会变得更加棘手。令人高兴的是,您可能希望使用特定的配置来呈现块,而糟糕的是,可以通过弄乱接口来更改配置ID,因此在允许用户使用块接口后,代码最终可能无法正常工作。
$block = \Drupal\block\Entity\Block::load('config.id');
$render = \Drupal::entityTypeManager()
->getViewBuilder('block')
->view($block);
return $render;
为了只显示模板中带有预处理的块,最好的方法是
$block = \Drupal\block\Entity\Block::load('my_block_id');
$variables['My_region'] = \Drupal::entityManager()
->getViewBuilder('block')
->view($block);
然后在您的page.html.twig
or node.html.twig
或xxx.html.twig
使用变量My_region中,如下所示:
{% if page.My_region %}
{{ page.My_region }}
{% endif %}
并在可渲染数组(自定义模块)中通过示例转换为content()中的控制器自定义:
public function content() {
$block = \Drupal\block\Entity\Block::load('my_block_id');
$block_content = \Drupal::entityManager()
->getViewBuilder('block')
->view($block);
return array(
'#type' => 'container',
'#attributes' => array(
'class' => array("Myclass"),
),
"element-content" => $block_content,
'#weight' => 0,
);
}
使用 这是没有用的,因为Drupal已经假定在D8中进行渲染,因此已弃用。您应该drupal_render
\Drupal::service('renderer')->renderRoot()
改用。
它有点重,最好使用最大面积系统,并且不要在预处理过程中添加负载块。在模块中使用控制器的情况下,这似乎是合理的用法。
element-content
在渲染数组中找不到有关属性的任何文档。您知道在哪里记录吗?
\Drupal\block\Entity\Block::load
不会一直返回一个块。仅当我加载的块以块布局放置在视图中时,它才会返回某些内容。如果未放置,则返回null。
\Drupal::entityTypeManager()->getViewBuilder('block')->view($block);
除了最重要的答案以外...如果要从视图中渲染图块,则可能必须做些不同的事情。
$view = views_embed_view('my_view_name', 'my_display_name');
(显示名称,例如-> block_1)
由于我们将其传递给树枝,因此不需要渲染(使用渲染服务)。
因此,您可以将其作为变量传递给树枝(在此示例中,它是控制器的返回):
return [
['description' => [
'#theme' => 'your_theme_hook',
'#your_variable => $view
]
]
在模块中,您需要为变量添加一个hook_theme():
function hook_theme($existing, $type, $theme, $path) {
return array(
'your_theme_hook' => array(
'variables' => [
'your_variable' => NULL,
]
)
)
}
最后在您的树枝模板中:
{{ your_variable }}
我需要获取自定义块的HTML并使用以下代码获取它:
$con = \Drupal\block\BlockViewBuilder::lazyBuilder('bartik_search', 'full');
$d = \Drupal::service('renderer')->renderPlain($con);
print $d->__toString();
__toString()
。
// You need a block_id! to get it just click configure in the desire block and you'll get url like this /admin/structure/block/manage/bartik_search the last part of the parameter is the block id
$block = \Drupal\block\Entity\Block::load('bartik_search');
$block_content = \Drupal::entityManager()
->getViewBuilder('block')
->view($block);
return array('#markup' => \Drupal::service('renderer')->renderRoot($block_content));
drupal_render
或渲染服务。drupal_render
被废弃,但是用渲染的内容重现一个渲染数组是很糟糕的,您应该返回$block_content
,可以在实际渲染之前更改渲染数组,并且应该让Drupal尽可能多地渲染渲染,或者自己做。
基本上,有两种类型的渲染。
布局中存在该块的现有实例时。可以使用预处理将块渲染为树枝
$ block = Block :: load('BLOCK_ID'); $ variables ['social_links'] = \ Drupal :: entityTypeManager()-> getViewBuilder('block')-> view($ block);
该块没有实例或配置。然后在预处理器中,我们需要创建实例,构建块,然后渲染它
$ block_manager = \ Drupal :: service('plugin.manager.block'); $ config = []; $ plugin_block = $ block_manager-> createInstance('farmjournal_social_sharing',$ config); $ render = $ plugin_block-> build(); $ variables ['farmjournal_social_sharing'] = render($ render);
您将获得块输出:
$block = \Drupal\block\Entity\Block::load ('my_bock_id');
$block_content = \Drupal::entityManager ()->
getViewBuilder ('block')->
view ($block);
然后您可能会以不同的方式返回输出:
return array (
'#type' => 'container',
'element-content' => $block_content
);
要么:
return ['#markup' => \Drupal::service ('renderer')->render ($block_content)];
\Drupal::service ('renderer')->render ($block_content)
可以进行作为drupal_render ($block_content)
然而后者在Drupal 8.弃用
drupal_render
或渲染服务。drupal_render
被废弃,但是用渲染的内容重现一个渲染数组是很糟糕的,您应该返回$block_content
,可以在实际渲染之前更改渲染数组,并且应该让Drupal尽可能多地渲染渲染,或者自己做。您返回的内容需要再次渲染,这使实际渲染毫无意义
根据我的研究,您可以基于如何在drupal 8中以编程方式渲染块中的代码。你也可以改变
return array('#markup' => \Drupal::service('renderer')->renderRoot($block_content));
变成简单的东西:
$output .= \Drupal::service('renderer')->renderRoot($block_content);
例如将其附加到页面的返回变量中。
drupal_render
或渲染服务。drupal_render
被废弃,但是用渲染的内容重现一个渲染数组是很糟糕的,您应该返回$block_content
,可以在实际渲染之前更改渲染数组,并且应该让Drupal尽可能多地渲染渲染,或者自己做。