Blocks trong Drupal 7 bây giờ là plugins trong Drupal 8

Blocks trong Drupal 7 bây giờ là plugins trong Drupal 8

Summary

In Drupal 7, definition and altering of blocks are done through block specific mechanisms. A block was defined by implementing hook_block_info()providing the available deltas and the corresponding administrative labels. hook_block_view()was implemented to return the relevant render array. The block then could be configured in the UI to appear once per theme in a specific region -- the disabled blocks are visible in the UI in the "disabled" region.

In Drupal 8, the logic for blocks is provided by so called plugins (annotated classes in a specific namespace), the annotation providing the administrative label. The concept of delta is gone, the plugin is identified by its plugin id. The defining module does not matter, the plugin id must be unique across all modules. The buildmethod of the plugin class provides the relevant render array. The block does not appear at all until it is placed; however it can be placed any number of times, it can appear in a theme any number of times. The placement information (theme, region, weight) and any block specific configuration information is saved in a configuration entity. This is the same plugin/configuration entity dual mechanism that is used for actions, editors, migrations, views etc.

API changes

  • hook_block_info()has been removed. Block types are now defined by adding a block plugin.
  • hook_block_configure(), hook_block_save(), and hook_block_view()have been replaced with block plugin methods.
  • hook_block_info_alter()has been removed. The administrative label can be changed with the new hook_block_alter(). Most other properties (cache, visibility etc) can be changed on the configuration entity save or load: hook_block_presave, hook_block_insert, hook_block_update(or even hook_block_loadfor very dynamic cases).
  • hook_block_list_alter()has been removed. First, as with every entity, there is the entity access layer: hook_entity_accessor hook_block_access(). This is the recommended way for most cases. Also, if the core provided access logic (roles, paths, language) is adequate then see above about changing the visibilityproperty in the configuration enttity.
  • hook_block_MODULE_DELTA_alter()has been replaced with hook_block_ID_alter()and hook_block_NAME_alter()

The above are the hooks normal modules should implement. However, in some cases overriding the default behaviors might be necessary and with Drupal 8 this is possible. At the end of this change notice we will list these.

Examples

Defining a block type

To define a block type, place a MyBlock.phpplugin class file in the following directory structure:
my_module/src/Plugin/Block
(See the explanation of the PSR-4 standard for more information.) This plugin class will be automatically discovered and loaded when my_module is enabled.

Drupal 7

In book.module:

