block.api.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <?php
  2. /**
  3. * @file
  4. * Hooks provided by the Block module.
  5. */
  6. use Drupal\Core\Access\AccessResult;
  7. /**
  8. * @defgroup block_api Block API
  9. * @{
  10. * Information about the classes and interfaces that make up the Block API.
  11. *
  12. * Blocks are a combination of a configuration entity and a plugin. The
  13. * configuration entity stores placement information (theme, region, weight) and
  14. * any other configuration that is specific to the block. The block plugin does
  15. * the work of rendering the block's content for display.
  16. *
  17. * To define a block in a module you need to:
  18. * - Define a Block plugin by creating a new class that implements the
  19. * \Drupal\Core\Block\BlockPluginInterface, in namespace Plugin\Block under your
  20. * module namespace. For more information about creating plugins, see the
  21. * @link plugin_api Plugin API topic. @endlink
  22. * - Usually you will want to extend the \Drupal\Core\Block\BlockBase class, which
  23. * provides a common configuration form and utility methods for getting and
  24. * setting configuration in the block configuration entity.
  25. * - Block plugins use the annotations defined by
  26. * \Drupal\Core\Block\Annotation\Block. See the
  27. * @link annotation Annotations topic @endlink for more information about
  28. * annotations.
  29. *
  30. * The Block API also makes use of Condition plugins, for conditional block
  31. * placement. Condition plugins have interface
  32. * \Drupal\Core\Condition\ConditionInterface, base class
  33. * \Drupal\Core\Condition\ConditionPluginBase, and go in plugin namespace
  34. * Plugin\Condition. Again, see the Plugin API and Annotations topics for
  35. * details of how to create a plugin class and annotate it.
  36. *
  37. * There are also several block-related hooks, which allow you to affect
  38. * the content and access permissions for blocks:
  39. * - hook_block_view_alter()
  40. * - hook_block_view_BASE_BLOCK_ID_alter()
  41. * - hook_block_access()
  42. *
  43. * Further information and examples:
  44. * - \Drupal\system\Plugin\Block\SystemPoweredByBlock provides a simple example
  45. * of defining a block.
  46. * - \Drupal\user\Plugin\Condition\UserRole is a straightforward example of a
  47. * block placement condition plugin.
  48. * - \Drupal\book\Plugin\Block\BookNavigationBlock is an example of a block with
  49. * a custom configuration form.
  50. * - For a more in-depth discussion of the Block API, see
  51. * https://www.drupal.org/developing/api/8/block_api.
  52. * - The Examples for Developers project also provides a Block example in
  53. * https://www.drupal.org/project/examples.
  54. * @}
  55. */
  56. /**
  57. * @addtogroup hooks
  58. * @{
  59. */
  60. /**
  61. * Alter the result of \Drupal\Core\Block\BlockBase::build().
  62. *
  63. * This hook is called after the content has been assembled in a structured
  64. * array and may be used for doing processing which requires that the complete
  65. * block content structure has been built.
  66. *
  67. * If the module wishes to act on the rendered HTML of the block rather than
  68. * the structured content array, it may use this hook to add a #post_render
  69. * callback. Alternatively, it could also implement hook_preprocess_HOOK() for
  70. * block.html.twig. See drupal_render() documentation or the
  71. * @link themeable Default theme implementations topic @endlink for details.
  72. *
  73. * In addition to hook_block_view_alter(), which is called for all blocks, there
  74. * is hook_block_view_BASE_BLOCK_ID_alter(), which can be used to target a
  75. * specific block or set of similar blocks.
  76. *
  77. * @param array &$build
  78. * A renderable array of data, as returned from the build() implementation of
  79. * the plugin that defined the block:
  80. * - #title: The default localized title of the block.
  81. * @param \Drupal\Core\Block\BlockPluginInterface $block
  82. * The block plugin instance.
  83. *
  84. * @see hook_block_view_BASE_BLOCK_ID_alter()
  85. * @see entity_crud
  86. *
  87. * @ingroup block_api
  88. */
  89. function hook_block_view_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
  90. // Remove the contextual links on all blocks that provide them.
  91. if (isset($build['#contextual_links'])) {
  92. unset($build['#contextual_links']);
  93. }
  94. }
  95. /**
  96. * Provide a block plugin specific block_view alteration.
  97. *
  98. * In this hook name, BASE_BLOCK_ID refers to the block implementation's plugin
  99. * id, regardless of whether the plugin supports derivatives. For example, for
  100. * the \Drupal\system\Plugin\Block\SystemPoweredByBlock block, this would be
  101. * 'system_powered_by_block' as per that class's annotation. And for the
  102. * \Drupal\system\Plugin\Block\SystemMenuBlock block, it would be
  103. * 'system_menu_block' as per that class's annotation, regardless of which menu
  104. * the derived block is for.
  105. *
  106. * @param array $build
  107. * A renderable array of data, as returned from the build() implementation of
  108. * the plugin that defined the block:
  109. * - #title: The default localized title of the block.
  110. * @param \Drupal\Core\Block\BlockPluginInterface $block
  111. * The block plugin instance.
  112. *
  113. * @see hook_block_view_alter()
  114. * @see entity_crud
  115. *
  116. * @ingroup block_api
  117. */
  118. function hook_block_view_BASE_BLOCK_ID_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
  119. // Change the title of the specific block.
  120. $build['#title'] = t('New title of the block');
  121. }
  122. /**
  123. * Alter the result of \Drupal\Core\Block\BlockBase::build().
  124. *
  125. * Unlike hook_block_view_alter(), this hook is called very early, before the
  126. * block is being assembled. Therefore, it is early enough to alter the
  127. * cacheability metadata (change #cache), or to explicitly placeholder the block
  128. * (set #create_placeholder).
  129. *
  130. * In addition to hook_block_build_alter(), which is called for all blocks,
  131. * there is hook_block_build_BASE_BLOCK_ID_alter(), which can be used to target
  132. * a specific block or set of similar blocks.
  133. *
  134. * @param array &$build
  135. * A renderable array of data, only containing #cache.
  136. * @param \Drupal\Core\Block\BlockPluginInterface $block
  137. * The block plugin instance.
  138. *
  139. * @see hook_block_build_BASE_BLOCK_ID_alter()
  140. * @see entity_crud
  141. *
  142. * @ingroup block_api
  143. */
  144. function hook_block_build_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
  145. // Add the 'user' cache context to some blocks.
  146. if ($block->label() === 'some condition') {
  147. $build['#cache']['contexts'][] = 'user';
  148. }
  149. }
  150. /**
  151. * Provide a block plugin specific block_build alteration.
  152. *
  153. * In this hook name, BASE_BLOCK_ID refers to the block implementation's plugin
  154. * id, regardless of whether the plugin supports derivatives. For example, for
  155. * the \Drupal\system\Plugin\Block\SystemPoweredByBlock block, this would be
  156. * 'system_powered_by_block' as per that class's annotation. And for the
  157. * \Drupal\system\Plugin\Block\SystemMenuBlock block, it would be
  158. * 'system_menu_block' as per that class's annotation, regardless of which menu
  159. * the derived block is for.
  160. *
  161. * @param array $build
  162. * A renderable array of data, only containing #cache.
  163. * @param \Drupal\Core\Block\BlockPluginInterface $block
  164. * The block plugin instance.
  165. *
  166. * @see hook_block_build_alter()
  167. * @see entity_crud
  168. *
  169. * @ingroup block_api
  170. */
  171. function hook_block_build_BASE_BLOCK_ID_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
  172. // Explicitly enable placeholdering of the specific block.
  173. $build['#create_placeholder'] = TRUE;
  174. }
  175. /**
  176. * Control access to a block instance.
  177. *
  178. * Modules may implement this hook if they want to have a say in whether or not
  179. * a given user has access to perform a given operation on a block instance.
  180. *
  181. * @param \Drupal\block\Entity\Block $block
  182. * The block instance.
  183. * @param string $operation
  184. * The operation to be performed; for instance, 'view', 'create', 'delete', or
  185. * 'update'.
  186. * @param \Drupal\Core\Session\AccountInterface $account
  187. * The user object to perform the access check operation on.
  188. *
  189. * @return \Drupal\Core\Access\AccessResultInterface
  190. * The access result. If all implementations of this hook return
  191. * AccessResultInterface objects whose value is !isAllowed() and
  192. * !isForbidden(), then default access rules from
  193. * \Drupal\block\BlockAccessControlHandler::checkAccess() are used.
  194. *
  195. * @see \Drupal\Core\Entity\EntityAccessControlHandler::access()
  196. * @see \Drupal\block\BlockAccessControlHandler::checkAccess()
  197. * @ingroup block_api
  198. */
  199. function hook_block_access(\Drupal\block\Entity\Block $block, $operation, \Drupal\Core\Session\AccountInterface $account) {
  200. // Example code that would prevent displaying the 'Powered by Drupal' block in
  201. // a region different than the footer.
  202. if ($operation == 'view' && $block->getPluginId() == 'system_powered_by_block') {
  203. return AccessResult::forbiddenIf($block->getRegion() != 'footer')->addCacheableDependency($block);
  204. }
  205. // No opinion.
  206. return AccessResult::neutral();
  207. }
  208. /**
  209. * @} End of "addtogroup hooks".
  210. */