block.module

Controls the visual building blocks a page is constructed with.

File

drupal/core/modules/block/block.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * Controls the visual building blocks a page is constructed with.
  5. */
  6. use Drupal\Component\Plugin\Exception\PluginException;
  7. use Drupal\Component\Utility\NestedArray;
  8. /**
  9. * Denotes that a block is not enabled in any region and should not be shown.
  10. */
  11. const BLOCK_REGION_NONE = -1;
  12. /**
  13. * Users cannot control whether or not they see this block.
  14. */
  15. const BLOCK_CUSTOM_FIXED = 0;
  16. /**
  17. * Shows this block by default, but lets individual users hide it.
  18. */
  19. const BLOCK_CUSTOM_ENABLED = 1;
  20. /**
  21. * Hides this block by default but lets individual users show it.
  22. */
  23. const BLOCK_CUSTOM_DISABLED = 2;
  24. /**
  25. * Shows this block on every page except the listed pages.
  26. */
  27. const BLOCK_VISIBILITY_NOTLISTED = 0;
  28. /**
  29. * Shows this block on only the listed pages.
  30. */
  31. const BLOCK_VISIBILITY_LISTED = 1;
  32. /**
  33. * Shows this block if the associated PHP code returns TRUE.
  34. */
  35. const BLOCK_VISIBILITY_PHP = 2;
  36. /**
  37. * Indicates the block label (title) should be displayed to end users.
  38. */
  39. const BLOCK_LABEL_VISIBLE = 'visible';
  40. /**
  41. * Implements hook_help().
  42. */
  43. function block_help($path, $arg) {
  44. switch ($path) {
  45. case 'admin/help#block':
  46. $output = '';
  47. $output .= '<h3>' . t('About') . '</h3>';
  48. $output .= '<p>' . t('The Block module allows you to create boxes of content, which are rendered into an area, or region, of one or more pages of a website. The core Seven administration theme, for example, implements the regions "Content" and "Help", and a block may appear in either of these regions. The <a href="@blocks">Blocks administration page</a> provides a drag-and-drop interface for assigning a block to a region, and for controlling the order of blocks within regions. For more information, see the online handbook entry for <a href="@block">Block module</a>.', array('@block' => 'http://drupal.org/documentation/modules/block', '@blocks' => url('admin/structure/block'))) . '</p>';
  49. $output .= '<h3>' . t('Uses') . '</h3>';
  50. $output .= '<dl>';
  51. $output .= '<dt>' . t('Positioning content') . '</dt>';
  52. $output .= '<dd>' . t('When working with blocks, remember that all themes do <em>not</em> implement the same regions, or display regions in the same way. Blocks are positioned on a per-theme basis. Users with the <em>Administer blocks</em> permission can disable blocks. Disabled blocks are listed on the <a href="@blocks">Blocks administration page</a>, but are not displayed in any region.', array('@block' => 'http://drupal.org/documentation/modules/block', '@blocks' => url('admin/structure/block'))) . '</dd>';
  53. $output .= '<dt>' . t('Controlling visibility') . '</dt>';
  54. $output .= '<dd>' . t('Blocks can be configured to be visible only on certain pages, only to users of certain roles, or only on pages displaying certain <a href="@content-type">content types</a>. Some dynamic blocks, such as those generated by modules, will be displayed only on certain pages.', array('@content-type' => url('admin/structure/types'), '@user' => url('user'))) . '</dd>';
  55. if (module_exists('custom_block')) {
  56. $output .= '<dt>' . t('Creating custom blocks') . '</dt>';
  57. $output .= '<dd>' . t('Users with the <em>Administer blocks</em> permission can <a href="@block-add">add custom blocks</a>, which are then listed on the <a href="@blocks">Blocks administration page</a>. Once created, custom blocks behave just like default and module-generated blocks.', array('@blocks' => url('admin/structure/block'), '@block-add' => url('admin/structure/block/list/block_plugin_ui:' . config('system.theme')->get('default') . '/add/custom_blocks'))) . '</dd>';
  58. }
  59. $output .= '</dl>';
  60. return $output;
  61. }
  62. if ($arg[0] == 'admin' && $arg[1] == 'structure' && $arg['2'] == 'block' && (empty($arg[3]) || $arg[3] == 'list') && empty($arg[5])) {
  63. if (!empty($arg[4])) {
  64. list(, $demo_theme) = explode(':', $arg[4]);
  65. }
  66. else {
  67. $demo_theme = config('system.theme')->get('default');
  68. }
  69. $themes = list_themes();
  70. $output = '<p>' . t('This page provides a drag-and-drop interface for assigning a block to a region, and for controlling the order of blocks within regions. Since not all themes implement the same regions, or display regions in the same way, blocks are positioned on a per-theme basis. Remember that your changes will not be saved until you click the <em>Save blocks</em> button at the bottom of the page. Click the <em>configure</em> link next to each block to configure its specific title and visibility settings.') . '</p>';
  71. $output .= '<p>' . l(t('Demonstrate block regions (@theme)', array('@theme' => $themes[$demo_theme]->info['name'])), 'admin/structure/block/demo/' . $demo_theme) . '</p>';
  72. return $output;
  73. }
  74. }
  75. /**
  76. * Implements hook_theme().
  77. */
  78. function block_theme() {
  79. return array(
  80. 'block' => array(
  81. 'render element' => 'elements',
  82. 'template' => 'block',
  83. ),
  84. );
  85. }
  86. /**
  87. * Implements hook_permission().
  88. */
  89. function block_permission() {
  90. return array(
  91. 'administer blocks' => array(
  92. 'title' => t('Administer blocks'),
  93. ),
  94. );
  95. }
  96. /**
  97. * Implements hook_menu().
  98. *
  99. * @todo Clarify the documentation for the per-plugin block admin links.
  100. */
  101. function block_menu() {
  102. $default_theme = config('system.theme')->get('default');
  103. $items['admin/structure/block'] = array(
  104. 'title' => 'Blocks',
  105. 'description' => 'Configure what block content appears in your site\'s sidebars and other regions.',
  106. 'page callback' => 'block_admin_display',
  107. 'page arguments' => array($default_theme),
  108. 'access arguments' => array('administer blocks'),
  109. 'file' => 'block.admin.inc',
  110. );
  111. $items['admin/structure/block/add/%/%'] = array(
  112. 'title' => 'Configure block',
  113. 'page callback' => 'block_admin_add',
  114. 'page arguments' => array(4, 5),
  115. 'access arguments' => array('administer blocks'),
  116. 'file' => 'block.admin.inc',
  117. );
  118. $items['admin/structure/block/manage/%block'] = array(
  119. 'title' => 'Configure block',
  120. 'page callback' => 'block_admin_edit',
  121. 'page arguments' => array(4),
  122. 'access arguments' => array('administer blocks'),
  123. 'file' => 'block.admin.inc',
  124. );
  125. $items['admin/structure/block/manage/%block/configure'] = array(
  126. 'title' => 'Configure block',
  127. 'type' => MENU_DEFAULT_LOCAL_TASK,
  128. 'context' => MENU_CONTEXT_INLINE,
  129. );
  130. $items['admin/structure/block/manage/%block/delete'] = array(
  131. 'title' => 'Delete block',
  132. 'type' => MENU_LOCAL_TASK,
  133. 'context' => MENU_CONTEXT_NONE,
  134. 'route_name' => 'block_admin_block_delete',
  135. );
  136. // Block administration is tied to the theme and plugin definition so
  137. // that the plugin can appropriately attach to this URL structure.
  138. // @todo D8: Use dynamic % arguments instead of static, hard-coded theme names
  139. // and plugin IDs to decouple the routes from these dependencies and allow
  140. // hook_menu_local_tasks() to check for the untranslated tab_parent path.
  141. // @see http://drupal.org/node/1067408
  142. $themes = list_themes();
  143. foreach (drupal_container()->get('plugin.manager.system.plugin_ui')->getDefinitions() as $plugin_id => $plugin) {
  144. list($plugin_base, $key) = explode(':', $plugin_id);
  145. if ($plugin_base == 'block_plugin_ui') {
  146. $theme = $themes[$key];
  147. $items['admin/structure/block/list/' . $plugin_id] = array(
  148. 'title' => check_plain($theme->info['name']),
  149. 'page arguments' => array($key),
  150. 'type' => $key == $default_theme ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
  151. 'access callback' => '_block_themes_access',
  152. 'access arguments' => array($key),
  153. 'file' => 'block.admin.inc',
  154. );
  155. $items['admin/structure/block/demo/' . $key] = array(
  156. 'title' => check_plain($theme->info['name']),
  157. 'page callback' => 'block_admin_demo',
  158. 'page arguments' => array($key),
  159. 'type' => MENU_CALLBACK,
  160. 'access callback' => '_block_themes_access',
  161. 'access arguments' => array($key),
  162. 'theme callback' => '_block_custom_theme',
  163. 'theme arguments' => array($key),
  164. 'file' => 'block.admin.inc',
  165. );
  166. }
  167. }
  168. return $items;
  169. }
  170. /**
  171. * Access callback: Only enabled themes can be accessed.
  172. *
  173. * Path:
  174. * - admin/structure/block/list/% (for each theme)
  175. * - admin/structure/block/demo/% (for each theme)
  176. *
  177. * @param $theme
  178. * Either the name of a theme or a full theme object.
  179. *
  180. * @see block_menu()
  181. */
  182. function _block_themes_access($theme) {
  183. return user_access('administer blocks') && drupal_theme_access($theme);
  184. }
  185. /**
  186. * Theme callback: Uses the theme specified in the parameter.
  187. *
  188. * @param $theme
  189. * The theme whose blocks are being configured. If not set, the default theme
  190. * is assumed.
  191. *
  192. * @return
  193. * The theme that should be used for the block configuration page, or NULL
  194. * to indicate that the default theme should be used.
  195. *
  196. * @see block_menu()
  197. */
  198. function _block_custom_theme($theme = NULL) {
  199. // We return exactly what was passed in, to guarantee that the page will
  200. // always be displayed using the theme whose blocks are being configured.
  201. return $theme;
  202. }
  203. /**
  204. * Implements hook_page_build().
  205. *
  206. * Renders blocks into their regions.
  207. */
  208. function block_page_build(&$page) {
  209. global $theme;
  210. // The theme system might not yet be initialized. We need $theme.
  211. drupal_theme_initialize();
  212. // Fetch a list of regions for the current theme.
  213. $all_regions = system_region_list($theme);
  214. $item = menu_get_item();
  215. if ($item['path'] != 'admin/structure/block/demo/' . $theme) {
  216. // Load all region content assigned via blocks.
  217. foreach (array_keys($all_regions) as $region) {
  218. // Assign blocks to region.
  219. if ($blocks = block_get_blocks_by_region($region)) {
  220. $page[$region] = $blocks;
  221. }
  222. }
  223. // Once we've finished attaching all blocks to the page, clear the static
  224. // cache to allow modules to alter the block list differently in different
  225. // contexts. For example, any code that triggers hook_page_build() more
  226. // than once in the same page request may need to alter the block list
  227. // differently each time, so that only certain parts of the page are
  228. // actually built. We do not clear the cache any earlier than this, though,
  229. // because it is used each time block_get_blocks_by_region() gets called
  230. // above.
  231. drupal_static_reset('block_list');
  232. }
  233. else {
  234. // Append region description if we are rendering the regions demo page.
  235. $item = menu_get_item();
  236. if ($item['path'] == 'admin/structure/block/demo/' . $theme) {
  237. $visible_regions = array_keys(system_region_list($theme, REGIONS_VISIBLE));
  238. foreach ($visible_regions as $region) {
  239. $description = '<div class="block-region">' . $all_regions[$region] . '</div>';
  240. $page[$region]['block_description'] = array(
  241. '#markup' => $description,
  242. '#weight' => 15,
  243. );
  244. }
  245. $page['page_top']['backlink'] = array(
  246. '#type' => 'link',
  247. '#title' => t('Exit block region demonstration'),
  248. '#href' => 'admin/structure/block' . (config('system.theme')->get('default') == $theme ? '' : '/list/' . $theme),
  249. // Add the "overlay-restore" class to indicate this link should restore
  250. // the context in which the region demonstration page was opened.
  251. '#options' => array('attributes' => array('class' => array('block-demo-backlink', 'overlay-restore'))),
  252. '#weight' => -10,
  253. );
  254. }
  255. }
  256. }
  257. /**
  258. * Gets a renderable array of a region containing all enabled blocks.
  259. *
  260. * @param $region
  261. * The requested region.
  262. *
  263. * @return
  264. * A renderable array of a region containing all enabled blocks.
  265. */
  266. function block_get_blocks_by_region($region) {
  267. $build = array();
  268. if ($list = block_list($region)) {
  269. $build = _block_get_renderable_region($list);
  270. }
  271. return $build;
  272. }
  273. /**
  274. * Gets an array of blocks suitable for drupal_render().
  275. *
  276. * @param $list
  277. * A list of blocks such as that returned by block_list().
  278. *
  279. * @return
  280. * A renderable array.
  281. */
  282. function _block_get_renderable_region($list = array()) {
  283. $build = array();
  284. // Block caching is not compatible with node_access modules. We also
  285. // preserve the submission of forms in blocks, by fetching from cache
  286. // only if the request method is 'GET' (or 'HEAD'). User 1 being out of
  287. // the regular 'roles define permissions' schema, it brings too many
  288. // chances of having unwanted output get in the cache and later be served
  289. // to other users. We therefore exclude user 1 from block caching.
  290. $not_cacheable = $GLOBALS['user']->uid == 1 ||
  291. count(module_implements('node_grants')) ||
  292. !\Drupal::request()->isMethodSafe();
  293. foreach ($list as $key => $block) {
  294. $settings = $block->get('settings');
  295. if ($not_cacheable || in_array($settings['cache'], array(DRUPAL_NO_CACHE, DRUPAL_CACHE_CUSTOM))) {
  296. // Non-cached blocks get built immediately.
  297. if ($block->access()) {
  298. $build[$key] = entity_view($block, 'block');
  299. }
  300. }
  301. else {
  302. $key_components = explode('.', $key);
  303. $id = array_pop($key_components);
  304. $build[$key] = array(
  305. '#block' => $block,
  306. '#weight' => $block->get('weight'),
  307. '#pre_render' => array('_block_get_renderable_block'),
  308. '#cache' => array(
  309. 'keys' => array($id, $settings['module']),
  310. 'granularity' => $settings['cache'],
  311. 'bin' => 'block',
  312. 'tags' => array('content' => TRUE),
  313. ),
  314. );
  315. }
  316. // Add contextual links for this block; skip the main content block, since
  317. // contextual links are basically output as tabs/local tasks already. Also
  318. // skip the help block, since we assume that most users do not need or want
  319. // to perform contextual actions on the help block, and the links needlessly
  320. // draw attention on it.
  321. if (isset($build[$key]) && !in_array($block->get('plugin'), array('system_help_block', 'system_main_block'))) {
  322. $build[$key]['#contextual_links']['block'] = array('admin/structure/block/manage', array($key));
  323. // If there are any nested contextual links, move them to the top level.
  324. if (isset($build[$key]['content']['#contextual_links'])) {
  325. $build[$key]['#contextual_links'] += $build[$key]['content']['#contextual_links'];
  326. unset($build[$key]['content']['#contextual_links']);
  327. }
  328. }
  329. }
  330. return $build;
  331. }
  332. /**
  333. * Returns an array of block class instances by theme.
  334. *
  335. * @param $theme
  336. * The theme to rehash blocks for. If not provided, defaults to the currently
  337. * used theme.
  338. *
  339. * @return
  340. * Blocks currently exported by modules.
  341. */
  342. function _block_rehash($theme = NULL) {
  343. $theme = $theme ? $theme : config('system.theme')->get('default');
  344. $regions = system_region_list($theme);
  345. $blocks = entity_load_multiple_by_properties('block', array('theme' => $theme));
  346. foreach ($blocks as $block_id => $block) {
  347. $region = $block->get('region');
  348. $status = $block->status();
  349. // Disable blocks in invalid regions.
  350. if (!empty($region) && $region != BLOCK_REGION_NONE && !isset($regions[$region]) && $status) {
  351. drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $block_id, '%region' => $region)), 'warning');
  352. // Disabled modules are moved into the BLOCK_REGION_NONE later so no
  353. // need to move the block to another region.
  354. $block->disable()->save();
  355. }
  356. // Set region to none if not enabled.
  357. if (!$status) {
  358. $block->set('region', BLOCK_REGION_NONE);
  359. $block->save();
  360. }
  361. }
  362. return $blocks;
  363. }
  364. /**
  365. * Initializes blocks for enabled themes.
  366. *
  367. * @param $theme_list
  368. * An array of theme names.
  369. */
  370. function block_themes_enabled($theme_list) {
  371. foreach ($theme_list as $theme) {
  372. block_theme_initialize($theme);
  373. }
  374. }
  375. /**
  376. * Assigns an initial, default set of blocks for a theme.
  377. *
  378. * This function is called the first time a new theme is enabled. The new theme
  379. * gets a copy of the default theme's blocks, with the difference that if a
  380. * particular region isn't available in the new theme, the block is assigned
  381. * to the new theme's default region.
  382. *
  383. * @param $theme
  384. * The name of a theme.
  385. */
  386. function block_theme_initialize($theme) {
  387. // Initialize theme's blocks if none already registered.
  388. $has_blocks = entity_load_multiple_by_properties('block', array('theme' => $theme));
  389. if (!$has_blocks) {
  390. $default_theme = config('system.theme')->get('default');
  391. // Apply only to new theme's visible regions.
  392. $regions = system_region_list($theme, REGIONS_VISIBLE);
  393. $default_theme_blocks = entity_load_multiple_by_properties('block', array('theme' => $default_theme));
  394. foreach ($default_theme_blocks as $default_theme_block_id => $default_theme_block) {
  395. list(, $machine_name) = explode('.', $default_theme_block_id);
  396. $block = $default_theme_block->createDuplicate();
  397. $block->set('id', $theme . '.' . $machine_name);
  398. // If the region isn't supported by the theme, assign the block to the
  399. // theme's default region.
  400. if (!isset($regions[$block->get('region')])) {
  401. $block->set('region', system_default_region($theme));
  402. }
  403. $block->save();
  404. }
  405. }
  406. }
  407. /**
  408. * Returns all blocks in the specified region for the current user.
  409. *
  410. * @param $region
  411. * The name of a region.
  412. *
  413. * @return
  414. * An array of block objects, indexed with the configuration object name
  415. * that represents the configuration. If you are displaying your blocks in
  416. * one or two sidebars, you may check whether this array is empty to see
  417. * how many columns are going to be displayed.
  418. */
  419. function block_list($region) {
  420. $blocks = &drupal_static(__FUNCTION__);
  421. if (!isset($blocks)) {
  422. global $theme;
  423. $blocks = array();
  424. foreach (entity_load_multiple_by_properties('block', array('theme' => $theme)) as $block_id => $block) {
  425. $blocks[$block->get('region')][$block_id] = $block;
  426. }
  427. }
  428. // Create an empty array if there are no entries.
  429. if (!isset($blocks[$region])) {
  430. $blocks[$region] = array();
  431. }
  432. return $blocks[$region];
  433. }
  434. /**
  435. * Loads a block instance.
  436. *
  437. * This should only be used when entity_load() cannot be used directly.
  438. *
  439. * @param string $entity_id
  440. * The block ID.
  441. *
  442. * @return \Drupal\block\Plugin\Core\Entity\Block
  443. * The loaded block object.
  444. */
  445. function block_load($entity_id) {
  446. return entity_load('block', $entity_id);
  447. }
  448. /**
  449. * Builds the content and label for a block.
  450. *
  451. * For cacheable blocks, this is called during #pre_render.
  452. *
  453. * @param $element
  454. * A renderable array.
  455. *
  456. * @return
  457. * A renderable array.
  458. */
  459. function _block_get_renderable_block($element) {
  460. $block = $element['#block'];
  461. // Don't bother to build blocks that aren't accessible.
  462. if ($element['#access'] = $block->access()) {
  463. $element += entity_view($block, 'block');
  464. }
  465. return $element;
  466. }
  467. /**
  468. * Implements hook_rebuild().
  469. */
  470. function block_rebuild() {
  471. foreach (list_themes() as $name => $data) {
  472. if ($data->status) {
  473. _block_rehash($name);
  474. }
  475. }
  476. }
  477. /**
  478. * Prepares variables for block templates.
  479. *
  480. * Default template: block.html.twig.
  481. *
  482. * Prepares the values passed to the theme_block function to be passed
  483. * into a pluggable template engine. Uses block properties to generate a
  484. * series of template file suggestions. If none are found, the default
  485. * block.html.twig is used.
  486. *
  487. * Most themes use their own copy of block.html.twig. The default is located
  488. * inside "core/modules/block/templates/block.html.twig". Look in there for the
  489. * full list of available variables.
  490. *
  491. * @param array $variables
  492. * An associative array containing:
  493. * - elements: An associative array containing the properties of the element.
  494. * Properties used: #block, #configuration, #children, #plugin_id.
  495. */
  496. function template_preprocess_block(&$variables) {
  497. $block_counter = &drupal_static(__FUNCTION__, array());
  498. $variables['configuration'] = $variables['elements']['#configuration'];
  499. $variables['plugin_id'] = $variables['elements']['#plugin_id'];
  500. $variables['label'] = !empty($variables['configuration']['label_display']) ? $variables['configuration']['label'] : '';
  501. $variables['content'] = $variables['elements']['content'];
  502. $variables['attributes']['class'][] = 'block';
  503. $variables['attributes']['class'][] = drupal_html_class('block-' . $variables['configuration']['module']);
  504. // The block template provides a wrapping element for the content. Render the
  505. // #attributes of the content on this wrapping element rather than passing
  506. // them through to the content's #theme function/template. This allows the
  507. // content to not require a function/template at all, or if it does use one,
  508. // to not require it to output an extra wrapping element.
  509. if (isset($variables['content']['#attributes'])) {
  510. $variables['content_attributes'] = NestedArray::mergeDeep($variables['content_attributes'], $variables['content']['#attributes']);
  511. unset($variables['content']['#attributes']);
  512. }
  513. // Add default class for block content.
  514. $variables['content_attributes']['class'][] = 'content';
  515. $variables['theme_hook_suggestions'][] = 'block__' . $variables['configuration']['module'];
  516. // Hyphens (-) and underscores (_) play a special role in theme suggestions.
  517. // Theme suggestions should only contain underscores, because within
  518. // drupal_find_theme_templates(), underscores are converted to hyphens to
  519. // match template file names, and then converted back to underscores to match
  520. // pre-processing and other function names. So if your theme suggestion
  521. // contains a hyphen, it will end up as an underscore after this conversion,
  522. // and your function names won't be recognized. So, we need to convert
  523. // hyphens to underscores in block deltas for the theme suggestions.
  524. // We can safely explode on : because we know the Block plugin type manager
  525. // enforces that delimiter for all derivatives.
  526. $parts = explode(':', $variables['plugin_id']);
  527. $suggestion = 'block';
  528. while ($part = array_shift($parts)) {
  529. $variables['theme_hook_suggestions'][] = $suggestion .= '__' . strtr($part, '-', '_');
  530. }
  531. // Create a valid HTML ID and make sure it is unique.
  532. if ($id = $variables['elements']['#block']->id()) {
  533. $config_id = explode('.', $id);
  534. $machine_name = array_pop($config_id);
  535. $variables['attributes']['id'] = drupal_html_id('block-' . $machine_name);
  536. $variables['theme_hook_suggestions'][] = 'block__' . $machine_name;
  537. }
  538. }
  539. /**
  540. * Implements hook_user_role_delete().
  541. *
  542. * Removes deleted role from blocks that use it.
  543. */
  544. function block_user_role_delete($role) {
  545. foreach (entity_load_multiple('block') as $block_id => $block) {
  546. $visibility = $block->get('visibility');
  547. if (isset($visibility['roles']['roles'][$role->id()])) {
  548. unset($visibility['roles']['roles'][$role->id()]);
  549. $block->set('visibility', $visibility);
  550. $block->save();
  551. }
  552. }
  553. }
  554. /**
  555. * Implements hook_menu_delete().
  556. */
  557. function block_menu_delete($menu) {
  558. foreach (entity_load_multiple('block') as $block_id => $block) {
  559. if ($block->get('plugin') == 'menu_menu_block:' . $menu->id()) {
  560. $block->delete();
  561. }
  562. }
  563. }
  564. /**
  565. * Implements hook_admin_paths().
  566. */
  567. function block_admin_paths() {
  568. $paths = array(
  569. // Exclude the block demonstration page from admin (overlay) treatment.
  570. // This allows us to present this page in its true form, full page.
  571. 'admin/structure/block/demo/*' => FALSE,
  572. );
  573. return $paths;
  574. }
  575. /**
  576. * Implements hook_language_delete().
  577. *
  578. * Delete the potential block visibility settings of the deleted language.
  579. */
  580. function block_language_delete($language) {
  581. // Remove the block visibility settings for the deleted language.
  582. foreach (entity_load_multiple('block') as $block_id => $block) {
  583. $visibility = $block->get('visibility');
  584. if (isset($visibility['language']['langcodes'][$language->langcode])) {
  585. unset($visibility['language']['langcodes'][$language->langcode]);
  586. $block->set('visibility', $visibility);
  587. $block->save();
  588. }
  589. }
  590. }
  591. /**
  592. * Implements hook_library_info().
  593. */
  594. function block_library_info() {
  595. $libraries['drupal.block'] = array(
  596. 'title' => 'Block',
  597. 'version' => VERSION,
  598. 'js' => array(
  599. drupal_get_path('module', 'block') . '/block.js' => array(),
  600. ),
  601. 'dependencies' => array(
  602. array('system', 'jquery'),
  603. array('system', 'drupal'),
  604. ),
  605. );
  606. return $libraries;
  607. }

Functions

Namesort descending Description
block_admin_paths Implements hook_admin_paths().
block_get_blocks_by_region Gets a renderable array of a region containing all enabled blocks.
block_help Implements hook_help().
block_language_delete Implements hook_language_delete().
block_library_info Implements hook_library_info().
block_list Returns all blocks in the specified region for the current user.
block_load Loads a block instance.
block_menu Implements hook_menu().
block_menu_delete Implements hook_menu_delete().
block_page_build Implements hook_page_build().
block_permission Implements hook_permission().
block_rebuild Implements hook_rebuild().
block_theme Implements hook_theme().
block_themes_enabled Initializes blocks for enabled themes.
block_theme_initialize Assigns an initial, default set of blocks for a theme.
block_user_role_delete Implements hook_user_role_delete().
template_preprocess_block Prepares variables for block templates.
_block_custom_theme Theme callback: Uses the theme specified in the parameter.
_block_get_renderable_block Builds the content and label for a block.
_block_get_renderable_region Gets an array of blocks suitable for drupal_render().
_block_rehash Returns an array of block class instances by theme.
_block_themes_access Access callback: Only enabled themes can be accessed.

Constants

Namesort descending Description
BLOCK_CUSTOM_DISABLED Hides this block by default but lets individual users show it.
BLOCK_CUSTOM_ENABLED Shows this block by default, but lets individual users hide it.
BLOCK_CUSTOM_FIXED Users cannot control whether or not they see this block.
BLOCK_LABEL_VISIBLE Indicates the block label (title) should be displayed to end users.
BLOCK_REGION_NONE Denotes that a block is not enabled in any region and should not be shown.
BLOCK_VISIBILITY_LISTED Shows this block on only the listed pages.
BLOCK_VISIBILITY_NOTLISTED Shows this block on every page except the listed pages.
BLOCK_VISIBILITY_PHP Shows this block if the associated PHP code returns TRUE.