Skip to content

Instantly share code, notes, and snippets.

@EclipseGc
Last active December 18, 2015 18:30
Show Gist options
  • Save EclipseGc/5826378 to your computer and use it in GitHub Desktop.
Save EclipseGc/5826378 to your computer and use it in GitHub Desktop.
diff --git a/core/core.services.yml b/core/core.services.yml
index e7aabf8..7832542 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -186,6 +186,9 @@ services:
factory_class: Drupal\Core\Database\Database
factory_method: getConnection
arguments: [slave]
+ context_resolver:
+ class: Drupal\Core\Plugin\Context\ContextResolver
+ arguments: ['@typed_data']
typed_data:
class: Drupal\Core\TypedData\TypedDataManager
calls:
diff --git a/core/lib/Drupal/Core/DisplayController.php b/core/lib/Drupal/Core/DisplayController.php
index 2e4974f..49cb03e 100644
--- a/core/lib/Drupal/Core/DisplayController.php
+++ b/core/lib/Drupal/Core/DisplayController.php
@@ -9,6 +9,7 @@
use Drupal\Core\FragmentRenderer\BlockFragmentRendererInterface;
use Drupal\block\Plugin\Type\BlockManager;
+use Drupal\Core\Plugin\Context\ContextResolver;
use Drupal\layout\Config\UnboundDisplayInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
@@ -71,6 +72,11 @@ class DisplayController {
protected $blockManager;
/**
+ * @var \Drupal\Core\Plugin\Context\ContextResolver
+ */
+ protected $resolver;
+
+ /**
* An array of FragmentRendererInterface objects.
*
* @var array
@@ -85,9 +91,10 @@ class DisplayController {
* @param BlockManager $blockManager
* The BlockManager, used to instantiate blocks.
*/
- public function __construct(ModuleHandlerInterface $moduleHandler, BlockManager $blockManager) {
+ public function __construct(ModuleHandlerInterface $moduleHandler, BlockManager $blockManager, ContextResolver $resolver) {
$this->moduleHandler = $moduleHandler;
$this->blockManager = $blockManager;
+ $this->resolver = $resolver;
}
/**
@@ -148,9 +155,21 @@ public function respond(Request $request, BoundDisplayInterface $_display) {
*/
protected function renderBlocks(Request $request, BoundDisplayInterface $display) {
$blockFragments = array();
+ // Resolve the contexts in the display.
+ $resolutions = $this->resolver->resolveContexts($request, $display->getContextConfigurations());
foreach ($display->getAllOuterBlockConfig() as $id => $config) {
$block = $display->getBlock($id);
-
+ // Check for any expected contexts for this block.
+ $definition = $block->getContextDefinitions();
+ // If there are expected contexts, and the display is providing a map to
+ // contexts it has available, set the context values for the block.
+ if ($definition && isset($config['contexts'])) {
+ foreach ($config['contexts'] as $local_context_slot => $display_context_id) {
+ if (isset($resolutions[$display_context_id])) {
+ $block->setContextValue($local_context_slot, $resolutions[$display_context_id]);
+ }
+ }
+ }
if ($block instanceof SystemMainBlock) {
$block->setControllerClosure($request->attributes->get('_content_closure'));
diff --git a/core/lib/Drupal/Core/Plugin/Context/ContextResolver.php b/core/lib/Drupal/Core/Plugin/Context/ContextResolver.php
new file mode 100644
index 0000000..d153eca
--- /dev/null
+++ b/core/lib/Drupal/Core/Plugin/Context/ContextResolver.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Plugin\Context\ContextResolver.
+ */
+
+namespace Drupal\Core\Plugin\Context;
+
+use Drupal\Core\TypedData\TypedDataManager;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * A class which resolves context configurations.
+ */
+class ContextResolver {
+
+ /**
+ * The typed data manager for resolving contexts.
+ *
+ * @var \Drupal\Core\TypedData\TypedDataManager
+ */
+ protected $manager;
+
+ /**
+ * @param TypedDataManager $manager
+ */
+ public function __construct(TypedDataManager $manager) {
+ $this->manager = $manager;
+ }
+
+ /**
+ * Resolves all the provided context configurations.
+ *
+ * @param Request $request
+ * @param array $contexts
+ * @return array
+ */
+ public function resolveContexts(Request $request, array $contexts) {
+ $resolutions = array();
+ foreach ($contexts as $id => $configuration) {
+ switch ($configuration['contextType']) {
+ case 'static':
+ $resolutions[$id] = $this->staticContexts($configuration);
+ break;
+ case 'argument':
+ // Extract context from the request
+ break;
+ case 'derivative':
+ // Extract context from other contexts.
+ break;
+ }
+ }
+ return $resolutions;
+ }
+
+ /**
+ * Resolve static context configurations.
+ *
+ * @param $configuration
+ */
+ protected function staticContexts($configuration) {
+ return $this->manager->create(array('type' => $configuration['type']), $configuration['value'])->getValue();
+ }
+}
diff --git a/core/modules/block/block.services.yml b/core/modules/block/block.services.yml
index 965f740..86ad282 100644
--- a/core/modules/block/block.services.yml
+++ b/core/modules/block/block.services.yml
@@ -11,7 +11,7 @@ services:
arguments: [block]
display_controller:
class: Drupal\Core\DisplayController
- arguments: ['@module_handler', '@plugin.manager.block']
+ arguments: ['@module_handler', '@plugin.manager.block', '@context_resolver']
tags:
- { name: fragment_handler }
access_check.block:
diff --git a/core/modules/layout/lib/Drupal/layout/Config/DisplayBase.php b/core/modules/layout/lib/Drupal/layout/Config/DisplayBase.php
index 8afab18..b20b2c3 100644
--- a/core/modules/layout/lib/Drupal/layout/Config/DisplayBase.php
+++ b/core/modules/layout/lib/Drupal/layout/Config/DisplayBase.php
@@ -112,6 +112,36 @@
protected $blockManager;
/**
+ * An associated array of context configuration.
+ *
+ * @var array
+ */
+ protected $contexts = array();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContextConfigurations() {
+ return $this->contexts;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContextConfiguration($id) {
+ if (isset($this->contexts[$id])) {
+ return $this->contexts[$id];
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setContextConfiguration($id, $value) {
+ $this->contexts[$id] = $value;
+ }
+
+ /**
* {@inheritdoc}
*
* @todo this makes unserialization of displays hard - though that may not be an issue.
@@ -229,6 +259,7 @@ public function getExportProperties() {
$properties['blockInfo'] = $this->blockInfo;
$properties['embeddedBlockConfigs'] = $this->embeddedBlockConfigs;
$properties['groups'] = $this->groups;
+ $properties['contexts'] = $this->contexts;
return $properties;
}
}
diff --git a/core/modules/layout/lib/Drupal/layout/Config/DisplayInterface.php b/core/modules/layout/lib/Drupal/layout/Config/DisplayInterface.php
index 0f88797..4c7f5c4 100644
--- a/core/modules/layout/lib/Drupal/layout/Config/DisplayInterface.php
+++ b/core/modules/layout/lib/Drupal/layout/Config/DisplayInterface.php
@@ -154,4 +154,33 @@ public function getAllRegionTypes();
* @return void
*/
public function flush();
+
+ /**
+ * Gets the configured contexts.
+ *
+ * @return array
+ * The configuration of all the available contexts.
+ */
+ public function getContextConfigurations();
+
+ /**
+ * Get a specific configured context.
+ *
+ * @param $id
+ * The array key for the desired context.
+ *
+ * @return array
+ * The configuration for the desired context.
+ */
+ public function getContextConfiguration($id);
+
+ /**
+ * Set the configuration of a specific context.
+ *
+ * @param $id
+ * The array key of the context element to set.
+ * @param $value
+ * The value to set for the context element.
+ */
+ public function setContextConfiguration($id, $value);
}
diff --git a/core/profiles/standard/config/display.bound.frontend.yml b/core/profiles/standard/config/display.bound.frontend.yml
index f1db4eb..521422f 100644
--- a/core/profiles/standard/config/display.bound.frontend.yml
+++ b/core/profiles/standard/config/display.bound.frontend.yml
@@ -2,6 +2,11 @@ id: frontend
label: Frontend master display
layout: static_layout:layout__core
layoutSettings: { }
+contexts:
+ url:
+ contextType: static
+ type: string
+ value: node
blockInfo:
# these have bartik in their namespace, but that's irrelevant to our use here -
# we're just reusing them while we get everything together.
@@ -44,6 +49,8 @@ blockInfo:
region-type: main
strategy: inline_block
weight: '-20'
+ contexts:
+ url: url
block.block.bartik.main_menu:
region: header
region-type: header
@@ -66,12 +73,12 @@ blockInfo:
strategy: inline_block
weight: '0'
embedded: '1'
- page_messages1:
- region: main
- region-type: main
- strategy: inline_block
- weight: '0'
- embedded: '1'
+# page_messages1:
+# region: main
+# region-type: main
+# strategy: inline_block
+# weight: '0'
+# embedded: '1'
page_site_name1:
region: header
region-type: header
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment