Browse Source

Issue #2845763 by landsman: Provide drupal_region function

8.x-1.x
Chi 8 years ago
parent
commit
9beab87c16
  1. 63
      src/TwigExtension.php
  2. 17
      tests/src/Functional/TwigTweakTest.php
  3. 17
      tests/twig_tweak_test/config/install/block.block.classy_page_title.yml
  4. 19
      tests/twig_tweak_test/config/install/block.block.classy_powered_by_drupal.yml
  5. 19
      tests/twig_tweak_test/config/install/block.block.classy_status_messages.yml
  6. 1
      tests/twig_tweak_test/templates/twig-tweak-test.html.twig
  7. 9
      twig_tweak.services.yml

63
src/TwigExtension.php

@ -2,13 +2,17 @@
namespace Drupal\twig_tweak;
use Drupal\Core\Block\TitleBlockPluginInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Controller\TitleResolverInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Menu\MenuLinkTreeInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Site\Settings;
use Drupal\Core\Utility\Token;
use Drupal\image\Entity\ImageStyle;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Twig extension with some useful functions and filters.
@ -50,6 +54,20 @@ class TwigExtension extends \Twig_Extension {
*/
protected $menuTree;
/**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* The title resolver.
*
* @var \Drupal\Core\Controller\TitleResolverInterface
*/
protected $titleResolver;
/**
* TwigExtension constructor.
*
@ -63,13 +81,19 @@ class TwigExtension extends \Twig_Extension {
* The route match.
* @param \Drupal\Core\Menu\MenuLinkTreeInterface $menu_tree
* The menu tree service.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
* @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver
* The title resolver.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, Token $token, ConfigFactoryInterface $config_factory, RouteMatchInterface $route_match, MenuLinkTreeInterface $menu_tree) {
public function __construct(EntityTypeManagerInterface $entity_type_manager, Token $token, ConfigFactoryInterface $config_factory, RouteMatchInterface $route_match, MenuLinkTreeInterface $menu_tree, RequestStack $request_stack, TitleResolverInterface $title_resolver) {
$this->entityTypeManager = $entity_type_manager;
$this->token = $token;
$this->configFactory = $config_factory;
$this->routeMatch = $route_match;
$this->menuTree = $menu_tree;
$this->requestStack = $request_stack;
$this->titleResolver = $title_resolver;
}
/**
@ -79,6 +103,7 @@ class TwigExtension extends \Twig_Extension {
return [
new \Twig_SimpleFunction('drupal_view', 'views_embed_view'),
new \Twig_SimpleFunction('drupal_block', [$this, 'drupalBlock']),
new \Twig_SimpleFunction('drupal_region', [$this, 'drupalRegion']),
new \Twig_SimpleFunction('drupal_token', [$this, 'drupalToken']),
new \Twig_SimpleFunction('drupal_entity', [$this, 'drupalEntity']),
new \Twig_SimpleFunction('drupal_field', [$this, 'drupalField']),
@ -113,6 +138,42 @@ class TwigExtension extends \Twig_Extension {
return 'twig_tweak';
}
/**
* Builds the render array of a given region.
*
* @param string $region
* The region to build.
* @param string $theme
* (Optional) The name of the theme to load the region. If it is not
* provided default site theme will be used.
*
* @return array
* A render array to display the region content.
*/
public function drupalRegion($region, $theme = NULL) {
$blocks = $this->entityTypeManager->getStorage('block')->loadByProperties([
'region' => $region,
'theme' => $theme ?: $this->configFactory->get('system.theme')->get('default'),
]);
$view_builder = $this->entityTypeManager->getViewBuilder('block');
$build = [];
/* @var $blocks \Drupal\block\BlockInterface[] */
foreach ($blocks as $id => $block) {
$block_plugin = $block->getPlugin();
if ($block_plugin instanceof TitleBlockPluginInterface) {
$request = $this->requestStack->getCurrentRequest();
if ($route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT)) {
$block_plugin->setTitle($this->titleResolver->getTitle($request, $route));
}
}
$build[$id] = $view_builder->view($block);
}
return $build;
}
/**
* Builds the render array for the provided block.
*

17
tests/src/Functional/TwigTweakTest.php

@ -77,7 +77,6 @@ class TwigTweakTest extends BrowserTestBase {
// Test loading entity from url.
$xpath = '//div[@class = "tt-entity-from-url" and . = ""]';
$this->assertByXpath($xpath);
$this->drupalGet('/node/2');
$xpath = '//div[@class = "tt-entity-from-url"]';
$xpath .= '/article[contains(@class, "node")]';
@ -100,6 +99,13 @@ class TwigTweakTest extends BrowserTestBase {
$xpath = '//div[@class = "tt-menu-depth"]/ul[@class = "menu"]/li[not(ul)]/a[. = "Link 1"]';
$this->assertByXpath($xpath);
// Test region.
$xpath = '//div[@class = "tt-region"]';
$xpath .= '/div[contains(@class, "block-page-title-block") and h1[@class="page-title" and . = "Beta"]]';
$xpath .= '/following-sibling::div[@class="messages messages--warning" and contains(., "Hi!")]';
$xpath .= '/following-sibling::div[contains(@class, "block-system-powered-by-block")]/span[. = "Powered by Drupal"]';
$this->assertByXpath($xpath);
// Test block.
$xpath = '//div[@class = "tt-block"]';
$xpath .= '/div[@id="block-powered-by-drupal"]/span[contains(., "Powered by Drupal")]';
@ -141,4 +147,13 @@ class TwigTweakTest extends BrowserTestBase {
$this->assertSession()->elementExists('xpath', $xpath);
}
/**
* {@inheritdoc}
*/
protected function drupalGet($path, array $options = [], array $headers = []) {
// Title block rendered through drupal_region() is cached by some reason.
\Drupal::service('cache_tags.invalidator')->invalidateTags(['block_view']);
return parent::drupalGet($path, $options, $headers);
}
}

