annotate core/modules/block/block.api.php @ 19:fa3358dc1485 tip

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