<?php
function book_block_info() {
 
$block = array();
 
$block[#DD0000">'navigation'][#DD0000">'info'] = t(#DD0000">'Book navigation');
 
$block[#DD0000">'navigation'][#DD0000">'cache'] = DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE;

  return
$block;
}
?>

Drupal 8

The relevant parts of core/modules/search/src/Plugin/Block/SearchBlock.php:

<?php
#FF8000">/**
 * @file
 * Contains \Drupal\search\Plugin\Block\SearchBlock.
 */

namespace Drupal\search\Plugin\Block;

use
Drupal\Core\Session\AccountInterface;
use
Drupal\block\BlockBase;

#FF8000">/**
 * Provides a 'Search form' block.
 *
 * @Block(
 *   id = "search_form_block",
 *   admin_label = @Translation("Search form"),
 *   category = @Translation("Forms")
 * )
 */
class SearchBlock extends BlockBase {

 
#FF8000">/**
   * {@inheritdoc}
   */
 
protected function blockAccess(AccountInterface $account) {
    return
$account->hasPermission(#DD0000">'search content');
  }

 
#FF8000">/**
   * {@inheritdoc}
   */
 
public function build() {
    return \
Drupal::formBuilder()->getForm(#DD0000">'Drupal\search\Form\SearchBlockForm');
  }
}
?>

The administration label hook_block_info()is now added to the block plugin's annotation (a special section at the end of the documentation block wrapped in @Block()). (More about annotations and plugin discovery). The information in the annotation (for example, category) is not editable in the UI and is the same for every placement. If some data, like the book block mode can change between placements then it needs to go in the defaultConfiguration()method.

Configuration settings are declared in a defaultSettings()method; instance settings are declared in a defaultInstanceSettings()method in the configuration entity. @see #2136197: Move field/instance/widget/formatter settings out of annotation / plugin definition. No longer applicable: This method was called "settings" and was changed in #2062573: Add method defaultConfiguration() in ConfigurablePluginInterface, see also this change notice [#2088589].

The "admin_label" key was originally called "subject", it was changed in #1591806: Change block "subject" so that it's called a (admin_)label like everything else on the theme layer, and block plugins were given their own separate annotation in #2065721: Add a dedicated @Block plugin annotation.

Adding configuration options to a block type's form

Drupal 7

In book.module:

<?php
function book_block_configure($delta = #DD0000">'') {
 
$form[#DD0000">'book_block_mode'] = array(
#FF8000">// form definition omitted for brevity.
 
);
  return
$form;
}
function
book_block_save($delta = #DD0000">'', $edit = array()) {
 
$block = array();
 
variable_set(#DD0000">'book_block_mode', $edit[#DD0000">'book_block_mode']);
}
?>

Drupal 8

In core/modules/book/src/Plugin/Block/BookNavigationBlock.php:

<?php
 
function blockForm($form, &$form_state) {
   
$form[#DD0000">'book_block_mode'] = array(
     
#DD0000">'#default_value' => $this->configuration[#DD0000">'block_mode'],
#FF8000">// rest of the form omitted for brevity.
   
);
    return
$form;
  }
  public function
blockSubmit($form, &$form_state) {
   
$this->configuration[#DD0000">'block_mode'] = $form_state[#DD0000">'values'][#DD0000">'book_block_mode'];
  }
?>

Note that these added form elements allow the user to configure the settings added in defaultConfiguration(). Also note blockSubmitmerely sets the configuration; the actual persisting of the configuration is done automatically.

Defining a block type's output

 

Drupal 7

The user login block is a much better example for this one. In user.module:

<?php
function user_block_view($delta = #DD0000">'') {
 
$block = array();
  switch (
$delta) {
    case
#DD0000">'login':
      if (!
$user->uid && !(arg(0) == #DD0000">'user' && !is_numeric(arg(1)))) {
       
$block[#DD0000">'subject'] = t(#DD0000">'User login');
       
$block[#DD0000">'content'] = drupal_get_form(#DD0000">'user_login_block');
      }
  }
  return
$block;
?>

Drupal 8

In core/modules/user/src/Plugin/Block/UserLoginBlock.php:

<?php
class UserLoginBlock extends BlockBase {

 
#FF8000">/**
   * {@inheritdoc}
   */
 
protected function blockAccess(AccountInterface $account) {
    return (!
$account->id() && !(arg(0) == #DD0000">'user' && !is_numeric(arg(1))));
  }

 
#FF8000">/**
   * {@inheritdoc}
   */
 
public function build() {
   
#FF8000">// Building of the form is omitted.
   
return array(
     
#DD0000">'user_login_form' => $form,
     
#DD0000">'user_links' => array(
       
#DD0000">'#theme' => #DD0000">'item_list',
       
#DD0000">'#items' => $items,
      ),
    );
?>

Note how accessreplaced the if– instead of returning an empty array, the build function is simply not called. This results in much cleaner code. (However, the buildfunction can still return an empty array if it wants the block skipped.)

Altering the visibility of other modules' blocks

Drupal 7

In node.module:

<?php
#FF8000">/**                                                                             
 * Implements hook_block_list_alter().                                              
 */
function node_block_list_alter(&$blocks) {
  foreach (
$blocks as $key => $block) {
#FF8000">// ...
     
else {
       
#FF8000">// This is not a node page, remove the block.
       
unset($blocks[$key]);
        continue;
      }
  }
}
?>

Drupal 8

In node.module:

<?php
#FF8000">/**                                                                             
 * Implements hook_block_access().                                              
 */
function node_block_access($block) {        
#FF8000">// …
   
if (empty($allowed_types)) {
     
#FF8000">// There are no node types selected in visibility settings so there is
      // nothing to do.
     
return;
    }
#FF8000">// …
   
return FALSE;
}
?>

Note how the new hook only gets one block and it can return FALSE to deny access or NULL if it doesn't want to make a decision on access.

The meta hooks / mechanisms

As mentioned above, the default behaviors are modifiable via various mechanisms, mostly hooks. The need to use these mechanisms should arise very rarely and even then extreme caution is advised. If two modules try to replace the same functionality, conflicts might arise. Most modules (and developers) will expect the default mechanisms to work. Don't forget: with great power comes great responsibility.

  • By using hook_block_alterit is possible to change the class belonging to a given plugin id.
  • hook_block_alteritself is fired by the block plugin manager which can be replaced: it is a service and services can be altered by a ModulenameServiceProviderclass implementing the ServiceModifierInterface.
  • By using hook_entity_info_alterit is possible to change the access, the storage and the view controller of the Blockentity type.
Bạn thấy bài viết này như thế nào?: 
No votes yet
Ảnh của Tommy Tran

Tommy owner Express Magazine

Drupal Developer having 9+ year experience, implementation and having strong knowledge of technical specifications, workflow development. Ability to perform effectively and efficiently in team and individually. Always enthusiastic and interseted to study new technologies

  • Skype ID: tthanhthuy

Tìm kiếm bất động sản

 

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
Bí quyết 1 - Multilingual Site trong Drupal 7

Bí quyết 1 - Multilingual Site trong Drupal 7

As we discussed in our first introductory blog post, Recipes for Building a Multilingual Site, not all Drupal installations are the same and nearly every site built with Drupal is different in one way or another

Apple "sửa" lỗ hổng bảo mật trong iOS 5

Apple sửa lỗ hổng bảo mật trong iOS 5

Apple đã phát hành bản cập nhật cho iOS 5 giành cho iPhone, iPod cảm ứng và iPad, bản này sửa lỗi hao pin và hàng tá lỗ hổng bảo mật như đã đưa tin.

Osama bin Laden bị phát hiện khi đang ẩn náu ở Pakistan

Khủng bố Osama bin Laden bị phát hiện do dây phơi quần áo

Khi thu thập manh mối về nơi ẩn náu của Osama bin Laden, CIA phát hiện khu nhà có dây phơi chăng đầy quần áo dường như là của gia đình trùm khủng bố

Công ty diệt chuột T&C

 

Diet con trung