diff --git a/core/core.services.yml b/core/core.services.yml index 1d3ee43..da50e1a 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -376,3 +376,5 @@ services: class: Drupal\system\Plugin\ImageToolkitInterface factory_method: getDefaultToolkit factory_service: image.toolkit.manager + breadcrumb: + class: Drupal\Core\Breadcrumb\BreadcrumbManager diff --git a/core/lib/Drupal/Core/Breadcrumb/BreadcrumbBuilderInterface.php b/core/lib/Drupal/Core/Breadcrumb/BreadcrumbBuilderInterface.php new file mode 100644 index 0000000..c19100e --- /dev/null +++ b/core/lib/Drupal/Core/Breadcrumb/BreadcrumbBuilderInterface.php @@ -0,0 +1,29 @@ +builders[$priority][] = $builder; + } + + /** + * Implements Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface::build(). + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The HttpRequest object representing the current request. + * + * @return array|FALSE|NULL + * A render array for the breacrumb, or + * FALSE, if one of the builders explicitly wants no breadcrumb, or + * NULL, if no plugin found a breadcrumb. + * In the general use case, FALSE and NULL will have the same effect. + */ + public function build(Request $request) { + // Call the build method of all breadcrumb builders. + foreach ($this->getSortedBuilders() as $builder) { + $breadcrumb = $builder->build($request); + if (isset($breadcrumb)) { + // $breadcrumb may be either a render array, + // or FALSE, to suppress the breadcrumbs on this page. + return $breadcrumb; + } + } + } + + /** + * Returns the sorted array of breadcrumb builders. + * + * @return array + * An array of breadcrumb builder objects. + */ + protected function getSortedBuilders() { + if (!isset($this->sortedBuilders)) { + // Sort the builders according to priority. + krsort($this->builders); + // Merge the nested $this->builders array into $this->sortedBuilders. + $this->sortedBuilders = array(); + foreach ($this->builders as $builders) { + $this->sortedBuilders = array_merge($this->sortedBuilders, $builders); + } + } + return $this->sortedBuilders; + } +} diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php index 8734772..58a0f75 100644 --- a/core/lib/Drupal/Core/CoreBundle.php +++ b/core/lib/Drupal/Core/CoreBundle.php @@ -16,6 +16,7 @@ use Drupal\Core\DependencyInjection\Compiler\RegisterRouteEnhancersPass; use Drupal\Core\DependencyInjection\Compiler\RegisterParamConvertersPass; use Drupal\Core\DependencyInjection\Compiler\RegisterServicesForDestructionPass; +use Drupal\Core\DependencyInjection\Compiler\RegisterBreadcrumbBuilderPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Reference; @@ -62,6 +63,9 @@ public function build(ContainerBuilder $container) { // Add the compiler pass that will process the tagged services. $container->addCompilerPass(new RegisterPathProcessorsPass()); $container->addCompilerPass(new ListCacheBinsPass()); + // Add the compiler pass that will process the tagged breadcrumb builder + // services. + $container->addCompilerPass(new RegisterBreadcrumbBuilderPass()); } /** diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterBreadcrumbBuilderPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterBreadcrumbBuilderPass.php new file mode 100644 index 0000000..c123b53 --- /dev/null +++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterBreadcrumbBuilderPass.php @@ -0,0 +1,30 @@ +hasDefinition('breadcrumb')) { + return; + } + $manager = $container->getDefinition('breadcrumb'); + foreach ($container->findTaggedServiceIds('breadcrumb_builder') as $id => $attributes) { + $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; + $manager->addMethodCall('addBuilder', array(new Reference($id), $priority)); + } + } +} diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkBreadcrumbBuilder.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkBreadcrumbBuilder.php new file mode 100644 index 0000000..5002b64 --- /dev/null +++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkBreadcrumbBuilder.php @@ -0,0 +1,44 @@ + 'breadcrumb', + '#breadcrumb' => $breadcrumb, + ); + } + else { + // $breadcrumb is expected to be FALSE or NULL. + return $breadcrumb; + } + } +} diff --git a/core/modules/menu_link/menu_link.services.yml b/core/modules/menu_link/menu_link.services.yml new file mode 100644 index 0000000..a428476 --- /dev/null +++ b/core/modules/menu_link/menu_link.services.yml @@ -0,0 +1,5 @@ +services: + menu_link.breadcrumb: + class: Drupal\menu_link\MenuLinkBreadcrumbBuilder + tags: + - { name: breadcrumb_builder, priority: 0 } diff --git a/core/modules/system/lib/Drupal/system/LegacyBreadcrumbBuilder.php b/core/modules/system/lib/Drupal/system/LegacyBreadcrumbBuilder.php new file mode 100644 index 0000000..d7ea9bd --- /dev/null +++ b/core/modules/system/lib/Drupal/system/LegacyBreadcrumbBuilder.php @@ -0,0 +1,47 @@ + 'breadcrumb', + '#breadcrumb' => $breadcrumb, + ); + } + else { + // $breadcrumb is expected to be FALSE or NULL. + return $breadcrumb; + } + } +} diff --git a/core/modules/system/lib/Drupal/system/Plugin/block/block/SystemBreadcrumbBlock.php b/core/modules/system/lib/Drupal/system/Plugin/block/block/SystemBreadcrumbBlock.php new file mode 100644 index 0000000..1420199 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Plugin/block/block/SystemBreadcrumbBlock.php @@ -0,0 +1,42 @@ +build($request); + if (!empty($breadcrumb)) { + // $breadcrumb is expected to be a render array. + return $breadcrumb; + } + } +} diff --git a/core/modules/system/system.services.yml b/core/modules/system/system.services.yml index bf43cd4..7f36e61 100644 --- a/core/modules/system/system.services.yml +++ b/core/modules/system/system.services.yml @@ -6,3 +6,7 @@ services: plugin.manager.system.plugin_ui: class: Drupal\system\Plugin\Type\PluginUIManager arguments: ['%container.namespaces%'] + system.breadcrumb.legacy: + class: Drupal\system\LegacyBreadcrumbBuilder + tags: + - {name: breadcrumb_builder, priority: 500} diff --git a/core/profiles/standard/config/block.block.bartik.breadcrumbs.yml b/core/profiles/standard/config/block.block.bartik.breadcrumbs.yml new file mode 100644 index 0000000..42d5083 --- /dev/null +++ b/core/profiles/standard/config/block.block.bartik.breadcrumbs.yml @@ -0,0 +1,18 @@ +id: bartik.breadcrumbs +label: Breadcrumbs +label_display: '0' +region: content +weight: '' +module: system +status: '1' +visibility: + path: + visibility: '0' + pages: '' + role: + roles: { } +plugin: system_breadcrumb_block +settings: + admin_label: Breadcrumbs + cache: '-1' +langcode: en diff --git a/core/profiles/standard/config/block.block.seven.breadcrumbs.yml b/core/profiles/standard/config/block.block.seven.breadcrumbs.yml new file mode 100644 index 0000000..cf2b504 --- /dev/null +++ b/core/profiles/standard/config/block.block.seven.breadcrumbs.yml @@ -0,0 +1,18 @@ +id: seven.breadcrumbs +label: Breadcrumbs +label_display: '0' +region: content +weight: '' +module: system +status: '1' +visibility: + path: + visibility: '0' + pages: '' + role: + roles: { } +plugin: system_breadcrumb_block +settings: + admin_label: Breadcrumbs + cache: '-1' +langcode: en