17
tests/twig_tweak_test/config/install/block.block.classy_page_title.yml

@ -0,0 +1,17 @@
langcode: en
status: true
dependencies:
theme:
- classy
id: classy_page_title
theme: classy
region: sidebar_first
weight: 0
provider: null
plugin: page_title_block
settings:
id: page_title_block
label: 'Page title'
provider: core
label_display: '0'
visibility: { }

19
tests/twig_tweak_test/config/install/block.block.classy_powered_by_drupal.yml

@ -0,0 +1,19 @@
langcode: en
status: true
dependencies:
module:
- system
theme:
- classy
id: classy_powered_by_drupal
theme: classy
region: sidebar_first
weight: 20
provider: null
plugin: system_powered_by_block
settings:
id: system_powered_by_block
label: 'Powered by Drupal'
provider: system
label_display: '0'
visibility: { }

19
tests/twig_tweak_test/config/install/block.block.classy_status_messages.yml

@ -0,0 +1,19 @@
langcode: en
status: true
dependencies:
module:
- system
theme:
- classy
id: classy_status_messages
theme: classy
region: sidebar_first
weight: 10
provider: null
plugin: system_messages_block
settings:
id: system_messages_block
label: 'Status messages'
provider: system
label_display: '0'
visibility: { }

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

@ -9,6 +9,7 @@
<div class="tt-menu-default">{{ drupal_menu('twig-tweak-test') }}</div>
<div class="tt-menu-level">{{ drupal_menu('twig-tweak-test', 2) }}</div>
<div class="tt-menu-depth">{{ drupal_menu('twig-tweak-test', 1, 1) }}</div>
<div class="tt-region">{{ drupal_region('sidebar_first') }}</div>
<div class="tt-block">{{ drupal_block('powered_by_drupal') }}</div>
<div class="tt-token">{{ drupal_token('site:name') }}</div>
<div class="tt-token-data">{{ drupal_token('node:title', {'node': node}) }}</div>

9
twig_tweak.services.yml

@ -1,6 +1,13 @@
services:
twig_tweak.twig_extension:
class: Drupal\twig_tweak\TwigExtension
arguments: ['@entity_type.manager', '@token', '@config.factory', '@current_route_match', '@menu.link_tree', '@menu.active_trail']
arguments:
- '@entity_type.manager'
- '@token'
- '@config.factory'
- '@current_route_match'
- '@menu.link_tree'
- '@request_stack'
- '@title_resolver'
tags:
- { name: twig.extension }

Loading…
Cancel
Save