Browse Source

Issue #2952972 by scotthooker, Chi: Rendering blocks in the same way panels does

merge-requests/4/head
Chi 7 years ago
parent
commit
f8f1a94c22
  1. 63
      src/TwigExtension.php
  2. 10
      tests/src/Functional/TwigTweakTest.php
  3. 3
      tests/twig_tweak_test/templates/twig-tweak-test.html.twig

63
src/TwigExtension.php

@ -3,11 +3,15 @@
namespace Drupal\twig_tweak; namespace Drupal\twig_tweak;
use Drupal\Component\Uuid\Uuid; use Drupal\Component\Uuid\Uuid;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Block\TitleBlockPluginInterface; use Drupal\Core\Block\TitleBlockPluginInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\FieldItemInterface; use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Link; use Drupal\Core\Link;
use Drupal\Core\Plugin\ContextAwarePluginInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Site\Settings; use Drupal\Core\Site\Settings;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\image\Entity\ImageStyle; use Drupal\image\Entity\ImageStyle;
@ -74,23 +78,70 @@ class TwigExtension extends \Twig_Extension {
} }
/** /**
* Builds the render array for the provided block plugin. * Builds the render array for a block.
* *
* @param mixed $id * @param mixed $id
* The ID of block plugin to render. * The string of block plugin to render.
* @param array $configuration * @param array $configuration
* (Optional) Pass on any configuration to the plugin block. * (Optional) Pass on any configuration to the plugin block.
* @param bool $wrapper
* (Optional) Whether or not use block template for rendering.
* *
* @return null|array * @return null|array
* A render array for the block or NULL if the block does not exist. * A render array for the block or NULL if the block cannot be rendered.
*/ */
public function drupalBlock($id, array $configuration = []) { public function drupalBlock($id, array $configuration = [], $wrapper = TRUE) {
$configuration += ['label_display' => BlockPluginInterface::BLOCK_LABEL_VISIBLE];
/** @var \Drupal\Core\Block\BlockPluginInterface $block_plugin */ /** @var \Drupal\Core\Block\BlockPluginInterface $block_plugin */
$block_plugin = \Drupal::service('plugin.manager.block') $block_plugin = \Drupal::service('plugin.manager.block')
->createInstance($id, $configuration); ->createInstance($id, $configuration);
if ($block_plugin->access(\Drupal::currentUser())) {
return $block_plugin->build(); // Inject runtime contexts.
if ($block_plugin instanceof ContextAwarePluginInterface) {
$contexts = \Drupal::service('context.repository')->getRuntimeContexts($block_plugin->getContextMapping());
\Drupal::service('context.handler')->applyContextMapping($block_plugin, $contexts);
} }
if (!$block_plugin->access(\Drupal::currentUser())) {
return;
}
$content = $block_plugin->build();
if ($content && !Element::isEmpty($content)) {
if ($wrapper) {
$build = [
'#theme' => 'block',
'#attributes' => [],
'#contextual_links' => [],
'#configuration' => $block_plugin->getConfiguration(),
'#plugin_id' => $block_plugin->getPluginId(),
'#base_plugin_id' => $block_plugin->getBaseId(),
'#derivative_plugin_id' => $block_plugin->getDerivativeId(),
'content' => $content,
];
}
else {
$build = $content;
}
}
else {
// Preserve cache metadata of empty blocks.
$build = [
'#markup' => '',
'#cache' => $content['#cache'],
];
}
if (!empty($content)) {
CacheableMetadata::createFromRenderArray($build)
->merge(CacheableMetadata::createFromRenderArray($content))
->applyTo($build);
}
return $build;
} }
/** /**

10
tests/src/Functional/TwigTweakTest.php

@ -88,11 +88,19 @@ class TwigTweakTest extends BrowserTestBase {
$xpath = '//div[@class = "tt-view-result" and text() = 3]'; $xpath = '//div[@class = "tt-view-result" and text() = 3]';
$this->assertByXpath($xpath); $this->assertByXpath($xpath);
// Test block plugin. // Test block.
$xpath = '//div[@class = "tt-block"]'; $xpath = '//div[@class = "tt-block"]';
$xpath .= '/img[contains(@src, "/core/themes/classy/logo.svg") and @alt="Home"]'; $xpath .= '/img[contains(@src, "/core/themes/classy/logo.svg") and @alt="Home"]';
$this->assertByXpath($xpath); $this->assertByXpath($xpath);
// Test block with wrapper.
$xpath = '//div[@class = "tt-block-with-wrapper"]';
$xpath .= '/div[@class = "block block-system block-system-branding-block"]';
$xpath .= '/h2[text() = "Branding"]';
$xpath .= '/following-sibling::a[img[contains(@src, "/core/themes/classy/logo.svg") and @alt="Home"]]';
$xpath .= '/following-sibling::div[@class = "site-name"]/a';
$this->assertByXpath($xpath);
// Test region. // Test region.
$xpath = '//div[@class = "tt-region"]/div[@class = "region region-sidebar-first"]'; $xpath = '//div[@class = "tt-region"]/div[@class = "region region-sidebar-first"]';
$xpath .= '/div[contains(@class, "block-page-title-block") and h1[@class="page-title" and text() = "Log in"]]'; $xpath .= '/div[contains(@class, "block-page-title-block") and h1[@class="page-title" and text() = "Log in"]]';

3
tests/twig_tweak_test/templates/twig-tweak-test.html.twig

@ -21,7 +21,8 @@
<div class="tt-view-page_1">{{ drupal_view('twig_tweak_test', 'page_1') }}</div> <div class="tt-view-page_1">{{ drupal_view('twig_tweak_test', 'page_1') }}</div>
<div class="tt-view-page_1-with-argument">{{ drupal_view('twig_tweak_test', 'page_1', 1) }}</div> <div class="tt-view-page_1-with-argument">{{ drupal_view('twig_tweak_test', 'page_1', 1) }}</div>
<div class="tt-view-result">{{ drupal_view_result('twig_tweak_test', 'page_1')|length }}</div> <div class="tt-view-result">{{ drupal_view_result('twig_tweak_test', 'page_1')|length }}</div>
<div class="tt-block">{{ drupal_block('system_branding_block', {use_site_name: false}) }}</div> <div class="tt-block">{{ drupal_block('system_branding_block', {use_site_name: false}, false) }}</div>
<div class="tt-block-with-wrapper">{{ drupal_block('system_branding_block', {label: 'Branding'}) }}</div>
<div class="tt-region">{{ drupal_region('sidebar_first') }}</div> <div class="tt-region">{{ drupal_region('sidebar_first') }}</div>
<div class="tt-entity-default">{{ drupal_entity('node', 1) }}</div> <div class="tt-entity-default">{{ drupal_entity('node', 1) }}</div>
<div class="tt-entity-teaser">{{ drupal_entity('node', 1, 'teaser') }}</div> <div class="tt-entity-teaser">{{ drupal_entity('node', 1, 'teaser') }}</div>

Loading…
Cancel
Save